diff --git a/go.mod b/go.mod index 48af58b8b3d..8dc23b6fdc0 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,9 @@ require ( github.com/VictoriaMetrics/fastcache v1.13.3 github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b github.com/alicebob/miniredis/v2 v2.38.0 - github.com/aws/aws-sdk-go-v2 v1.42.0 - github.com/aws/aws-sdk-go-v2/config v1.32.26 - github.com/aws/aws-sdk-go-v2/service/dynamodb v1.59.1 + github.com/aws/aws-sdk-go-v2 v1.45.1 + github.com/aws/aws-sdk-go-v2/config v1.33.1 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.65.1 github.com/axiomhq/hyperloglog v0.2.6 github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf @@ -21,8 +21,8 @@ require ( github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb github.com/felixge/fgprof v0.9.5 github.com/go-kit/log v0.2.1 - github.com/go-openapi/strfmt v0.26.4 - github.com/go-openapi/swag/jsonutils v0.27.0 + github.com/go-openapi/strfmt v0.27.0 + github.com/go-openapi/swag/jsonutils v0.29.1 github.com/go-redis/redis/v8 v8.11.5 github.com/gogo/protobuf v1.3.2 github.com/gogo/status v1.1.1 @@ -33,62 +33,62 @@ require ( github.com/gorilla/mux v1.8.1 github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 - github.com/hashicorp/consul/api v1.34.3 + github.com/hashicorp/consul/api v1.34.4 github.com/hashicorp/go-cleanhttp v0.5.2 - github.com/hashicorp/go-metrics v0.6.0 + github.com/hashicorp/go-metrics v0.6.1 github.com/hashicorp/go-sockaddr v1.0.7 github.com/hashicorp/golang-lru/v2 v2.0.7 - github.com/hashicorp/memberlist v0.5.4 + github.com/hashicorp/memberlist v0.6.0 github.com/json-iterator/go v1.1.12 - github.com/klauspost/compress v1.18.7 - github.com/minio/minio-go/v7 v7.2.1 + github.com/klauspost/compress v1.19.2 + github.com/minio/minio-go/v7 v7.3.0 github.com/mitchellh/go-wordwrap v1.0.1 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/oklog/ulid v1.3.1 - github.com/oklog/ulid/v2 v2.1.1 + github.com/oklog/ulid/v2 v2.1.2 github.com/opentracing-contrib/go-grpc v0.1.4 github.com/opentracing-contrib/go-stdlib v1.1.1 github.com/opentracing/opentracing-go v1.2.0 - github.com/parquet-go/parquet-go v0.30.1 + github.com/parquet-go/parquet-go v0.32.0 github.com/pkg/errors v0.9.1 github.com/prometheus-community/parquet-common v0.0.0-20260614025832-5f32460b5373 github.com/prometheus/alertmanager v0.33.0 - github.com/prometheus/client_golang v1.23.2 + github.com/prometheus/client_golang v1.24.1 github.com/prometheus/client_golang/exp v0.0.0-20251212205219-7ba246a648ca github.com/prometheus/client_model v0.6.2 - github.com/prometheus/common v0.69.0 - github.com/prometheus/procfs v0.21.0 + github.com/prometheus/common v0.70.1 + github.com/prometheus/procfs v0.21.1 // Prometheus maps version 3.x.y to tags v0.30x.y. github.com/prometheus/prometheus v0.309.1 github.com/segmentio/fasthash v1.0.3 github.com/sercand/kuberesolver/v5 v5.1.1 github.com/sony/gobreaker v1.0.0 github.com/spf13/afero v1.15.0 - github.com/stretchr/testify v1.11.1 + github.com/stretchr/testify v1.12.1 github.com/thanos-io/objstore v0.0.0-20250804093838-71d60dfee488 github.com/thanos-io/promql-engine v0.0.0-20260729073658-f8bd3f940687 github.com/thanos-io/thanos v0.42.1-0.20260727122508-92397939e4cc - github.com/tjhop/slog-gokit v0.2.0 + github.com/tjhop/slog-gokit v0.2.2 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/weaveworks/common v0.0.0-20230728070032-dd9e68f319d5 go.etcd.io/etcd/api/v3 v3.5.17 go.etcd.io/etcd/client/pkg/v3 v3.5.17 go.etcd.io/etcd/client/v3 v3.5.17 - go.opentelemetry.io/collector/pdata v1.61.0 - go.opentelemetry.io/contrib/propagators/aws v1.44.0 - go.opentelemetry.io/otel v1.45.0 - go.opentelemetry.io/otel/bridge/opentracing v1.45.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 - go.opentelemetry.io/otel/sdk v1.44.0 - go.opentelemetry.io/otel/trace v1.45.0 + go.opentelemetry.io/collector/pdata v1.65.0 + go.opentelemetry.io/contrib/propagators/aws v1.46.0 + go.opentelemetry.io/otel v1.46.0 + go.opentelemetry.io/otel/bridge/opentracing v1.46.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 + go.opentelemetry.io/otel/sdk v1.46.0 + go.opentelemetry.io/otel/trace v1.46.0 go.uber.org/atomic v1.11.0 go.uber.org/automaxprocs v1.6.0 - golang.org/x/net v0.57.0 + golang.org/x/net v0.58.0 golang.org/x/sync v0.22.0 golang.org/x/time v0.15.0 - google.golang.org/grpc v1.83.0 - google.golang.org/protobuf v1.36.11 + google.golang.org/grpc v1.83.1 + google.golang.org/protobuf v1.36.12 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -116,20 +116,20 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible // indirect github.com/andybalholm/brotli v1.1.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.19.25 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.12.6 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 // indirect - github.com/aws/aws-sdk-go-v2/service/signin v1.2.1 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.20.1 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.13.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.1 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.7.1 // indirect github.com/aws/aws-sdk-go-v2/service/sns v1.39.17 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.31.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.43.4 // indirect - github.com/aws/smithy-go v1.27.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.35.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.40.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.47.1 // indirect + github.com/aws/smithy-go v1.28.1 // indirect github.com/baidubce/bce-sdk-go v0.9.230 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -152,32 +152,33 @@ require ( github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect github.com/fatih/color v1.19.0 // indirect github.com/fatih/faillint v1.15.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect github.com/fsnotify/fsnotify v1.10.0 // indirect github.com/go-chi/chi/v5 v5.2.4 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logfmt/logfmt v0.6.1 // indirect github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.25.0 // indirect + github.com/go-openapi/analysis v0.25.5 // indirect github.com/go-openapi/errors v0.22.8 // indirect - github.com/go-openapi/jsonpointer v0.22.5 // indirect - github.com/go-openapi/jsonreference v0.21.5 // indirect - github.com/go-openapi/loads v0.23.3 // indirect - github.com/go-openapi/runtime v0.29.4 // indirect - github.com/go-openapi/spec v0.22.4 // indirect - github.com/go-openapi/swag v0.26.0 // indirect - github.com/go-openapi/swag/cmdutils v0.26.0 // indirect - github.com/go-openapi/swag/conv v0.27.0 // indirect - github.com/go-openapi/swag/fileutils v0.26.0 // indirect - github.com/go-openapi/swag/jsonname v0.26.0 // indirect - github.com/go-openapi/swag/loading v0.26.0 // indirect - github.com/go-openapi/swag/mangling v0.26.0 // indirect - github.com/go-openapi/swag/netutils v0.26.0 // indirect - github.com/go-openapi/swag/stringutils v0.26.0 // indirect - github.com/go-openapi/swag/typeutils v0.27.0 // indirect - github.com/go-openapi/swag/yamlutils v0.26.0 // indirect - github.com/go-openapi/validate v0.25.2 // indirect + github.com/go-openapi/jsonpointer v1.0.0 // indirect + github.com/go-openapi/jsonreference v1.0.0 // indirect + github.com/go-openapi/loads v0.25.0 // indirect + github.com/go-openapi/runtime v0.33.0 // indirect + github.com/go-openapi/runtime/server-middleware v0.30.0 // indirect + github.com/go-openapi/spec v0.22.9 // indirect + github.com/go-openapi/swag v0.28.0 // indirect + github.com/go-openapi/swag/cmdutils v0.28.0 // indirect + github.com/go-openapi/swag/conv v0.29.1 // indirect + github.com/go-openapi/swag/fileutils v0.28.0 // indirect + github.com/go-openapi/swag/loading v0.28.0 // indirect + github.com/go-openapi/swag/mangling v0.28.0 // indirect + github.com/go-openapi/swag/netutils v0.28.0 // indirect + github.com/go-openapi/swag/pools v0.29.1 // indirect + github.com/go-openapi/swag/stringutils v0.28.0 // indirect + github.com/go-openapi/swag/typeutils v0.29.1 // indirect + github.com/go-openapi/swag/yamlutils v0.28.0 // indirect + github.com/go-openapi/validate v0.26.1 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.13.0 // indirect @@ -192,7 +193,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect github.com/googleapis/gax-go/v2 v2.17.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -200,14 +201,14 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-version v1.9.0 // indirect - github.com/hashicorp/golang-lru v0.6.0 // indirect - github.com/hashicorp/serf v0.10.1 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/hashicorp/serf v0.10.4 // indirect github.com/huaweicloud/huaweicloud-sdk-go-obs v3.25.4+incompatible // indirect github.com/jessevdk/go-flags v1.6.1 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kamstrup/intmap v0.5.2 // indirect - github.com/klauspost/cpuid/v2 v2.2.11 // indirect + github.com/klauspost/cpuid/v2 v2.4.0 // indirect github.com/klauspost/crc32 v1.3.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect @@ -216,12 +217,12 @@ require ( github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lib/pq v1.11.2 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-colorable v0.1.15 // indirect + github.com/mattn/go-isatty v0.0.22 // indirect github.com/mdlayher/socket v0.5.1 // indirect github.com/mdlayher/vsock v1.2.1 // indirect github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a // indirect - github.com/miekg/dns v1.1.69 // indirect + github.com/miekg/dns v1.1.72 // indirect github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -245,7 +246,6 @@ require ( github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus-community/prom-label-proxy v0.11.1 // indirect github.com/prometheus/exporter-toolkit v0.16.0 // indirect github.com/prometheus/otlptranslator v1.0.0 // indirect @@ -260,9 +260,9 @@ require ( github.com/sirupsen/logrus v1.9.4 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/spiffe/go-spiffe/v2 v2.7.0 // indirect - github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/objx v0.5.3 // indirect github.com/tencentyun/cos-go-sdk-v5 v0.7.66 // indirect - github.com/tinylib/msgp v1.6.1 // indirect + github.com/tinylib/msgp v1.6.4 // indirect github.com/twmb/franz-go v1.21.2 // indirect github.com/twmb/franz-go/pkg/kmsg v1.13.1 // indirect github.com/twmb/franz-go/plugin/kslog v1.0.0 // indirect @@ -280,40 +280,40 @@ require ( go.opentelemetry.io/collector/confmap v1.48.0 // indirect go.opentelemetry.io/collector/confmap/xconfmap v0.142.0 // indirect go.opentelemetry.io/collector/consumer v1.48.0 // indirect - go.opentelemetry.io/collector/featuregate v1.61.0 // indirect + go.opentelemetry.io/collector/featuregate v1.65.0 // indirect go.opentelemetry.io/collector/pipeline v1.48.0 // indirect go.opentelemetry.io/collector/processor v1.48.0 // indirect go.opentelemetry.io/collector/semconv v0.128.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.44.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 // indirect go.opentelemetry.io/contrib/propagators/autoprop v0.61.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.36.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 // indirect go.opentelemetry.io/contrib/propagators/ot v1.36.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.opentelemetry.io/otel/metric v1.46.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.46.0 // indirect + go.opentelemetry.io/proto/otlp v1.11.0 // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.54.0 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect + golang.org/x/crypto v0.55.0 // indirect golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/mod v0.37.0 // indirect + golang.org/x/mod v0.38.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sys v0.47.0 // indirect - golang.org/x/text v0.40.0 // indirect - golang.org/x/tools v0.47.0 // indirect + golang.org/x/text v0.41.0 // indirect + golang.org/x/tools v0.48.0 // indirect gonum.org/v1/gonum v0.17.0 // indirect google.golang.org/api v0.264.0 // indirect google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect - gopkg.in/ini.v1 v1.67.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // indirect + gopkg.in/ini.v1 v1.67.3 // indirect gopkg.in/telebot.v3 v3.3.8 // indirect k8s.io/apimachinery v0.34.3 // indirect k8s.io/client-go v0.34.3 // indirect diff --git a/go.sum b/go.sum index 14aded077a1..4e667f3e079 100644 --- a/go.sum +++ b/go.sum @@ -158,46 +158,46 @@ github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go-v2 v1.42.0 h1:XvXMJTkFQtpBKIWZnmr9ZEOc2InWM2yldjXEJ/bymhA= -github.com/aws/aws-sdk-go-v2 v1.42.0/go.mod h1:27+ACypSLljLAEKsCYOmrjKh83vuTRkuAe9Uv/3A4bg= -github.com/aws/aws-sdk-go-v2/config v1.32.26 h1:JI+W5B3jUA8UBz2ggbICGd9UCR6/+SB21G8EFl0SFTQ= -github.com/aws/aws-sdk-go-v2/config v1.32.26/go.mod h1:RLE2Ls/wRstvdSz1GPrIWNnXcKZ/znDdWyMuiQxdBoY= -github.com/aws/aws-sdk-go-v2/credentials v1.19.25 h1:TzPVjfUZ1hsKafvYE+DIzKXIik2KufQxsPHanlkttbo= -github.com/aws/aws-sdk-go-v2/credentials v1.19.25/go.mod h1:K4hw0buguVvtC74HnVfTRr0LzQQHAWPqJbBU9QGk2Pg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29 h1:r6qZHbT+wxgWO/e9vYNUEtg7lv5+UN3pRqKhLXvnArg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29/go.mod h1:QRnaRcTVGKPGRy8w78HMQtKUGRYcnMZAANATkeVA6Mo= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 h1:f3vKqSo13fhTYb+JEcXwXefZQE26I1FB5eTSniU67ko= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29/go.mod h1:MzoLFUArKGpGD+ukmPiTPG1X5x4o6M2kq4v2dr1FiEc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 h1:RdwIf/CuUsvJX3RgJagbOyotl/cxoLY4xviKuE7p2GY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29/go.mod h1:71wt8W2EgswdZy9Mf9KNnzxZ3TiZlv4caKghPktDOkA= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 h1:VTGy885W5DKBxWRUJbym9hytNaYzsyaPkCHGRRMAOhU= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30/go.mod h1:AS0HycUvJRFvTt613AYDOgO2jzw+00cVSMny8XB3yMY= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.59.1 h1:GaRPmlTeDxjnp6XipIV4b69PJalB59DcMMClFJeHeMw= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.59.1/go.mod h1:jLkDwIDBkCIpiENQhAOjAR2L9jwj56mZgVEvuro4gUE= +github.com/aws/aws-sdk-go-v2 v1.45.1 h1:iIoG3NaLhV6UZpPXyPXlDj2I9oS8tV/nMcMnITCC6Ks= +github.com/aws/aws-sdk-go-v2 v1.45.1/go.mod h1:bttEH6JqnUL8LepvDVfdrds/fZ5bCIxzpe3abyUrhDU= +github.com/aws/aws-sdk-go-v2/config v1.33.1 h1:bq9jze1hQ5YTCLoVxNnbp0T7rglrlOE7N9YsHqjGkEw= +github.com/aws/aws-sdk-go-v2/config v1.33.1/go.mod h1:2A3HQwG4zaL5Tm80rc6RZj8LmWWv4WYT5v8raSz/L7A= +github.com/aws/aws-sdk-go-v2/credentials v1.20.1 h1:Z8GRNEx0u9sDkZOq4PUnN8mjGwbUQGRzMSXpvt3d8xQ= +github.com/aws/aws-sdk-go-v2/credentials v1.20.1/go.mod h1:uBIK00kFo95dnemqfFMTWx0X8YRqsh6ecIoCjjOkZqM= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.1 h1:YIEBqcqRnpi4Pfv0YHImtgi6czGCwKHANC7SwmUAVD0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.1/go.mod h1:imEf0oufgAo8KAkCHhrOdqGEC0YWx1PPBQH82shSxGw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.1 h1:pc138gM1CW+XPc60rEwUlwwuwWFQK16CI1T7v1F9Oec= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.1/go.mod h1:1+koxpPIbfBdfzP6vojm5/zTpTQ/micYwlxIiNB3TxI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.1 h1:K0JsbZQj+1h208Ro1zHeA4l7bMp0NvRffHQ91q8Ol1s= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.1/go.mod h1:W3/vL6EtCIatICGy9ab29QhMuae+cOKPWcMxv02CO+Q= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.1 h1:yhw5KD1phVyP9vijxOUzDfEtJx+bt+L63k+VfuiYFAA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.1/go.mod h1:ZW2e0d7DYlRxlS9hEiMXE47gTdX5KRN4byUiNbUpG+Q= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.65.1 h1:KD7o9P8cdTqYWMSCslCfFTaOB1SWbKtj+dayFrbQVGI= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.65.1/go.mod h1:1n7X9A0OjJ8CZjeac5PsFxEkIzBioOs223JPLDZ5bbQ= github.com/aws/aws-sdk-go-v2/service/ec2 v1.277.0 h1:RHJSkRXDGkAKrV4CTEsZsZkOmSpxXKO4aKx4rXd94K4= github.com/aws/aws-sdk-go-v2/service/ec2 v1.277.0/go.mod h1:Wg68QRgy2gEGGdmTPU/UbVpdv8sM14bUZmF64KFwAsY= github.com/aws/aws-sdk-go-v2/service/ecs v1.69.5 h1:5nkhwt0d/gjuT3AQ2LUK0aFRNB3MGlzB2elqy/ZsKP4= github.com/aws/aws-sdk-go-v2/service/ecs v1.69.5/go.mod h1:LQMlcWBoiFVD3vUVEz42ST0yTiaDujv2dRE6sXt1yPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 h1:ZD2+BSw9vFsNlKYIasSNt3uDbjqqXIBcM13UJv/Lx2k= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12/go.mod h1:Ms4zlcVBbXbiP7EVLhl+lgjvA/a7YphqQ3Ih3174EmI= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.12.6 h1:Bs2OwYq0HBgHYwfGmUwYIPtTNaGMGAHkRje4jmW2VoI= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.12.6/go.mod h1:OTctu4cW8t7/TRlTKPLT6akzyOkfceMWhtEHqtYDIQQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 h1:DRebniUGZ2MqiiIVmQJ04vIXr918hubdHMnarSLEWyU= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29/go.mod h1:LfRkPCD8YHDM2E5eTkos2UpwYeZnBcVarTa8L59bJHA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 h1:bAdDl/HkGCcGPoe25ToSHEw23VIxt6CT5fLcg111BKg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19/go.mod h1:KaUzbLxv4CeSxh6ZCl9B4m7CuFenS8kUEaDs+f/DQr4= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.13.1 h1:kIfDHRmq8zgw3DB0XxzGTZi19BX7OwIn+yDE9BJ2I1g= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.13.1/go.mod h1:o6YX/HIkSNfumuKUum+FrqrsebMFVJUiGcmGp03WnsQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.1 h1:RmmWQPREQdk9U+PfqeHW3MqZaBaNK7TpV9W3RY+b+7g= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.1/go.mod h1:0A3W4F+68ZnNk5XcNL/e9HFMwnP8RlEicFfy6eOEDyw= github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.10 h1:MQuZZ6Tq1qQabPlkVxrCMdyVl70Ogl4AERZKo+y9Wzo= github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.10/go.mod h1:U5C3JME1ibKESmpzBAqlRpTYZfVbTqrb5ICJm+sVVd8= -github.com/aws/aws-sdk-go-v2/service/signin v1.2.1 h1:BeJmkm5YOZs6lGRGcNoIuLSoTTtGLLCEqlSiRKYodfM= -github.com/aws/aws-sdk-go-v2/service/signin v1.2.1/go.mod h1:LxYujSTLPRlp2vTtcUO/+1ilrew8ytt6SvQyOgejzFQ= +github.com/aws/aws-sdk-go-v2/service/signin v1.7.1 h1:mdMtSVKdQ3+mzBh+l0ogrFYZVQUCg6pJZOirA2ARsYE= +github.com/aws/aws-sdk-go-v2/service/signin v1.7.1/go.mod h1:9IqUlsJDbUPcg6cgx3WEzXdjrbWzLDQrak0aaSqlTcI= github.com/aws/aws-sdk-go-v2/service/sns v1.39.17 h1:synXIPC/L4Cc489P0XDcrVJzHSLj7krKRpFLalbGM2k= github.com/aws/aws-sdk-go-v2/service/sns v1.39.17/go.mod h1:4ABZnI23uNK37waIjGwkubnCwGhepIt9x1GvASfljJA= -github.com/aws/aws-sdk-go-v2/service/sso v1.31.4 h1:i465b/3c7xJd++pobNIDOggouekCuiWOnB0goQJy+94= -github.com/aws/aws-sdk-go-v2/service/sso v1.31.4/go.mod h1:Lk7PlmoTYryQmyBG0EXqj5BcUbj3whXdU2s3yGI3EAc= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.7 h1:xbmJAnBbyYPkTzoCNCF/bpJ6ymQHRdXX1vquYfDIGYk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.7/go.mod h1:Q5N6icH+KJZDLh+ESNwzdv6cZ6vLFF/egy3IOxWhmz4= -github.com/aws/aws-sdk-go-v2/service/sts v1.43.4 h1:Np0vmL7op0Zs5xGacYMMX3v5O5pvZ46xhb5LwDgPj8M= -github.com/aws/aws-sdk-go-v2/service/sts v1.43.4/go.mod h1:r8wkDOuLaaMFqFiYAb8dGY2A3gJCOujMc6CFOVC4Zhc= -github.com/aws/smithy-go v1.27.1 h1:4T340VFndXtADGF52gYa1POyL7s9E4Z1OeZ1hCscIw8= -github.com/aws/smithy-go v1.27.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2/service/sso v1.35.1 h1:B6WFn91tobD6gG4724ONHaqrpKsoETGnv98LHe/yIGM= +github.com/aws/aws-sdk-go-v2/service/sso v1.35.1/go.mod h1:tWuiVBUtPBr8/rgRiYS8Uf85sHcAN+G7XS3D3CEoUh8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.40.1 h1:6yeYCWFvgbI2TI3K6jr9LtBNhXgJ7g4xqD+DEiaDDmM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.40.1/go.mod h1:naFe83jSMuYkH+QjQPX8n1MLhBkeCFM5Lsnh5m5wz3c= +github.com/aws/aws-sdk-go-v2/service/sts v1.47.1 h1:Sv2xPnRHlThSUtVujYuUBPI/Il8si6UPHXL8DMiB/F0= +github.com/aws/aws-sdk-go-v2/service/sts v1.47.1/go.mod h1:mKo/CzaCz8qytGW70NG4vIIGAx1HXTlb5lHNkC5k3lk= +github.com/aws/smithy-go v1.28.1 h1:R/nXH00c8qcfCzQVELtRw+eLQWtzv+VAIEFJ1/xxXlQ= +github.com/aws/smithy-go v1.28.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/axiomhq/hyperloglog v0.2.6 h1:sRhvvF3RIXWQgAXaTphLp4yJiX4S0IN3MWTaAgZoRJw= github.com/axiomhq/hyperloglog v0.2.6/go.mod h1:YjX/dQqCR/7QYX0g8mu8UZAjpIenz1FKM71UEsjFoTo= github.com/baidubce/bce-sdk-go v0.9.230 h1:HzELBKiD7QAgYqZ1qHZexoI2A3Lo/6zYGQFvcUbS5cA= @@ -340,8 +340,8 @@ github.com/fatih/faillint v1.15.0 h1:GBsqRgd/uPvo7AdunUoM4oEBVCE7KCxz77J0f9IKr2w github.com/fatih/faillint v1.15.0/go.mod h1:xg4qfUwfXviSkDlZqJ7cDaf0JyOgR2Hx+a977rJt5Rc= github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY= github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= +github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.10.0 h1:Xx/5Ydg9CeBDX/wi4VJqStNtohYjitZhhlHt4h3St1M= @@ -373,59 +373,61 @@ github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/analysis v0.25.0 h1:EnjAq1yO8wEO9HbPmY8vLPEIkdZuuFhCAKBPvCB7bCs= -github.com/go-openapi/analysis v0.25.0/go.mod h1:5WFTRE43WLkPG9r9OtlMfqkkvUTYLVVCIxLlEpyF8kE= +github.com/go-openapi/analysis v0.25.5 h1:xPYEvTb90o1y0epuiOPAoG4QqahjP3cdp5xNlHeKJRI= +github.com/go-openapi/analysis v0.25.5/go.mod h1:d3UGtQC5uq5Kqqqis2VH09Km/v3vwsWrYkbp4gdm+Rc= github.com/go-openapi/errors v0.22.8 h1:oP7sW7TWc3wFFjrzzj0nI83H2qMBkNjNfSd+XRejk/I= github.com/go-openapi/errors v0.22.8/go.mod h1:BuUoHcYrU6E7V9gfj1I5wLQqgtIHnup/alXZ8KdgQ0w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= -github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= +github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= -github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= -github.com/go-openapi/loads v0.23.3 h1:g5Xap1JfwKkUnZdn+S0L3SzBDpcTIYzZ5Qaag0YDkKQ= -github.com/go-openapi/loads v0.23.3/go.mod h1:NOH07zLajXo8y55hom0omlHWDVVvCwBM/S+csCK8LqA= -github.com/go-openapi/runtime v0.29.4 h1:k2lDxrGoSAJRdhFG2tONKMpkizY/4X1cciSdtzk4Jjo= -github.com/go-openapi/runtime v0.29.4/go.mod h1:K0k/2raY6oqXJnZAgWJB2i/12QKrhUKpZcH4PfV9P18= +github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= +github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= +github.com/go-openapi/loads v0.25.0 h1:74Bc2snfaVlsHzwdQj/3gsA9XJz3daXTJVs+4ZaK7jI= +github.com/go-openapi/loads v0.25.0/go.mod h1:JFBw4SIB9+PTIFHDfcXuSSy5h6aWzjtUCrPYyx3qWU8= +github.com/go-openapi/runtime v0.33.0 h1:Dd3Oj2ig+WH8ckK95l0Wn2V8a4bH/UqWPRZVT0vc8yU= +github.com/go-openapi/runtime v0.33.0/go.mod h1:+rsupH3+TFKqmFysqkmgBOTxpVJV8eV+j9myvvea2Xw= +github.com/go-openapi/runtime/server-middleware v0.30.0 h1:8rPoJ/xv7JL8BsovaqboKETlpWBArVh8n+0L/GyePog= +github.com/go-openapi/runtime/server-middleware v0.30.0/go.mod h1:OYNT/TxNvB/VK5oe4htM2jDTwlEXuejVJmu0DVZfAMs= github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ= github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.26.4 h1:yI6IAEfcWow459BD5UzFY430KUwXZwBHrYusPFkhWlc= -github.com/go-openapi/strfmt v0.26.4/go.mod h1:hNJi6nb5ETD6i7A1yRo03M9S6ZoTPPoWff1iUexmfUc= +github.com/go-openapi/strfmt v0.27.0 h1:kbcTeaD9TXuXD0hhMXzuYa1sdTo6+dWGvwjW93E80IM= +github.com/go-openapi/strfmt v0.27.0/go.mod h1:s/qhDqfY72irigXUGJmtgid2Rm+3tnz3k8hZaRmvWYc= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.26.0 h1:GVDXCmfvhfu1BxiHo8/FA+BbKmhecHnG3varjON5/RI= -github.com/go-openapi/swag v0.26.0/go.mod h1:82g3193sZJRbocs7bNCqGfIgq8pkuwVwCfhKIRlEQF0= -github.com/go-openapi/swag/cmdutils v0.26.0 h1:iowihOcvq7y4egO8cOq0dmfohz6wfeQ63U1EnuhO2TU= -github.com/go-openapi/swag/cmdutils v0.26.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= -github.com/go-openapi/swag/conv v0.27.0 h1:EKOH4feXrvdo8DbSsXSAqRT8fz1epEnS5O2IfXUOzE8= -github.com/go-openapi/swag/conv v0.27.0/go.mod h1:pfiv0uKQTbaGApk8Zs/lZV3uSjmSpa2FO1y183YngN8= -github.com/go-openapi/swag/fileutils v0.26.0 h1:WJoPRvsA7QRiiWluowkLJa9jaYR7FCuxmDvnCgaRRxU= -github.com/go-openapi/swag/fileutils v0.26.0/go.mod h1:0WDJ7lp67eNjPMO50wAWYlKvhOb6CQ37rzR7wrgI8Tc= -github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= -github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= -github.com/go-openapi/swag/jsonutils v0.27.0 h1:VYtd9jEQYeU4j8q5vdn5KWotF4vKywhGdMBrALtAsfE= -github.com/go-openapi/swag/jsonutils v0.27.0/go.mod h1:U7pb8AGuwhok3RDicHeHwSG4L3PXSq6PAL98Aon632g= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0 h1:+d7C7Ur/SsGg/UZ9G0JEovnfRqtMNZCJQGKc2h/ojoE= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= -github.com/go-openapi/swag/loading v0.26.0 h1:Apg6zaKhCJurpJer0DCxq99qwmhFddBhaMX7kilDcko= -github.com/go-openapi/swag/loading v0.26.0/go.mod h1:dBxQ/6V2uBaAQdevN18VELE6xSpJWZxLX4txe12JwDg= -github.com/go-openapi/swag/mangling v0.26.0 h1:Du2YC4YLA/Y5m/YKQd7AnY5qq0wRKSFZTTt8ktFaXcQ= -github.com/go-openapi/swag/mangling v0.26.0/go.mod h1:jifS7W9vbg+pw63bT+GI53otluMQL3CeemuyCHKwVx0= -github.com/go-openapi/swag/netutils v0.26.0 h1:CmZp+ZT7HrmFwrC3GdGsXBq2+42T1bjKBapcqVpIs3c= -github.com/go-openapi/swag/netutils v0.26.0/go.mod h1:5iK+Ok3ZohWWex1C50BFTPexi03UaPwjW4Oj8kgrpwo= -github.com/go-openapi/swag/stringutils v0.26.0 h1:qZQngLxs5s7SLijc3N2ZO+fUq2o8LjuWAASSrJuh+xg= -github.com/go-openapi/swag/stringutils v0.26.0/go.mod h1:sWn5uY+QIIspwPhvgnqJsH8xqFT2ZbYcvbcFanRyhFE= -github.com/go-openapi/swag/typeutils v0.27.0 h1:aCf4MSGo8NLwZP8Q6t32DWLJSvl/WwNqgmEG+xJ6v2o= -github.com/go-openapi/swag/typeutils v0.27.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= -github.com/go-openapi/swag/yamlutils v0.26.0 h1:H7O8l/8NJJQ/oiReEN+oMpnGMyt8G0hl460nRZxhLMQ= -github.com/go-openapi/swag/yamlutils v0.26.0/go.mod h1:1evKEGAtP37Pkwcc7EWMF0hedX0/x3Rkvei2wtG/TbU= -github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= -github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= -github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= -github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= -github.com/go-openapi/validate v0.25.2 h1:12NsfLAwGegqbGWr2CnvT65X/Q2USJipmJ9b7xDJZz0= -github.com/go-openapi/validate v0.25.2/go.mod h1:Pgl1LpPPGFnZ+ys4/hTlDiRYQdI1ocKypgE+8Q8BLfY= +github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw= +github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg= +github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q= +github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= +github.com/go-openapi/swag/conv v0.29.1 h1:AC4Eh/5c/eUDOUCzzsRC9ghmFgOSBHeRMGIngY0ZUGA= +github.com/go-openapi/swag/conv v0.29.1/go.mod h1:S1X7/ZrBEZOC0Wc8AGxjbcGS92l3WEjA7aPtpl+RaqM= +github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU= +github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= +github.com/go-openapi/swag/jsonutils v0.29.1 h1:AFCxs0eQZ24/QyfhVHM2t49rMz7Vv3XCsZQI6yrNy+c= +github.com/go-openapi/swag/jsonutils v0.29.1/go.mod h1:u3+sCfJpttDpcmS5kpm0yxL6GK0eWgODsx8Yw8fcqNM= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.29.1 h1:BiiXE31Bx9SfpsMmOQj5KYpUhTZBpLVriVhJDuLuY2o= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.29.1/go.mod h1:julgTUKZ9/D0j6O7GKajmRs+812FWxQg/mMpGunWSjg= +github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU= +github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k= +github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM= +github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k= +github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= +github.com/go-openapi/swag/pools v0.29.1 h1:NRogYxdEW9SjRM4mkAOji9iefO4MRXq3p/ZJcoQbUKg= +github.com/go-openapi/swag/pools v0.29.1/go.mod h1:leDcaghjkRAhCuCRv9NfJU5f0mjoU3cT/XZObhMk3pc= +github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU= +github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= +github.com/go-openapi/swag/typeutils v0.29.1 h1:Nzv9nhnlLCRBPQqfOX+7lB6Guju370or8StT+lIOf6M= +github.com/go-openapi/swag/typeutils v0.29.1/go.mod h1:hxpgDZJVBkBsi/d3MIUosafoFdE5exaQRmVp0zwu3YE= +github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY= +github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.1 h1:Jm+/ze2rMtbD98yen92AhATGLGREDYXG56Xr4gMjEtE= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.1/go.mod h1:YDPnwCRDu38/oJBVMBVXOUDiJ9cIeBHWvfImHaXqnv4= +github.com/go-openapi/testify/v2 v2.6.1 h1:6CNJhTjMzgaeaH8WhshcsZNPIvRemiOcFpU7seO/y7Q= +github.com/go-openapi/testify/v2 v2.6.1/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= +github.com/go-openapi/validate v0.26.1 h1:pZSbvtRO8G2R2FpWTYRn3w8LrsNwbtaVhP2dWiBa0Us= +github.com/go-openapi/validate v0.26.1/go.mod h1:B8UMgXiQiwwQWIbmuROlwJZDPGlikPuh7iHV1vPX9Oo= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= @@ -588,11 +590,11 @@ github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4z github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 h1:/Tnpcb2E0Pz/tN9s3bfEY2Q8ePCEX9iuS+cneUwncnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0/go.mod h1:zOBXOsUaBSjKgmH4OGzV1esUpR3oUSCPYVd2cUBjKYY= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/api v1.34.3 h1:OiZaQnwkS6uvutie3CF6NFXj8uScNezDlsU9MEqKT0s= -github.com/hashicorp/consul/api v1.34.3/go.mod h1:A4wKd7yw7Wz4zn07p74+o0bLBi5dXsSDMMcMCEinY40= +github.com/hashicorp/consul/api v1.34.4 h1:0U4YZ1Yp7K9WK9ex0gTJraFim26l02wCvsmf2ukalVE= +github.com/hashicorp/consul/api v1.34.4/go.mod h1:vz5gBNeycefpAAVNVbLBFObUu3isju6EK8UVZjXSTWc= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/consul/sdk v0.18.1 h1:RDTeBvAeOveI2xI86sV+8WkaN7OkP4zz+cG3fOobDCM= github.com/hashicorp/consul/sdk v0.18.1/go.mod h1:XdP2tEJmAvlK4jgoKTTtohGkRJlS4mU44mv9/sjU21s= @@ -612,11 +614,13 @@ github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVH github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-metrics v0.6.0 h1:+kjWqHRH2HxAocneVfB/BI6EeWUUHyPhyQZozMT8Ed4= -github.com/hashicorp/go-metrics v0.6.0/go.mod h1:0B52B5pZ7+qm5Zhzs8Fygr87isvmUgr0Zv9rmJ9qsnQ= +github.com/hashicorp/go-metrics v0.6.1 h1:V7j9cgHTXl4OebnX3y0l6ZSoO5dTp0VI0K8Y7JfRsS4= +github.com/hashicorp/go-metrics v0.6.1/go.mod h1:XOozbQKeJz12GG8cCcQb/E5vNVeTdJt0aHbM+uHnL1M= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.5 h1:Ue879bPnutj/hXfmUk6s/jtIK90XxgiUIcXRl656T44= +github.com/hashicorp/go-msgpack/v2 v2.1.5/go.mod h1:bjCsRXpZ7NsJdk45PoCQnzRGDaK8TKm5ZnDI/9y3J4M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -639,8 +643,8 @@ github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= -github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -650,8 +654,8 @@ github.com/hashicorp/nomad/api v0.0.0-20251216171439-1dee0671280e h1:wGl06iy/H90 github.com/hashicorp/nomad/api v0.0.0-20251216171439-1dee0671280e/go.mod h1:sldFTIgs+FsUeKU3LwVjviAIuksxD8TzDOn02MYwslE= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= -github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hashicorp/serf v0.10.4 h1:TCQOrJXHZ1Xf80c4WBhMM9OwUFgDaIP0R+YvoQUKadI= +github.com/hashicorp/serf v0.10.4/go.mod h1:l+s5Q1OSPWU6b9l9m7ODJzTp7mLevSaVzAI03Nka2F0= github.com/hetznercloud/hcloud-go/v2 v2.32.0 h1:BRe+k7ESdYv3xQLBGdKUfk+XBFRJNGKzq70nJI24ciM= github.com/hetznercloud/hcloud-go/v2 v2.32.0/go.mod h1:hAanyyfn9M0cMmZ68CXzPCF54KRb9EXd8eiE2FHKGIE= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -685,11 +689,11 @@ github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRt github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= -github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= +github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= -github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= +github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= @@ -740,16 +744,16 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= +github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= +github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= @@ -759,14 +763,14 @@ github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQo github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a/go.mod h1:3OETvrxfELvGsU2RoGGWercfeZ4bCL3+SOwzIWtJH/Q= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc= -github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g= +github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= +github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.2.1 h1:PfBfwvKB/MmqyN8Vb1G9voWisaM9OrLv+WwOvMwS9Dw= -github.com/minio/minio-go/v7 v7.2.1/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0= +github.com/minio/minio-go/v7 v7.3.0 h1:HM4pFCSQq/TK+j0/zmorSh5ddh81iDgRgU0BG0Vz/YU= +github.com/minio/minio-go/v7 v7.3.0/go.mod h1:KUPWdecEO1LWyUz+sTGXAuf2jZHrPh5fCsRH86QbPfk= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= @@ -815,8 +819,8 @@ github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= -github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/oklog/ulid/v2 v2.1.2 h1:IEclFb9JNvzYA6MW2SCxbLzcHTVsfqm3PrqGQJH5zec= +github.com/oklog/ulid/v2 v2.1.2/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= @@ -833,8 +837,8 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opentracing-contrib/go-grpc v0.1.4 h1:m9VukGYQ+tfcgtwdsifjjFtAoWRqmcbnGhgRQcZ+ZQA= github.com/opentracing-contrib/go-grpc v0.1.4/go.mod h1:xP8rkWX/qdQJVTkf01D6Fc002zN0WUMKsvuKg7Tf93E= -github.com/opentracing-contrib/go-grpc/test v0.0.0-20260727233914-064b4d2bcbbf h1:xfFA+XblffDh3LsTrbSG1MHpmrXsY/9GQI4sbCnY+kI= -github.com/opentracing-contrib/go-grpc/test v0.0.0-20260727233914-064b4d2bcbbf/go.mod h1:AYO7D5MbvWwD7/UggkDbqyW0pDt7KZyQkHCn4IC2i/w= +github.com/opentracing-contrib/go-grpc/test v0.0.0-20260818233951-8a7674689da3 h1:h/3uavyXDWrPyriPf/W2zutFYtV3LJ4/ChiARlwc8dA= +github.com/opentracing-contrib/go-grpc/test v0.0.0-20260818233951-8a7674689da3/go.mod h1:prtVLN+YEqwflFNqkR77tvsZp3KRTM4nxnAIhDvxr/U= github.com/opentracing-contrib/go-stdlib v1.1.1 h1:nl22krMt3PpAWPCKpDjFiAH4Qdr2855F5wOkQ52C0+w= github.com/opentracing-contrib/go-stdlib v1.1.1/go.mod h1:S0p+X9p6dcBkoMTL+Qq2VOvxKs9ys5PpYWXWqlCS0bQ= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -849,8 +853,8 @@ github.com/parquet-go/bitpack v1.0.0 h1:AUqzlKzPPXf2bCdjfj4sTeacrUwsT7NlcYDMUQxP github.com/parquet-go/bitpack v1.0.0/go.mod h1:XnVk9TH+O40eOOmvpAVZ7K2ocQFrQwysLMnc6M/8lgs= github.com/parquet-go/jsonlite v1.0.0 h1:87QNdi56wOfsE5bdgas0vRzHPxfJgzrXGml1zZdd7VU= github.com/parquet-go/jsonlite v1.0.0/go.mod h1:nDjpkpL4EOtqs6NQugUsi0Rleq9sW/OtC1NnZEnxzF0= -github.com/parquet-go/parquet-go v0.30.1 h1:Oy6ganNrAdFiVwy7wNmWagfPTWA2X9Z3tVHBc7JtuX8= -github.com/parquet-go/parquet-go v0.30.1/go.mod h1:navtkAYr2LGoJVp141oXPlO/sxLvaOe3la2JEoD8+rg= +github.com/parquet-go/parquet-go v0.32.0 h1:NWDqTUHfrCS4cJP/Fj2HlxvqsrVedWG3sayMkf+znzM= +github.com/parquet-go/parquet-go v0.32.0/go.mod h1:navtkAYr2LGoJVp141oXPlO/sxLvaOe3la2JEoD8+rg= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -889,8 +893,8 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= -github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU= +github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE= github.com/prometheus/client_golang/exp v0.0.0-20251212205219-7ba246a648ca h1:BOxmsLoL2ymn8lXJtorca7N/m+2vDQUDoEtPjf0iAxA= github.com/prometheus/client_golang/exp v0.0.0-20251212205219-7ba246a648ca/go.mod h1:gndBHh3ZdjBozGcGrjUYjN3UJLRS3l2drALtu4lUt+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -903,8 +907,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85CuiNk= -github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= +github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY= +github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc= github.com/prometheus/exporter-toolkit v0.16.0 h1:xT/j7L2XKF+VJd6B4fpUw6xWabHrSmsUf6mYmFqyu0s= github.com/prometheus/exporter-toolkit v0.16.0/go.mod h1:d1EL8Z9674xQe/iWhwP2wDyCEoBPbXVeqDbqAUsgJWY= github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= @@ -914,8 +918,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.21.0 h1:Qh/e6TlBjZf+XLLqNCqFGmCU6Kj/2Bu7kj3oAc0UnXc= -github.com/prometheus/procfs v0.21.0/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= +github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= +github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= github.com/prometheus/prometheus v0.309.1 h1:jutK6eCYDpWdPTUbVbkcQsNCMO9CCkSwjQRMLds4jSo= github.com/prometheus/prometheus v0.309.1/go.mod h1:d+dOGiVhuNDa4MaFXHVdnUBy/CzqlcNTooR8oM1wdTU= github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs= @@ -975,8 +979,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -990,8 +995,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0= @@ -1005,10 +1011,10 @@ github.com/thanos-io/promql-engine v0.0.0-20260729073658-f8bd3f940687 h1:r9VYttK github.com/thanos-io/promql-engine v0.0.0-20260729073658-f8bd3f940687/go.mod h1:uzn40oZHPXvfdP498h+MiRL2fN7RF519gNaV3LyhChc= github.com/thanos-io/thanos v0.42.1-0.20260727122508-92397939e4cc h1:Sx5AfjHy6OspiLdJTFUO8DsfndpMNM8mbkMBMXtVFqc= github.com/thanos-io/thanos v0.42.1-0.20260727122508-92397939e4cc/go.mod h1:GH7XiOiHgMLvIST9qgcy/UuhtV22umoBCXAceOFMzCA= -github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY= -github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= -github.com/tjhop/slog-gokit v0.2.0 h1:tUNkuukDjpswQ2abhsugEobRRxN1aHEW8h4rvwdHMqU= -github.com/tjhop/slog-gokit v0.2.0/go.mod h1:yA48zAHvV+Sg4z4VRyeFyFUNNXd3JY5Zg84u3USICq0= +github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ= +github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= +github.com/tjhop/slog-gokit v0.2.2 h1:ev90r/tMq5cx7q6lMuhJ6v7fjsr1bDho7W2BLAFVwtI= +github.com/tjhop/slog-gokit v0.2.2/go.mod h1:yA48zAHvV+Sg4z4VRyeFyFUNNXd3JY5Zg84u3USICq0= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twmb/franz-go v1.21.2 h1:WrvV/spF48JzcRylqDQy02Vm6V6W4lhtD9Y4BOYNMu4= github.com/twmb/franz-go v1.21.2/go.mod h1:rfoMTnVk7107fhTGxfEKIHP/e7tPe6oyij/ywzO0czk= @@ -1085,12 +1091,12 @@ go.opentelemetry.io/collector/consumer/consumertest v0.142.0 h1:TRt8zR57Vk1PTjtq go.opentelemetry.io/collector/consumer/consumertest v0.142.0/go.mod h1:yq2dhMxFUlCFkRN7LES3fzsTmUDw9VaunyRAka2TEaY= go.opentelemetry.io/collector/consumer/xconsumer v0.142.0 h1:qOoQnLZXQ9sRLexTkkmBx3qfaOmEgco9VBPmryg5UhA= go.opentelemetry.io/collector/consumer/xconsumer v0.142.0/go.mod h1:oPN0yJzEpovwlWvmSaiYgtDqGuOmMMLmmg352sqZdsE= -go.opentelemetry.io/collector/featuregate v1.61.0 h1:XtnQ/XPHLmw9zgg4Cjq/f0rgdqn7z1M10wnmGhgNbYk= -go.opentelemetry.io/collector/featuregate v1.61.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= -go.opentelemetry.io/collector/internal/testutil v0.155.0 h1:ExZ3lqM1e1Y83AAXKr6Xsw20v4LHW6GZ8VeLLQHiOrA= -go.opentelemetry.io/collector/internal/testutil v0.155.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= -go.opentelemetry.io/collector/pdata v1.61.0 h1:EVfGB/9dcyMXhMsZ5kzKeGFJj8QWqvmZjgg4RMjnRhE= -go.opentelemetry.io/collector/pdata v1.61.0/go.mod h1:qYEsyeIJ9tWHb2jSR5HQ9/VmbCGVca+G+ZDAB8dFCMc= +go.opentelemetry.io/collector/featuregate v1.65.0 h1:Dh+uYVB+POc5DTebZRWjtKJolGhevkiIpbHn+zhkq2o= +go.opentelemetry.io/collector/featuregate v1.65.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= +go.opentelemetry.io/collector/internal/testutil v0.159.0 h1:/OfAv3ZRIc3eVFFq4bFc+Ju5HQBebiWywgvAcysIX4M= +go.opentelemetry.io/collector/internal/testutil v0.159.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= +go.opentelemetry.io/collector/pdata v1.65.0 h1:6bQ3sIrEzOdapetxYFjdCns90kKXg1qCoIZ3la1aR5E= +go.opentelemetry.io/collector/pdata v1.65.0/go.mod h1:r5vRY0p7nZcEif06twUW09Sf6vaNsyPzij+EpwI/xeI= go.opentelemetry.io/collector/pdata/pprofile v0.142.0 h1:Ivyw7WY8SIIWqzXsnNmjEgz3ysVs/OkIf0KIpJUnuuo= go.opentelemetry.io/collector/pdata/pprofile v0.142.0/go.mod h1:94GAph54K4WDpYz9xirhroHB3ptNLuPiY02k8fyoNUI= go.opentelemetry.io/collector/pdata/testdata v0.142.0 h1:+jf9RyLWl8WyhIVjpg7yuH+bRdQH4mW20cPtCMlY1cI= @@ -1107,53 +1113,53 @@ go.opentelemetry.io/collector/semconv v0.128.0 h1:MzYOz7Vgb3Kf5D7b49pqqgeUhEmOCu go.opentelemetry.io/collector/semconv v0.128.0/go.mod h1:OPXer4l43X23cnjLXIZnRj/qQOjSuq4TgBLI76P9hns= go.opentelemetry.io/contrib/detectors/gcp v1.44.0 h1:NmLfL734pJhM0JKaYd2Y28+nY9dPRWYAAbxhRCrKXPw= go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0 h1:oECp5f+hN7nkwjU/8BxQ/q23bGPb8FIrD839owX222E= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0/go.mod h1:DqEFwLumhzMBDQv9PcWbyoDxHI/4lAk6CM4nJBH39sc= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 h1:cuXaPAfIoJKsYjBjPSb2nKZEmgM43zVr25l37IxhKME= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0/go.mod h1:BuzhPofpCzlDi/Q/Xjg54M4/3oWqqyDe2Zeq7A2I0QE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 h1:LMuyCAyfalSjDyjdC65nK6N0zoTT63+E/u95X0JovZI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0/go.mod h1:085m8qbm4hgc8rZWGDEa4vmyyo2c3nPxUslYUKUIU04= go.opentelemetry.io/contrib/propagators/autoprop v0.61.0 h1:cxOVDJ30qfzV27G5p9WMtJUB/3cXC0iL+u9EV1fSOws= go.opentelemetry.io/contrib/propagators/autoprop v0.61.0/go.mod h1:Y+xiUbWetg65vAroDZcIzJ5wyPNWRH32EoIV9rIaa0g= -go.opentelemetry.io/contrib/propagators/aws v1.44.0 h1:Rtvfd6nTbAF2csjiw41m1DfuqC5TneXs+gB84ZA3gq4= -go.opentelemetry.io/contrib/propagators/aws v1.44.0/go.mod h1:auu0tIyZErQGLLUvOp9DgmhKALIoebR4Fpkt9CT0c0k= +go.opentelemetry.io/contrib/propagators/aws v1.46.0 h1:JslT1wq/5vb6lQsbdOqShvIEs7sDlf0IvKxNZdadfjY= +go.opentelemetry.io/contrib/propagators/aws v1.46.0/go.mod h1:JE4srRJf2cRJcJjRaNhViFjyFJqiCZJiDVlqe6GWXsA= go.opentelemetry.io/contrib/propagators/b3 v1.36.0 h1:xrAb/G80z/l5JL6XlmUMSD1i6W8vXkWrLfmkD3w/zZo= go.opentelemetry.io/contrib/propagators/b3 v1.36.0/go.mod h1:UREJtqioFu5awNaCR8aEx7MfJROFlAWb6lPaJFbHaG0= go.opentelemetry.io/contrib/propagators/jaeger v1.36.0 h1:SoCgXYF4ISDtNyfLUzsGDaaudZVTx2yJhOyBO0+/GYk= go.opentelemetry.io/contrib/propagators/jaeger v1.36.0/go.mod h1:VHu48l0YTRKSObdPQ+Sb8xMZvdnJlN7yhHuHoPgNqHM= go.opentelemetry.io/contrib/propagators/ot v1.36.0 h1:UBoZjbx483GslNKYK2YpfvePTJV4BHGeFd8+b7dexiM= go.opentelemetry.io/contrib/propagators/ot v1.36.0/go.mod h1:adDDRry19/n9WoA7mSCMjoVJcmzK/bZYzX9SR+g2+W4= -go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= -go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/bridge/opentracing v1.45.0 h1:hFf959SYHZpFc8ZWlqiYlnH3Ke5w4fcWZh7He+CmqXk= -go.opentelemetry.io/otel/bridge/opentracing v1.45.0/go.mod h1:etOoQoentzhTX0XTaRJmwlsiQx8TXD7mHo76YxNeBYg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo= +go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc= +go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE= +go.opentelemetry.io/otel/bridge/opentracing v1.46.0 h1:CwwxvAh7Ae3guKD8axpBBr6kQp7rusFYvKGxnFIyP4s= +go.opentelemetry.io/otel/bridge/opentracing v1.46.0/go.mod h1:b96KdqscfVMDeEUsfv7YR5kELEWxRGC0pj/wN+r0jhQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 h1:OFnwLJr+pF3iHrlGSzbxyuo6/6HyBlnlN1CWEJmBVcw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0/go.mod h1:716wFneO0ov19A2beH5hjfh9AK5z/VWNAtDijp1Y0/g= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 h1:w53CDeOA/Kurp7yRsegSr6pbbr759dOvJ+yNmWM6Hxs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0/go.mod h1:BOmGMCbAtvcJiSJ+hLuhgPLdDbimnraSl8irz3iY8sY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= -go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= -go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= -go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= -go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= +go.opentelemetry.io/otel/metric v1.46.0 h1:yBnkXvgV7AXFILZc5K6IZe/CBFF3OS7BJ8ov6/lj0K8= +go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o= +go.opentelemetry.io/otel/metric/x v0.68.0 h1:TA/cBT23D3MnxYPwHL7YFOdYGdx0A0v+s7Mzotpd1dU= +go.opentelemetry.io/otel/metric/x v0.68.0/go.mod h1:agudOmvWhwUTjgibWDzxD2PoWYnpw5Ht5jISYOD2Hd4= +go.opentelemetry.io/otel/sdk v1.46.0 h1:h5CNQQjEbuQXY/JfZtgt3i7HVFV3aHPO2OAwO2eTYPI= +go.opentelemetry.io/otel/sdk v1.46.0/go.mod h1:GAERFXFt5SYCEB+YiKUbMBeza6UaDH7GmGOZEfh2gSM= +go.opentelemetry.io/otel/sdk/metric v1.46.0 h1:0piZ26EG4RBfebb2jhDH6ERCYHoVWduc3kLgPCwSnSE= +go.opentelemetry.io/otel/sdk/metric v1.46.0/go.mod h1:I1PbKrdVc8Qu8HYVDNtqVIwLwjNrhsV/uFuxfwg8mO4= +go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c= +go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= -go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= -go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= -go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= +go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk= +go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= +go.opentelemetry.io/proto/slim/otlp v1.11.0 h1:zB37f+f99+y6UIZR4h7UpwbXd5kFNyip35U7GaJ/Jik= +go.opentelemetry.io/proto/slim/otlp v1.11.0/go.mod h1:mI3DeND+VXZuA4keqFPKDJ3BklwveYm1JqBcEWKDEOM= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.4.0 h1:mt+DWtks0biKnz0jXMpDbxWN0CHJi6OJDKe4GcREkcs= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.4.0/go.mod h1:7UXaX/7uT+kumUHd3LIWyjMlklEp0mPlrE9xmtbG6/8= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.4.0 h1:rLHkdB6eHDiRSIoz0cvNuTJsVJBxaL6IyS1e9BSaXLY= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.4.0/go.mod h1:BrX0dmOGsMuWNXXbFafTD7Gb6F3yK+2czVQ6+c24Cnk= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -1171,8 +1177,8 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1186,8 +1192,8 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= -golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1227,8 +1233,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= -golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= +golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1281,8 +1287,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1431,8 +1437,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= -golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1496,8 +1502,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= -golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= +golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1636,10 +1642,10 @@ google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 h1:ax2KzoSRIZU/M0cIxri3pKxy99vniH1PVxWC6si/eZI= +google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688/go.mod h1:1RJ9BQGyNdZwkGc1eTqkErfRZ6RJyYPHZo73BZ1vQqI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1671,8 +1677,8 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ= -google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y= +google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1688,8 +1694,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1702,8 +1708,8 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWM gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss= -gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= +gopkg.in/ini.v1 v1.67.3 h1:iM9Lhz5MRSGhHVGGwCuzG9KO8PoirCXj/m/qTmOJJQw= +gopkg.in/ini.v1 v1.67.3/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= gopkg.in/telebot.v3 v3.3.8 h1:uVDGjak9l824FN9YARWUHMsiNZnlohAVwUycw21k6t8= gopkg.in/telebot.v3 v3.3.8/go.mod h1:1mlbqcLTVSfK9dx7fdp+Nb5HZsy4LLPtpZTKmwhwtzM= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go index 372b1512487..0183a1222ac 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go @@ -164,6 +164,14 @@ type Config struct { // the shared config profile attribute request_min_compression_size_bytes RequestMinCompressSizeBytes int64 + // DisableClockSkewCorrection turns off SDK clock skew correction. When set + // the SDK will not adjust request signing timestamps to compensate for + // drift between the client and service clocks. Set to false (enabled) by + // default. This variable is sourced from the environment variable + // AWS_DISABLE_CLOCK_SKEW_CORRECTION or the shared config profile attribute + // disable_clock_skew_correction. + DisableClockSkewCorrection bool + // Controls how a resolved AWS account ID is handled for endpoint routing. AccountIDEndpointMode AccountIDEndpointMode diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go index 46cb77c209d..6bfd0dfa751 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go @@ -3,4 +3,4 @@ package aws // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.42.0" +const goModuleVersion = "1.45.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go index d66f0960aa5..ba2082411fb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go @@ -15,6 +15,8 @@ type RegisterServiceMetadata struct { SigningName string Region string OperationName string + + RequiresLegacyEndpoints bool } // ID returns the middleware identifier. @@ -33,10 +35,13 @@ func (s RegisterServiceMetadata) HandleInitialize( ctx = SetSigningName(ctx, s.SigningName) } if len(s.Region) > 0 { - ctx = setRegion(ctx, s.Region) + ctx = SetRegion(ctx, s.Region) } if len(s.OperationName) > 0 { - ctx = setOperationName(ctx, s.OperationName) + ctx = SetOperationName(ctx, s.OperationName) + } + if s.RequiresLegacyEndpoints { + ctx = SetRequiresLegacyEndpoints(ctx, true) } return next.HandleInitialize(ctx, in) } @@ -161,19 +166,19 @@ func SetServiceID(ctx context.Context, value string) context.Context { return middleware.WithStackValue(ctx, serviceIDKey{}, value) } -// setRegion sets the endpoint region on the context. +// SetRegion sets the endpoint region on the context. // // Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues // to clear all stack values. -func setRegion(ctx context.Context, value string) context.Context { +func SetRegion(ctx context.Context, value string) context.Context { return middleware.WithStackValue(ctx, regionKey{}, value) } -// setOperationName sets the service operation on the context. +// SetOperationName sets the service operation on the context. // // Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues // to clear all stack values. -func setOperationName(ctx context.Context, value string) context.Context { +func SetOperationName(ctx context.Context, value string) context.Context { return middleware.WithStackValue(ctx, operationNameKey{}, value) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go index 6d5f0079c2f..3c4f2caecb7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go @@ -43,7 +43,12 @@ func (r ClientRequestID) HandleBuild(ctx context.Context, in middleware.BuildInp } // RecordResponseTiming records the response timing for the SDK client requests. -type RecordResponseTiming struct{} +type RecordResponseTiming struct { + // DisableClockSkewCorrection suppresses recording of clock skew observed + // from the response, per the Clock Skew Correction SEP. Response timing is + // still recorded. + DisableClockSkewCorrection bool +} // ID is the middleware identifier func (a *RecordResponseTiming) ID() string { @@ -54,14 +59,17 @@ func (a *RecordResponseTiming) ID() string { func (a RecordResponseTiming) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { + requestAt := sdk.NowTime() out, metadata, err = next.HandleDeserialize(ctx, in) responseAt := sdk.NowTime() setResponseAt(&metadata, responseAt) var serverTime time.Time + var hasAgeHeader bool switch resp := out.RawResponse.(type) { case *smithyhttp.Response: + hasAgeHeader = len(resp.Header.Get("Age")) > 0 respDateHeader := resp.Header.Get("Date") if len(respDateHeader) == 0 { break @@ -77,14 +85,45 @@ func (a RecordResponseTiming) HandleDeserialize(ctx context.Context, in middlewa setServerTime(&metadata, serverTime) } - if !serverTime.IsZero() { - attemptSkew := serverTime.Sub(responseAt) - setAttemptSkew(&metadata, attemptSkew) + if !a.DisableClockSkewCorrection { + if skew, ok := computeClockSkew(serverTime, requestAt, responseAt, hasAgeHeader); ok { + setAttemptSkew(&metadata, skew) + } } return out, metadata, err } +// maxTrustedRequestDuration bounds how long a request may take before the SDK +// discards the skew measurement derived from its response. A slower round trip +// could only produce a signing failure if it pushed the timestamp outside the +// SigV4 validity window. See the Clock Skew Correction SEP. +const maxTrustedRequestDuration = 15 * time.Minute + +// computeClockSkew derives a clock skew candidate from a response per the Clock +// Skew Correction SEP. It returns ok=false (no candidate) when the Date header +// was absent/unparseable (serverTime zero), the round trip exceeded the maximum +// trusted request duration, or the response was served from a cache (Age +// header present). Otherwise the skew is the difference between the server's +// Date and the midpoint of the request round trip. +func computeClockSkew(serverTime, requestAt, responseAt time.Time, hasAgeHeader bool) (time.Duration, bool) { + if serverTime.IsZero() { + return 0, false + } + + if hasAgeHeader { + return 0, false + } + + elapsed := responseAt.Sub(requestAt) + if elapsed > maxTrustedRequestDuration { + return 0, false + } + + midpoint := requestAt.Add(elapsed / 2) + return serverTime.Sub(midpoint), true +} + type responseAtKey struct{} // GetResponseAt returns the time response was received at. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go index ab024de047b..126dcf47bd7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go @@ -48,6 +48,12 @@ type Attempt struct { // call. ClientSkew *atomic.Int64 + // DisableClockSkewCorrection disables clock skew correction per the Clock + // Skew Correction SEP: observed skew is not applied to the signing + // timestamp, not recorded into ClientSkew, and clock skew error codes are + // not treated as retry candidates. + DisableClockSkewCorrection bool + retryer aws.RetryerV2 requestCloner RequestCloner } @@ -88,7 +94,7 @@ func (r *Attempt) HandleFinalize(ctx context.Context, in smithymiddle.FinalizeIn out smithymiddle.FinalizeOutput, metadata smithymiddle.Metadata, err error, ) { var attemptClockSkew time.Duration - if r.ClientSkew != nil { + if !r.DisableClockSkewCorrection && r.ClientSkew != nil { attemptClockSkew = time.Duration(r.ClientSkew.Load()) } @@ -159,7 +165,7 @@ func (r *Attempt) HandleFinalize(ctx context.Context, in smithymiddle.FinalizeIn // this guarantees we are staying on top of the persistent skew value // (either to apply it or to heal it back if the clocks realign) - if r.ClientSkew != nil { + if !r.DisableClockSkewCorrection && r.ClientSkew != nil { if resultSkew, ok := awsmiddle.GetAttemptSkew(metadata); ok { r.ClientSkew.Store(resultSkew.Nanoseconds()) } @@ -245,7 +251,10 @@ func (r *Attempt) handleAttempt( return out, attemptResult, nopRelease, err } - err = wrapAsClockSkew(ctx, err) + if !r.DisableClockSkewCorrection { + candidateSkew, hasCandidateSkew := awsmiddle.GetAttemptSkew(metadata) + err = wrapAsClockSkew(err, candidateSkew, hasCandidateSkew, retryMetadata.AttemptClockSkew) + } //------------------------------ // Is Retryable and Should Retry @@ -316,37 +325,66 @@ func (r *Attempt) handleAttempt( return out, attemptResult, releaseRetryToken, err } -// errors that, if detected when we know there's a clock skew, -// can be retried and have a high chance of success -var possibleSkewCodes = map[string]struct{}{ +// clockSkewCodes are the error codes that may indicate a clock skew problem. +// Per the Clock Skew Correction SEP these are retryable only when the absolute +// skew observed from the response Date header exceeds the detection threshold. +// The SEP does not distinguish "definite" from "possible" skew errors: modern +// services overload a single code (e.g. InvalidSignatureException) for both +// skewed and genuinely malformed signatures, so every code is gated on the +// observed skew. +var clockSkewCodes = map[string]struct{}{ "InvalidSignatureException": {}, "SignatureDoesNotMatch": {}, "AuthFailure": {}, + "RequestTimeTooSkewed": {}, + "AccessDeniedException": {}, } -var definiteSkewCodes = map[string]struct{}{ - "RequestExpired": {}, - "RequestInTheFuture": {}, - "RequestTimeTooSkewed": {}, -} - -// wrapAsClockSkew checks if this error could be related to a clock skew -// error and if so, wrap the error. -func wrapAsClockSkew(ctx context.Context, err error) error { +// wrapAsClockSkew classifies err as a retryable clock skew error when its code +// is a known clock skew code and the signing time diverges from the server +// time by more than the detection threshold. +// +// The signing time is now() + attemptSkew. The server time is now() + +// candidateSkew (derived from the response Date header). The signing error is: +// +// |attemptSkew - candidateSkew| > skewThreshold +// +// This single check covers both fresh skew detection (attemptSkew is zero on +// first attempt, so the error equals |candidateSkew|) and stale offset healing +// (attemptSkew is large but the server and client clocks have realigned, so +// candidateSkew is near zero). +// +// If no candidate was observed (the Date header was absent, unparseable, or +// discarded as untrusted), the error is not treated as clock skew. +func wrapAsClockSkew(err error, candidateSkew time.Duration, hasCandidateSkew bool, attemptSkew time.Duration) error { var v interface{ ErrorCode() string } if !errors.As(err, &v) { return err } - if _, ok := definiteSkewCodes[v.ErrorCode()]; ok { - return &retryableClockSkewError{Err: err} + + if _, ok := clockSkewCodes[v.ErrorCode()]; !ok { + return err } - _, isPossibleSkewCode := possibleSkewCodes[v.ErrorCode()] - if skew := internalcontext.GetAttemptSkewContext(ctx); skew > skewThreshold && isPossibleSkewCode { + + if !hasCandidateSkew { + return err + } + + if absDuration(attemptSkew-candidateSkew) > skewThreshold { return &retryableClockSkewError{Err: err} } + return err } +func absDuration(d time.Duration) time.Duration { + if d < 0 { + return -d + } + + return d +} + // MetricsHeader attaches SDK request metric header for retries to the transport type MetricsHeader struct{} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go index d99b32ceb07..0b9ddd13ba3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go @@ -58,6 +58,10 @@ var RequiredSignedHeaders = Rules{ "X-Amz-Tagging": struct{}{}, }, }, + InclusiveRules{ + Patterns{"X-Amz-Checksum-"}, + ExcludeList{Patterns{"X-Amz-Checksum-Mode"}}, + }, Patterns{"X-Amz-Object-Lock-"}, Patterns{"X-Amz-Meta-"}, } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go index 49cc31205c5..50b7417c28a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go @@ -2,6 +2,7 @@ package http import ( "context" + "crypto/fips140" "crypto/tls" "net" "net/http" @@ -27,6 +28,19 @@ var ( // Default to TLS 1.2 for all HTTPS requests. DefaultHTTPTransportTLSMinVersion uint16 = tls.VersionTLS12 + + // DefaultHTTPTransportTLSCurvePreferencesFIPS is the elliptic curve preference + // list applied to the default transport when the FIPS 140-3 module is active. + // + // Go's default preferences lead with X25519, which crypto/ecdh rejects under + // GODEBUG=fips140=only, failing every TLS handshake the SDK attempts. Only the + // NIST curves are FIPS-approved, so restricting to them keeps the default + // client usable in FIPS deployments. + DefaultHTTPTransportTLSCurvePreferencesFIPS = []tls.CurveID{ + tls.CurveP256, + tls.CurveP384, + tls.CurveP521, + } ) // Timeouts for net.Dialer's network connection. @@ -48,6 +62,7 @@ type BuildableClient struct { initOnce sync.Once clientTimeout time.Duration + readTimeout *time.Duration client *http.Client } @@ -82,9 +97,12 @@ func (b *BuildableClient) Freeze() aws.HTTPClient { } func (b *BuildableClient) build() { + tr := b.GetTransport() + b.installReadTimeout(tr) + b.client = wrapWithLimitedRedirect(&http.Client{ Timeout: b.clientTimeout, - Transport: b.GetTransport(), + Transport: tr, }) } @@ -93,6 +111,7 @@ func (b *BuildableClient) clone() *BuildableClient { cpy.transport = b.GetTransport() cpy.dialer = b.GetDialer() cpy.clientTimeout = b.clientTimeout + cpy.readTimeout = b.readTimeout return cpy } @@ -141,6 +160,25 @@ func (b *BuildableClient) WithTimeout(timeout time.Duration) *BuildableClient { return cpy } +// WithReadTimeout copies the BuildableClient and returns it with the read +// timeout set. +// +// The timeout is the maximum time the client waits for a connection to deliver +// any data. It resets on every byte received, so a slow but progressing response +// does not fail. It is not a deadline on the operation; use WithTimeout for that. +// +// A value set here takes precedence over the SDK's defaults for every service +// this client is used with, including services the SDK would otherwise apply a +// higher value to or exempt entirely. Pass 0 to disable read timeouts. +// +// The timeout is applied per connection, so a client shared between service +// clients applies the same value to all of them. +func (b *BuildableClient) WithReadTimeout(timeout time.Duration) *BuildableClient { + cpy := b.clone() + cpy.readTimeout = &timeout + return cpy +} + // GetTransport returns a copy of the client's HTTP Transport. func (b *BuildableClient) GetTransport() *http.Transport { var tr *http.Transport @@ -170,6 +208,17 @@ func (b *BuildableClient) GetTimeout() time.Duration { return b.clientTimeout } +// GetReadTimeout returns the configured read timeout and whether one was set on +// this client. When it was not, the SDK resolves a default per +// service. +func (b *BuildableClient) GetReadTimeout() (time.Duration, bool) { + if b.readTimeout == nil { + return 0, false + } + + return *b.readTimeout, true +} + func defaultDialer() *net.Dialer { return &net.Dialer{ Timeout: DefaultDialConnectTimeout, @@ -178,6 +227,16 @@ func defaultDialer() *net.Dialer { } } +// defaultTLSCurvePreferences returns the curve preferences for the default +// transport. Outside FIPS mode it returns nil so Go's own defaults apply, +// preserving X25519 and the post-quantum X25519MLKEM768 hybrid. +func defaultTLSCurvePreferences(fipsEnabled bool) []tls.CurveID { + if !fipsEnabled { + return nil + } + return DefaultHTTPTransportTLSCurvePreferencesFIPS +} + func defaultHTTPTransport() *http.Transport { dialer := defaultDialer() @@ -192,7 +251,8 @@ func defaultHTTPTransport() *http.Transport { ExpectContinueTimeout: DefaultHTTPTransportExpectContinueTimeout, ForceAttemptHTTP2: true, TLSClientConfig: &tls.Config{ - MinVersion: DefaultHTTPTransportTLSMinVersion, + MinVersion: DefaultHTTPTransportTLSMinVersion, + CurvePreferences: defaultTLSCurvePreferences(fips140.Enabled()), }, } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeouts.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeouts.go new file mode 100644 index 00000000000..fbd23ef9712 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeouts.go @@ -0,0 +1,54 @@ +package http + +import ( + "context" + "errors" + "net" + "net/http" + "os" + "time" +) + +// deadlineConn applies a rolling inactivity window to reads on a connection by +// resetting the read deadline before each one. A read returns as soon as any +// bytes are available, so a slow but progressing transfer survives, and a +// connection that goes silent fails once. +type deadlineConn struct { + net.Conn + timeout time.Duration +} + +// Read implements [io.Reader]. +func (c *deadlineConn) Read(p []byte) (int, error) { + if err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)); err != nil { + return 0, err + } + + n, err := c.Conn.Read(p) + if errors.Is(err, os.ErrDeadlineExceeded) { + return n, &ResponseTimeoutError{TimeoutDur: c.timeout} + } + + return n, err +} + +func (b *BuildableClient) installReadTimeout(tr *http.Transport) { + timeout, ok := b.GetReadTimeout() + if !ok || timeout <= 0 { + return + } + + dial := tr.DialContext + if dial == nil { + dial = defaultDialer().DialContext + } + + tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + conn, err := dial(ctx, network, addr) + if err != nil { + return nil, err + } + + return &deadlineConn{Conn: conn, timeout: timeout}, nil + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md index 520b2379b9c..484c98b6436 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md @@ -1,3 +1,75 @@ +# v1.33.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.40 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.39 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.38 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.37 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.36 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.35 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.34 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.32.33 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.32 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.31 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.30 (2026-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.29 (2026-07-08.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.28 (2026-07-06) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.27 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.32.26 (2026-06-29) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/config.go index c6a6365a39a..f056bf416ec 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/config.go @@ -77,6 +77,8 @@ var defaultAWSConfigResolvers = []awsConfigResolver{ // Sets the DisableRequestCompression if present in env var or shared config profile resolveDisableRequestCompression, + // Sets the DisableClockSkewCorrection if present in env var or shared config profile + resolveDisableClockSkewCorrection, // Sets the RequestMinCompressSizeBytes if present in env var or shared config profile resolveRequestMinCompressSizeBytes, diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go index f0619ce8548..886aec4c22b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go @@ -78,6 +78,8 @@ const ( awsDisableRequestCompressionEnv = "AWS_DISABLE_REQUEST_COMPRESSION" awsRequestMinCompressionSizeBytesEnv = "AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES" + awsDisableClockSkewCorrectionEnv = "AWS_DISABLE_CLOCK_SKEW_CORRECTION" + awsS3DisableExpressSessionAuthEnv = "AWS_S3_DISABLE_EXPRESS_SESSION_AUTH" awsAccountIDEnv = "AWS_ACCOUNT_ID" @@ -293,6 +295,10 @@ type EnvConfig struct { // retrieved from env var AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES RequestMinCompressSizeBytes *int64 + // determine if clock skew correction is disabled, default to false + // retrieved from env var AWS_DISABLE_CLOCK_SKEW_CORRECTION + DisableClockSkewCorrection *bool + // Whether S3Express auth is disabled. // // This will NOT prevent requests from being made to S3Express buckets, it @@ -364,6 +370,9 @@ func NewEnvConfig() (EnvConfig, error) { if err := setInt64PtrFromEnvVal(&cfg.RequestMinCompressSizeBytes, []string{awsRequestMinCompressionSizeBytesEnv}, smithyrequestcompression.MaxRequestMinCompressSizeBytes); err != nil { return cfg, err } + if err := setBoolPtrFromEnvVal(&cfg.DisableClockSkewCorrection, []string{awsDisableClockSkewCorrectionEnv}); err != nil { + return cfg, err + } if err := setEndpointDiscoveryTypeFromEnvVal(&cfg.EnableEndpointDiscovery, []string{awsEnableEndpointDiscoveryEnv}); err != nil { return cfg, err @@ -453,6 +462,13 @@ func (c EnvConfig) getDisableRequestCompression(context.Context) (bool, bool, er return *c.DisableRequestCompression, true, nil } +func (c EnvConfig) getDisableClockSkewCorrection(context.Context) (bool, bool, error) { + if c.DisableClockSkewCorrection == nil { + return false, false, nil + } + return *c.DisableClockSkewCorrection, true, nil +} + func (c EnvConfig) getRequestMinCompressSizeBytes(context.Context) (int64, bool, error) { if c.RequestMinCompressSizeBytes == nil { return 0, false, nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go index c92c427c550..c5d3716904b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go @@ -3,4 +3,4 @@ package config // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.32.26" +const goModuleVersion = "1.33.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go b/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go index 843ea6b7d7f..b7b3d8b2050 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go @@ -214,6 +214,9 @@ type LoadOptions struct { // The inclusive min bytes of a request body that could be compressed RequestMinCompressSizeBytes *int64 + // Specifies whether SDK clock skew correction is disabled + DisableClockSkewCorrection *bool + // Whether S3 Express auth is disabled. S3DisableExpressAuth *bool @@ -299,6 +302,14 @@ func (o LoadOptions) getDisableRequestCompression(ctx context.Context) (bool, bo return *o.DisableRequestCompression, true, nil } +// getDisableClockSkewCorrection returns DisableClockSkewCorrection from config's LoadOptions +func (o LoadOptions) getDisableClockSkewCorrection(ctx context.Context) (bool, bool, error) { + if o.DisableClockSkewCorrection == nil { + return false, false, nil + } + return *o.DisableClockSkewCorrection, true, nil +} + // getRequestMinCompressSizeBytes returns RequestMinCompressSizeBytes from config's LoadOptions func (o LoadOptions) getRequestMinCompressSizeBytes(ctx context.Context) (int64, bool, error) { if o.RequestMinCompressSizeBytes == nil { @@ -369,6 +380,18 @@ func WithDisableRequestCompression(DisableRequestCompression *bool) LoadOptionsF } } +// WithDisableClockSkewCorrection is a helper function to construct functional +// options that sets DisableClockSkewCorrection on config's LoadOptions. +func WithDisableClockSkewCorrection(DisableClockSkewCorrection *bool) LoadOptionsFunc { + return func(o *LoadOptions) error { + if DisableClockSkewCorrection == nil { + return nil + } + o.DisableClockSkewCorrection = DisableClockSkewCorrection + return nil + } +} + // WithRequestMinCompressSizeBytes is a helper function to construct functional options // that sets RequestMinCompressSizeBytes on config's LoadOptions. func WithRequestMinCompressSizeBytes(RequestMinCompressSizeBytes *int64) LoadOptionsFunc { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go index deabd29c82c..ae298afb60d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go @@ -208,6 +208,23 @@ func getDisableRequestCompression(ctx context.Context, configs configs) (value b return } +// disableClockSkewCorrectionProvider provides access to the DisableClockSkewCorrection +type disableClockSkewCorrectionProvider interface { + getDisableClockSkewCorrection(context.Context) (bool, bool, error) +} + +func getDisableClockSkewCorrection(ctx context.Context, configs configs) (value bool, found bool, err error) { + for _, cfg := range configs { + if p, ok := cfg.(disableClockSkewCorrectionProvider); ok { + value, found, err = p.getDisableClockSkewCorrection(ctx) + if err != nil || found { + break + } + } + } + return +} + // requestMinCompressSizeBytesProvider provides access to the MinCompressSizeBytes type requestMinCompressSizeBytesProvider interface { getRequestMinCompressSizeBytes(context.Context) (int64, bool, error) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go index b6796fc87e4..a2c56dc625b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go @@ -151,6 +151,18 @@ func resolveDisableRequestCompression(ctx context.Context, cfg *aws.Config, conf return nil } +// resolveDisableClockSkewCorrection extracts the DisableClockSkewCorrection from +// the configs slice's SharedConfig or EnvConfig +func resolveDisableClockSkewCorrection(ctx context.Context, cfg *aws.Config, configs configs) error { + disable, _, err := getDisableClockSkewCorrection(ctx, configs) + if err != nil { + return err + } + + cfg.DisableClockSkewCorrection = disable + return nil +} + // resolveRequestMinCompressSizeBytes extracts the RequestMinCompressSizeBytes from the configs slice's // SharedConfig or EnvConfig func resolveRequestMinCompressSizeBytes(ctx context.Context, cfg *aws.Config, configs configs) error { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go index 5b251f54f57..40b6daf3cfb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go @@ -113,6 +113,8 @@ const ( disableRequestCompression = "disable_request_compression" requestMinCompressionSizeBytes = "request_min_compression_size_bytes" + disableClockSkewCorrection = "disable_clock_skew_correction" + s3DisableExpressSessionAuthKey = "s3_disable_express_session_auth" accountIDKey = "aws_account_id" @@ -346,6 +348,10 @@ type SharedConfig struct { // retrieved from config file's profile field request_min_compression_size_bytes RequestMinCompressSizeBytes *int64 + // determine if clock skew correction is disabled, default to false + // retrieved from config file's profile field disable_clock_skew_correction + DisableClockSkewCorrection *bool + // Whether S3Express auth is disabled. // // This will NOT prevent requests from being made to S3Express buckets, it @@ -1149,6 +1155,9 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er if err := updateDisableRequestCompression(&c.DisableRequestCompression, section, disableRequestCompression); err != nil { return fmt.Errorf("failed to load %s from shared config, %w", disableRequestCompression, err) } + if err := updateDisableRequestCompression(&c.DisableClockSkewCorrection, section, disableClockSkewCorrection); err != nil { + return fmt.Errorf("failed to load %s from shared config, %w", disableClockSkewCorrection, err) + } if err := updateRequestMinCompressSizeBytes(&c.RequestMinCompressSizeBytes, section, requestMinCompressionSizeBytes); err != nil { return fmt.Errorf("failed to load %s from shared config, %w", requestMinCompressionSizeBytes, err) } @@ -1292,6 +1301,13 @@ func (c SharedConfig) getDisableRequestCompression(ctx context.Context) (bool, b return *c.DisableRequestCompression, true, nil } +func (c SharedConfig) getDisableClockSkewCorrection(ctx context.Context) (bool, bool, error) { + if c.DisableClockSkewCorrection == nil { + return false, false, nil + } + return *c.DisableClockSkewCorrection, true, nil +} + func (c SharedConfig) getAccountIDEndpointMode(ctx context.Context) (aws.AccountIDEndpointMode, bool, error) { return c.AccountIDEndpointMode, len(c.AccountIDEndpointMode) > 0, nil } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md index c348b8e13f4..b808f6702ed 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md @@ -1,3 +1,75 @@ +# v1.20.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.39 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.38 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.37 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.36 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.35 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.34 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.33 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.19.32 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.31 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.30 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.29 (2026-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.28 (2026-07-08.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.27 (2026-07-06) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.26 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.19.25 (2026-06-29) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go index dc291c97cd7..429e3261e50 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go @@ -104,8 +104,6 @@ func (c *Client) GetCredentials(ctx context.Context, params *GetCredentialsInput addProtocolFinalizerMiddlewares(stack, options, "GetCredentials") retry.AddRetryMiddlewares(stack, retry.AddRetryMiddlewaresOptions{Retryer: options.Retryer}) middleware.AddSDKAgentKey(middleware.FeatureMetadata, ServiceID) - smithyhttp.AddErrorCloseResponseBodyMiddleware(stack) - smithyhttp.AddCloseResponseBodyMiddleware(stack) for _, fn := range options.APIOptions { if err := fn(stack); err != nil { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go index f2820d20eac..ba985890525 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go @@ -82,12 +82,18 @@ func (d *deserializeOpGetCredential) HandleDeserialize(ctx context.Context, in s out smithymiddleware.DeserializeOutput, metadata smithymiddleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) + + // Close the response body on every exit path in place of the standalone close middleware. + // Deferred in a closure so it observes the final err (this output is not a streaming + // payload, so it is always closed regardless). + response, _ := out.RawResponse.(*smithyhttp.Response) + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + if err != nil { return out, metadata, err } - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { + if response == nil { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go index 084ac978f96..d167a84fd4f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go @@ -3,4 +3,4 @@ package credentials // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.19.25" +const goModuleVersion = "1.20.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md index a2f7103a97d..3e192f6743c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md @@ -1,3 +1,62 @@ +# v1.19.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.40 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.39 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.38 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.37 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.36 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.35 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.34 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.18.33 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.32 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.31 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.30 (2026-07-01) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.18.29 (2026-06-08) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go index 64d469b041d..686dcb3aa1a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go @@ -3,4 +3,4 @@ package imds // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.18.29" +const goModuleVersion = "1.19.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md index 26f507f8b12..ba684a6ad6d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md @@ -1,3 +1,62 @@ +# v1.5.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.40 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.39 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.38 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.37 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.36 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.35 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.34 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.4.33 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.32 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.31 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.30 (2026-07-01) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.4.29 (2026-06-08) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go index 851fed2b3ee..31a8cc2936c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go @@ -3,4 +3,4 @@ package configsources // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.4.29" +const goModuleVersion = "1.5.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md index 508593b45a8..8c19c30d7a5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md @@ -1,3 +1,62 @@ +# v2.8.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.8.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.40 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.39 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.38 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.37 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.36 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.35 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.34 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v2.7.33 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.32 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.31 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.30 (2026-07-01) + +* **Dependency Update**: Updated to the latest SDK module versions + # v2.7.29 (2026-06-08) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go index 1c161a0a732..d87fcef1d2e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go @@ -3,4 +3,4 @@ package endpoints // goModuleVersion is the tagged release for this module -const goModuleVersion = "2.7.29" +const goModuleVersion = "2.8.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/awsinternal.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/awsinternal.go new file mode 100644 index 00000000000..7967f709130 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/awsinternal.go @@ -0,0 +1,6 @@ +package timeouts + +// Enabled internally. +var enableReadTimeout2026 = false + +var readTimeout2026Rollout map[string]bool diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/timeouts.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/timeouts.go new file mode 100644 index 00000000000..626f29c9255 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/timeouts.go @@ -0,0 +1,39 @@ +package timeouts + +import ( + "os" + "sync" + "time" +) + +// DefaultReadTimeout is the SDK's default read timeout for a service with no +// entry in serviceInactivityTimeoutMillis. +const DefaultReadTimeout = 5 * time.Minute + +const enableReadTimeoutEnvVar = "AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026" + +var enableFromEnv = sync.OnceValue(func() bool { + return os.Getenv(enableReadTimeoutEnvVar) == "true" +}) + +// GetServiceReadTimeout reports the SDK's default read timeout for a service, +// and whether one applies. +func GetServiceReadTimeout(serviceID string) (time.Duration, bool) { + if enableReadTimeout2026 { + if !readTimeout2026Rollout[serviceID] { + return 0, false + } + } else if !enableFromEnv() { + return 0, false + } + + ms, ok := serviceInactivityTimeoutMillis[serviceID] + if !ok { + return DefaultReadTimeout, true + } + if ms < 0 { + return 0, false + } + + return time.Duration(ms) * time.Millisecond, true +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/timeouts_services.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/timeouts_services.go new file mode 100644 index 00000000000..216a5895aad --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeouts/timeouts_services.go @@ -0,0 +1,102 @@ +// Code generated from the connection read timeout risk mitigation +// document's exemption table. DO NOT EDIT. + +package timeouts + +// serviceInactivityTimeoutMillis overrides the default read timeout for +// services whose operations legitimately hold a connection open, keyed by +// ServiceID. A negative value means the service is fully exempt and gets no +// timeout. +// +// Services absent from this map get DefaultReadTimeout. +var serviceInactivityTimeoutMillis = map[string]int64{ + // Fully exempt: an operation takes an event stream or a streaming blob as + // input. The caller controls how long the request takes, and no response + // arrives until it finishes, so a read timeout would fire on the duration of + // the caller's own upload rather than on a network problem. + "Bedrock Runtime": -1, + "CloudSearch Domain": -1, + "ConnectHealth": -1, + "EBS": -1, + "Glacier": -1, + "Lambda": -1, + "Lex Runtime Service": -1, + "Lex Runtime V2": -1, + "MediaStore Data": -1, + "Omics": -1, + "Polly": -1, + "QBusiness": -1, + "S3": -1, + "SageMaker Runtime HTTP2": -1, + "Transcribe Streaming": -1, + "codeartifact": -1, + + // Long-hold operations: a higher ceiling rather than no ceiling. + "API Gateway": 900000, + "ApiGatewayV2": 900000, + "AppIntegrations": 900000, + "AppStream": 900000, + "Athena": 900000, + "Auto Scaling": 900000, + "Batch": 900000, + "Bedrock": 900000, + "Bedrock Agent": 900000, + "Bedrock Agent Runtime": 900000, + "Bedrock AgentCore": 900000, + "Bedrock AgentCore Control": 900000, + "Bedrock Data Automation Runtime": 900000, + "CloudFormation": 900000, + "CloudWatch": 900000, + "CodeBuild": 900000, + "CodeCatalyst": 900000, + "CodeDeploy": 900000, + "Config Service": 900000, + "Connect": 900000, + "Data Pipeline": 900000, + "DataBrew": 900000, + "DataExchange": 900000, + "DataZone": 900000, + "Device Farm": 900000, + "EC2": 900000, + "ECS": 900000, + "EMR Serverless": 900000, + "Elastic Load Balancing v2": 900000, + "GameLift": 900000, + "GameLiftStreams": 900000, + "Glue": 900000, + "IoT": 900000, + "IoT Data Plane": 900000, + "IoT Jobs Data Plane": 900000, + "IoTSecureTunneling": 900000, + "Kinesis": 900000, + "Kinesis Analytics V2": 900000, + "Kinesis Video Archived Media": 900000, + "Kinesis Video Media": 900000, + "Kinesis Video Signaling": 900000, + "Kinesis Video WebRTC Storage": 900000, + "Lex Model Building Service": 900000, + "Lex Models V2": 900000, + "Neptune Graph": 900000, + "Nova Act": 900000, + "QApps": 900000, + "QConnect": 900000, + "QuickSight": 900000, + "RDS": 900000, + "RDS Data": 900000, + "RTBFabric": 900000, + "SFN": 900000, + "SQS": 900000, + "SSM": 900000, + "SWF": 900000, + "SageMaker": 900000, + "SageMaker Runtime": 900000, + "SagemakerJobRuntime": 900000, + "Storage Gateway": 900000, + "Timestream Query": 900000, + "Wisdom": 900000, + "WorkSpaces": 900000, + "WorkSpaces Web": 900000, + "b2bi": 900000, + "mgn": 900000, + "neptunedata": 900000, +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md index 554f43b5e67..d96fd25629b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/CHANGELOG.md @@ -1,3 +1,62 @@ +# v1.5.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.41 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.40 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.39 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.38 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.37 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.36 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.35 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.4.34 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.33 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.32 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.31 (2026-07-01) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.4.30 (2026-06-08) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go index 2703ec797e3..a259d6e38c4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/v4a/go_module_metadata.go @@ -3,4 +3,4 @@ package v4a // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.4.30" +const goModuleVersion = "1.5.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/CHANGELOG.md index 01a8aa106a4..cbf633391ee 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/CHANGELOG.md @@ -1,3 +1,81 @@ +# v1.65.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.65.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.64.0 (2026-08-26) + +* **Feature**: Stop registering the `ComputeContentLength` middleware in generated clients. `Content-Length` is now set when the request body is set via `SetStream`. +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.63.5 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.63.4 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.63.3 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.63.2 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.63.1 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.63.0 (2026-08-04) + +* **Feature**: Vector indexes are a type of index in Amazon DynamoDB that enable similarity search on vector embedding stored in your table items. Vector indexes use approximate nearest neighbor search to find items whose vectors are most similar to a query vector that you provide. + +# v1.62.3 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.62.2 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.62.1 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.62.0 (2026-07-24) + +* **Feature**: Endpoint test standardizations + +# v1.61.0 (2026-07-21) + +* **Feature**: Add an option to clients to disable clock skew +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.60.1 (2026-07-13) + +* No change notes available for this release. + +# v1.60.0 (2026-07-06) + +* **Feature**: Add request serialization snapshot tests. + +# v1.59.2 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.59.1 (2026-06-29) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_client.go index cc9ce6c2b48..0b2aa0e692f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_client.go @@ -16,6 +16,7 @@ import ( internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/timeouts" ddbcust "github.com/aws/aws-sdk-go-v2/service/dynamodb/internal/customizations" acceptencodingcust "github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" @@ -277,6 +278,10 @@ func (c *Client) invokeOperation( finalizeClientEndpointResolverOptions(&options) + ctx = setLoggerContext(ctx, options, opID) + + ctx = resolveServiceMetadata(ctx, options, opID) + if err := c.addCommonMiddlewares(stack, options, opID); err != nil { return nil, metadata, err } @@ -393,9 +398,6 @@ func (c *Client) addCommonMiddlewares(stack *middleware.Stack, options Options, if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { return fmt.Errorf("add protocol finalizers: %v", err) } - if err := addSetLoggerMiddleware(stack, options); err != nil { - return err - } if err := addClientRequestID(stack); err != nil { return err } @@ -448,30 +450,6 @@ func resolveAuthSchemes(options *Options) { type noSmithyDocumentSerde = smithydocument.NoSerde -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -479,8 +457,9 @@ func resolveDefaultLogger(o *Options) { o.Logger = logging.Nop{} } -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) +func setLoggerContext(ctx context.Context, options Options, operation string) context.Context { + _ = operation + return middleware.SetLogger(ctx, options.Logger) } func setResolvedDefaultsMode(o *Options) { @@ -501,17 +480,18 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - AccountIDEndpointMode: cfg.AccountIDEndpointMode, - AuthSchemePreference: cfg.AuthSchemePreference, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + DisableClockSkewCorrection: cfg.DisableClockSkewCorrection, + AccountIDEndpointMode: cfg.AccountIDEndpointMode, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -560,6 +540,12 @@ func resolveHTTPClient(o *Options) { }) } + if _, ok := buildable.GetReadTimeout(); !ok { + if timeout, ok := timeouts.GetServiceReadTimeout(ServiceID); ok { + buildable = buildable.WithReadTimeout(timeout) + } + } + o.HTTPClient = buildable } @@ -711,16 +697,14 @@ func addClientRequestID(stack *middleware.Stack) error { return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) } -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Insert(&smithyhttp.ComputeContentLength{}, "ClientRequestID", middleware.After) -} - func addRawResponseToMetadata(stack *middleware.Stack) error { return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) } -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +func addRecordResponseTiming(stack *middleware.Stack, options Options) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{ + DisableClockSkewCorrection: options.DisableClockSkewCorrection, + }, middleware.After) } func addSpanRetryLoop(stack *middleware.Stack, options Options) error { @@ -798,6 +782,7 @@ func addRetry(stack *middleware.Stack, o Options, c *Client) error { m.LogAttempts = o.ClientLogMode.IsRetries() m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/dynamodb") m.ClientSkew = c.timeOffset + m.DisableClockSkewCorrection = o.DisableClockSkewCorrection }) if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { return err @@ -1035,12 +1020,16 @@ type IdempotencyTokenProvider interface { GetIdempotencyToken() (string, error) } -func newServiceMetadataMiddleware(region, operation string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: operation, +func resolveServiceMetadata(ctx context.Context, options Options, operation string) context.Context { + ctx = awsmiddleware.SetServiceID(ctx, ServiceID) + if options.Region != "" { + ctx = awsmiddleware.SetRegion(ctx, options.Region) + } + ctx = awsmiddleware.SetOperationName(ctx, operation) + if options.EndpointResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) } + return ctx } func addRecursionDetection(stack *middleware.Stack) error { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchExecuteStatement.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchExecuteStatement.go index 82201b4843b..be42bf37b99 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchExecuteStatement.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchExecuteStatement.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // This operation allows you to perform batch reads or writes on data stored in @@ -92,25 +91,13 @@ func (c *Client) addOperationBatchExecuteStatementMiddlewares(stack *middleware. return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -122,9 +109,6 @@ func (c *Client) addOperationBatchExecuteStatementMiddlewares(stack *middleware. if err = addOpBatchExecuteStatementValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "BatchExecuteStatement"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchGetItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchGetItem.go index 70da9d78910..17ccb2878dc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchGetItem.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchGetItem.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The BatchGetItem operation returns the attributes of one or more items from one @@ -240,25 +239,13 @@ func (c *Client) addOperationBatchGetItemMiddlewares(stack *middleware.Stack, op return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpBatchGetItemDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -273,9 +260,6 @@ func (c *Client) addOperationBatchGetItemMiddlewares(stack *middleware.Stack, op if err = addOpBatchGetItemValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "BatchGetItem"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchWriteItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchWriteItem.go index 5d843b37e10..49e537121d7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchWriteItem.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_BatchWriteItem.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The BatchWriteItem operation puts or deletes multiple items in one or more @@ -32,12 +31,12 @@ import ( // iteration would check for unprocessed items and submit a new BatchWriteItem // request with those unprocessed items until all items have been processed. // -// For tables and indexes with provisioned capacity, if none of the items can be -// processed due to insufficient provisioned throughput on all of the tables in the -// request, then BatchWriteItem returns a ProvisionedThroughputExceededException . -// For all tables and indexes, if none of the items can be processed due to other -// throttling scenarios (such as exceeding partition level limits), then -// BatchWriteItem returns a ThrottlingException . +// If BatchWriteItem cannot process any items due to throttling (for example, +// insufficient provisioned throughput on the tables in the request, or +// partition-level or account-level limits), it returns a +// ProvisionedThroughputExceededException or a ThrottlingException . Both indicate +// that the request was throttled; check the ThrottlingReason field in the +// returned exception for details. // // If DynamoDB returns any unprocessed items, you should retry the batch operation // on those items. However, we strongly recommend that you use an exponential @@ -191,6 +190,9 @@ type BatchWriteItemOutput struct { // - TableName - The table that consumed the provisioned throughput. // // - CapacityUnits - The total number of capacity units consumed. + // + // If the table has vector indexes, each element also includes a VectorIndexes + // field with VectorWriteRequestBytes consumed for each affected vector index. ConsumedCapacity []types.ConsumedCapacity // A list of tables that were processed by BatchWriteItem and, for each table, @@ -260,25 +262,13 @@ func (c *Client) addOperationBatchWriteItemMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpBatchWriteItemDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -293,9 +283,6 @@ func (c *Client) addOperationBatchWriteItemMiddlewares(stack *middleware.Stack, if err = addOpBatchWriteItemValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "BatchWriteItem"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateBackup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateBackup.go index 886a252620a..d538e09ec65 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateBackup.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateBackup.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates a backup for an existing table. @@ -99,25 +98,13 @@ func (c *Client) addOperationCreateBackupMiddlewares(stack *middleware.Stack, op return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpCreateBackupDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -132,9 +119,6 @@ func (c *Client) addOperationCreateBackupMiddlewares(stack *middleware.Stack, op if err = addOpCreateBackupValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "CreateBackup"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateGlobalTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateGlobalTable.go index 4d51eb7a489..0c2bcb2c3ea 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateGlobalTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateGlobalTable.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates a global table from an existing table. A global table creates a @@ -121,25 +120,13 @@ func (c *Client) addOperationCreateGlobalTableMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpCreateGlobalTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -154,9 +141,6 @@ func (c *Client) addOperationCreateGlobalTableMiddlewares(stack *middleware.Stac if err = addOpCreateGlobalTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "CreateGlobalTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateTable.go index 294ee44a245..afb400ac0d7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_CreateTable.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The CreateTable operation adds a new table to your account. In an Amazon Web @@ -259,6 +258,31 @@ type CreateTableInput struct { // [Tagging for DynamoDB]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html Tags []types.Tag + // One or more vector indexes to be created on the table. Each vector index + // enables similarity search on a vector attribute. Each element in the list + // consists of: + // + // - IndexName - The name of the vector index. Must be unique within the table. + // + // - VectorAttribute - The attribute that contains vector embeddings. If multiple + // vector indexes reference the same attribute, they must all use the same number + // of dimensions. + // + // - Dimensions - The number of dimensions in each vector. + // + // - DistanceFunction - The distance function used to calculate similarity. Valid + // values: COSINE , EUCLIDEAN , DOT_PRODUCT . + // + // - Projection - Specifies attributes that are copied (projected) from the table + // into the vector index. The total number of projected non-key attributes is + // shared across the vector attribute (counts as 1) and INLINE_FILTER search + // schema elements (each counts as 1). HASH search schema elements do not count + // toward this limit. + // + // - SearchSchema - (Optional) Defines the partition key ( HASH ) and inline + // filter ( INLINE_FILTER ) attributes for the vector index. + VectorIndexes []types.VectorIndex + // Represents the warm throughput (in read units per second and write units per // second) for creating a table. WarmThroughput *types.WarmThroughput @@ -294,25 +318,13 @@ func (c *Client) addOperationCreateTableMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpCreateTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -327,9 +339,6 @@ func (c *Client) addOperationCreateTableMiddlewares(stack *middleware.Stack, opt if err = addOpCreateTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "CreateTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteBackup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteBackup.go index 62b602a4c39..07b5fee8bbd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteBackup.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteBackup.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes an existing backup of a table. @@ -66,25 +65,13 @@ func (c *Client) addOperationDeleteBackupMiddlewares(stack *middleware.Stack, op return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDeleteBackupDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -99,9 +86,6 @@ func (c *Client) addOperationDeleteBackupMiddlewares(stack *middleware.Stack, op if err = addOpDeleteBackupValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DeleteBackup"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteItem.go index abaff832288..4d75bc2c447 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteItem.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteItem.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes a single item in a table by primary key. You can perform a conditional @@ -222,6 +221,9 @@ type DeleteItemOutput struct { // returned if the ReturnConsumedCapacity parameter was specified. For more // information, see [Provisioned capacity mode]in the Amazon DynamoDB Developer Guide. // + // If the table has vector indexes, the response includes a VectorIndexes field + // with VectorWriteRequestBytes consumed for each affected vector index. + // // [Provisioned capacity mode]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/provisioned-capacity-mode.html ConsumedCapacity *types.ConsumedCapacity @@ -262,25 +264,13 @@ func (c *Client) addOperationDeleteItemMiddlewares(stack *middleware.Stack, opti return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDeleteItemDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -295,9 +285,6 @@ func (c *Client) addOperationDeleteItemMiddlewares(stack *middleware.Stack, opti if err = addOpDeleteItemValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DeleteItem"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteResourcePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteResourcePolicy.go index 55afbefa5d0..a9305d40ca6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteResourcePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteResourcePolicy.go @@ -7,7 +7,6 @@ import ( "fmt" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Deletes the resource-based policy attached to the resource, which can be a @@ -93,25 +92,13 @@ func (c *Client) addOperationDeleteResourcePolicyMiddlewares(stack *middleware.S return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDeleteResourcePolicyDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -126,9 +113,6 @@ func (c *Client) addOperationDeleteResourcePolicyMiddlewares(stack *middleware.S if err = addOpDeleteResourcePolicyValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DeleteResourcePolicy"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteTable.go index fc50927bafc..f0020a6b9c0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DeleteTable.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The DeleteTable operation deletes a table and all of its items. After a @@ -87,25 +86,13 @@ func (c *Client) addOperationDeleteTableMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDeleteTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -120,9 +107,6 @@ func (c *Client) addOperationDeleteTableMiddlewares(stack *middleware.Stack, opt if err = addOpDeleteTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DeleteTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeBackup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeBackup.go index 58ce7629776..35b8fbaaa4c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeBackup.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeBackup.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Describes an existing backup of a table. @@ -66,25 +65,13 @@ func (c *Client) addOperationDescribeBackupMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeBackupDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -99,9 +86,6 @@ func (c *Client) addOperationDescribeBackupMiddlewares(stack *middleware.Stack, if err = addOpDescribeBackupValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeBackup"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContinuousBackups.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContinuousBackups.go index ee0968ff409..07fc5bebde3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContinuousBackups.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContinuousBackups.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Checks the status of continuous backups and point in time recovery on the @@ -82,25 +81,13 @@ func (c *Client) addOperationDescribeContinuousBackupsMiddlewares(stack *middlew return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeContinuousBackupsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -115,9 +102,6 @@ func (c *Client) addOperationDescribeContinuousBackupsMiddlewares(stack *middlew if err = addOpDescribeContinuousBackupsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeContinuousBackups"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContributorInsights.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContributorInsights.go index 1a6730b8643..fc62b136053 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContributorInsights.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeContributorInsights.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" smithywaiter "github.com/aws/smithy-go/waiter" "time" ) @@ -106,25 +105,13 @@ func (c *Client) addOperationDescribeContributorInsightsMiddlewares(stack *middl return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -136,9 +123,6 @@ func (c *Client) addOperationDescribeContributorInsightsMiddlewares(stack *middl if err = addOpDescribeContributorInsightsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeContributorInsights"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeEndpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeEndpoints.go index e21bf097452..e838918f965 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeEndpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeEndpoints.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the regional endpoint information. For more information on policy @@ -55,25 +54,13 @@ func (c *Client) addOperationDescribeEndpointsMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -82,9 +69,6 @@ func (c *Client) addOperationDescribeEndpointsMiddlewares(stack *middleware.Stac if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeEndpoints"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeExport.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeExport.go index 9e749e7ebe5..54f0ad67a8b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeExport.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeExport.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" smithywaiter "github.com/aws/smithy-go/waiter" "time" ) @@ -66,25 +65,13 @@ func (c *Client) addOperationDescribeExportMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -96,9 +83,6 @@ func (c *Client) addOperationDescribeExportMiddlewares(stack *middleware.Stack, if err = addOpDescribeExportValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeExport"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTable.go index c4fbb63b6e5..30d21c791d4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTable.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns information about the specified global table. @@ -76,25 +75,13 @@ func (c *Client) addOperationDescribeGlobalTableMiddlewares(stack *middleware.St return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeGlobalTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -109,9 +96,6 @@ func (c *Client) addOperationDescribeGlobalTableMiddlewares(stack *middleware.St if err = addOpDescribeGlobalTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeGlobalTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTableSettings.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTableSettings.go index 9b7d5a81cfd..c62a871511e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTableSettings.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeGlobalTableSettings.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Describes Region-specific settings for a global table. @@ -79,25 +78,13 @@ func (c *Client) addOperationDescribeGlobalTableSettingsMiddlewares(stack *middl return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeGlobalTableSettingsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -112,9 +99,6 @@ func (c *Client) addOperationDescribeGlobalTableSettingsMiddlewares(stack *middl if err = addOpDescribeGlobalTableSettingsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeGlobalTableSettings"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeImport.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeImport.go index a15716b31a8..709abdc08fe 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeImport.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeImport.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" smithywaiter "github.com/aws/smithy-go/waiter" "time" ) @@ -70,25 +69,13 @@ func (c *Client) addOperationDescribeImportMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -100,9 +87,6 @@ func (c *Client) addOperationDescribeImportMiddlewares(stack *middleware.Stack, if err = addOpDescribeImportValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeImport"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeKinesisStreamingDestination.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeKinesisStreamingDestination.go index 0da887082c0..e747c45b0c4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeKinesisStreamingDestination.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeKinesisStreamingDestination.go @@ -9,7 +9,6 @@ import ( internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" smithywaiter "github.com/aws/smithy-go/waiter" "strconv" "time" @@ -72,25 +71,13 @@ func (c *Client) addOperationDescribeKinesisStreamingDestinationMiddlewares(stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeKinesisStreamingDestinationDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -105,9 +92,6 @@ func (c *Client) addOperationDescribeKinesisStreamingDestinationMiddlewares(stac if err = addOpDescribeKinesisStreamingDestinationValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeKinesisStreamingDestination"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeLimits.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeLimits.go index aa4f9a27b72..ba32dfb2c67 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeLimits.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeLimits.go @@ -7,7 +7,6 @@ import ( "fmt" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the current provisioned-capacity quotas for your Amazon Web Services @@ -127,25 +126,13 @@ func (c *Client) addOperationDescribeLimitsMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeLimitsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -157,9 +144,6 @@ func (c *Client) addOperationDescribeLimitsMiddlewares(stack *middleware.Stack, if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeLimits"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTable.go index 266568b3794..1c98e3a1cdf 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTable.go @@ -10,7 +10,6 @@ import ( internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" smithywaiter "github.com/aws/smithy-go/waiter" "time" ) @@ -78,25 +77,13 @@ func (c *Client) addOperationDescribeTableMiddlewares(stack *middleware.Stack, o return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -111,9 +98,6 @@ func (c *Client) addOperationDescribeTableMiddlewares(stack *middleware.Stack, o if err = addOpDescribeTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTableReplicaAutoScaling.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTableReplicaAutoScaling.go index 7c550e29f0e..e64d302d41f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTableReplicaAutoScaling.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTableReplicaAutoScaling.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Describes auto scaling settings across replicas of the global table at once. @@ -63,25 +62,13 @@ func (c *Client) addOperationDescribeTableReplicaAutoScalingMiddlewares(stack *m return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -93,9 +80,6 @@ func (c *Client) addOperationDescribeTableReplicaAutoScalingMiddlewares(stack *m if err = addOpDescribeTableReplicaAutoScalingValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeTableReplicaAutoScaling"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTimeToLive.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTimeToLive.go index 53f7be7f8d7..1abe42cd1ea 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTimeToLive.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DescribeTimeToLive.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Gives a description of the Time to Live (TTL) status on the specified table. @@ -65,25 +64,13 @@ func (c *Client) addOperationDescribeTimeToLiveMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDescribeTimeToLiveDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -98,9 +85,6 @@ func (c *Client) addOperationDescribeTimeToLiveMiddlewares(stack *middleware.Sta if err = addOpDescribeTimeToLiveValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DescribeTimeToLive"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DisableKinesisStreamingDestination.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DisableKinesisStreamingDestination.go index 1378c96b2ec..062b4253ee0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DisableKinesisStreamingDestination.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_DisableKinesisStreamingDestination.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Stops replication from the DynamoDB table to the Kinesis data stream. This is @@ -83,25 +82,13 @@ func (c *Client) addOperationDisableKinesisStreamingDestinationMiddlewares(stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpDisableKinesisStreamingDestinationDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -116,9 +103,6 @@ func (c *Client) addOperationDisableKinesisStreamingDestinationMiddlewares(stack if err = addOpDisableKinesisStreamingDestinationValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DisableKinesisStreamingDestination"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_EnableKinesisStreamingDestination.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_EnableKinesisStreamingDestination.go index fd6d5903c75..a2e9d7234db 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_EnableKinesisStreamingDestination.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_EnableKinesisStreamingDestination.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Starts table data replication to the specified Kinesis data stream at a @@ -85,25 +84,13 @@ func (c *Client) addOperationEnableKinesisStreamingDestinationMiddlewares(stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpEnableKinesisStreamingDestinationDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -118,9 +105,6 @@ func (c *Client) addOperationEnableKinesisStreamingDestinationMiddlewares(stack if err = addOpEnableKinesisStreamingDestinationValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "EnableKinesisStreamingDestination"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteStatement.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteStatement.go index d33de5bf533..28bbe12f7af 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteStatement.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteStatement.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // This operation allows you to perform reads and singleton writes on data stored @@ -140,25 +139,13 @@ func (c *Client) addOperationExecuteStatementMiddlewares(stack *middleware.Stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -170,9 +157,6 @@ func (c *Client) addOperationExecuteStatementMiddlewares(stack *middleware.Stack if err = addOpExecuteStatementValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ExecuteStatement"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteTransaction.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteTransaction.go index af10ae61d46..e2930273e01 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteTransaction.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExecuteTransaction.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // This operation allows you to perform transactional reads or writes on data @@ -80,25 +79,13 @@ func (c *Client) addOperationExecuteTransactionMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -113,9 +100,6 @@ func (c *Client) addOperationExecuteTransactionMiddlewares(stack *middleware.Sta if err = addOpExecuteTransactionValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ExecuteTransaction"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExportTableToPointInTime.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExportTableToPointInTime.go index 81186948fd2..e5f46784f71 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExportTableToPointInTime.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ExportTableToPointInTime.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" "time" ) @@ -126,25 +125,13 @@ func (c *Client) addOperationExportTableToPointInTimeMiddlewares(stack *middlewa return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -159,9 +146,6 @@ func (c *Client) addOperationExportTableToPointInTimeMiddlewares(stack *middlewa if err = addOpExportTableToPointInTimeValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ExportTableToPointInTime"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetItem.go index 9d27e788a70..5305f0fdfa8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetItem.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetItem.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The GetItem operation returns a set of attributes for the item with the given @@ -172,25 +171,13 @@ func (c *Client) addOperationGetItemMiddlewares(stack *middleware.Stack, options return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpGetItemDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -205,9 +192,6 @@ func (c *Client) addOperationGetItemMiddlewares(stack *middleware.Stack, options if err = addOpGetItemValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetItem"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetResourcePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetResourcePolicy.go index 440b9db6b0e..06d718a854b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetResourcePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_GetResourcePolicy.go @@ -7,7 +7,6 @@ import ( "fmt" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the resource-based policy document attached to the resource, which can @@ -98,25 +97,13 @@ func (c *Client) addOperationGetResourcePolicyMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpGetResourcePolicyDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -131,9 +118,6 @@ func (c *Client) addOperationGetResourcePolicyMiddlewares(stack *middleware.Stac if err = addOpGetResourcePolicyValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetResourcePolicy"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ImportTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ImportTable.go index 1ec25bd027a..39b54e8ce4a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ImportTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ImportTable.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Imports table data from an S3 bucket. @@ -104,25 +103,13 @@ func (c *Client) addOperationImportTableMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -137,9 +124,6 @@ func (c *Client) addOperationImportTableMiddlewares(stack *middleware.Stack, opt if err = addOpImportTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ImportTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListBackups.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListBackups.go index 634a3909e33..b20b2d25ad1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListBackups.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListBackups.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" "time" ) @@ -121,25 +120,13 @@ func (c *Client) addOperationListBackupsMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpListBackupsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -151,9 +138,6 @@ func (c *Client) addOperationListBackupsMiddlewares(stack *middleware.Stack, opt if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListBackups"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListContributorInsights.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListContributorInsights.go index b4e0428465d..985552a3402 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListContributorInsights.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListContributorInsights.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a list of ContributorInsightsSummary for a table and all its global @@ -72,25 +71,13 @@ func (c *Client) addOperationListContributorInsightsMiddlewares(stack *middlewar return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -99,9 +86,6 @@ func (c *Client) addOperationListContributorInsightsMiddlewares(stack *middlewar if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListContributorInsights"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListExports.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListExports.go index 2f291560687..7f44f966eb2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListExports.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListExports.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Lists completed exports within the past 90 days, in reverse alphanumeric order @@ -74,25 +73,13 @@ func (c *Client) addOperationListExportsMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -101,9 +88,6 @@ func (c *Client) addOperationListExportsMiddlewares(stack *middleware.Stack, opt if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListExports"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListGlobalTables.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListGlobalTables.go index d715f7ba457..bc7a33f22ff 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListGlobalTables.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListGlobalTables.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Lists all global tables that have a replica in the specified Region. @@ -83,25 +82,13 @@ func (c *Client) addOperationListGlobalTablesMiddlewares(stack *middleware.Stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpListGlobalTablesDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -113,9 +100,6 @@ func (c *Client) addOperationListGlobalTablesMiddlewares(stack *middleware.Stack if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListGlobalTables"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListImports.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListImports.go index 5db278e1e26..82be1e25c75 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListImports.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListImports.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Lists completed imports within the past 90 days. @@ -73,25 +72,13 @@ func (c *Client) addOperationListImportsMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -100,9 +87,6 @@ func (c *Client) addOperationListImportsMiddlewares(stack *middleware.Stack, opt if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListImports"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTables.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTables.go index 6aaa40f2293..f861c4c6332 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTables.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTables.go @@ -7,7 +7,6 @@ import ( "fmt" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns an array of table names associated with the current account and @@ -78,25 +77,13 @@ func (c *Client) addOperationListTablesMiddlewares(stack *middleware.Stack, opti return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpListTablesDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -108,9 +95,6 @@ func (c *Client) addOperationListTablesMiddlewares(stack *middleware.Stack, opti if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListTables"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTagsOfResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTagsOfResource.go index 8168ae37ebc..b7f9541b1b6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTagsOfResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_ListTagsOfResource.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // List all tags on an Amazon DynamoDB resource. You can call ListTagsOfResource @@ -80,25 +79,13 @@ func (c *Client) addOperationListTagsOfResourceMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpListTagsOfResourceDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -113,9 +100,6 @@ func (c *Client) addOperationListTagsOfResourceMiddlewares(stack *middleware.Sta if err = addOpListTagsOfResourceValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListTagsOfResource"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutItem.go index 03ee5452a98..303668376c9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutItem.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutItem.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates a new item, or replaces an old item with a new item. If an item that @@ -74,6 +73,18 @@ type PutItemInput struct { // types for those attributes must match those of the schema in the table's // attribute definition. // + // If the table has vector indexes, the following validations apply to write + // operations. A violation of any of these constraints results in a + // ValidationException : + // + // - The vector attribute must be a list of numbers with dimensions matching the + // index configuration. + // + // - Vector values must fit in 32-bit IEEE-754 floating point format (f32). + // + // - Partition key and inline filter attributes defined in the search schema + // must have data types matching the index schema definition. + // // Empty String and Binary attribute values are allowed. Attribute values of type // String and Binary must have a length greater than zero if the attribute is used // as a key attribute for a table or index. @@ -259,6 +270,9 @@ type PutItemOutput struct { // returned if the ReturnConsumedCapacity parameter was specified. For more // information, see [Capacity unity consumption for write operations]in the Amazon DynamoDB Developer Guide. // + // If the table has vector indexes, the response includes a VectorIndexes field + // with VectorWriteRequestBytes consumed for each affected vector index. + // // [Capacity unity consumption for write operations]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/read-write-operations.html#write-operation-consumption ConsumedCapacity *types.ConsumedCapacity @@ -299,25 +313,13 @@ func (c *Client) addOperationPutItemMiddlewares(stack *middleware.Stack, options return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpPutItemDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -332,9 +334,6 @@ func (c *Client) addOperationPutItemMiddlewares(stack *middleware.Stack, options if err = addOpPutItemValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "PutItem"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutResourcePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutResourcePolicy.go index a77e8d9b1e9..e956831c209 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutResourcePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_PutResourcePolicy.go @@ -7,7 +7,6 @@ import ( "fmt" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Attaches a resource-based policy document to the resource, which can be a table @@ -122,25 +121,13 @@ func (c *Client) addOperationPutResourcePolicyMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpPutResourcePolicyDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -155,9 +142,6 @@ func (c *Client) addOperationPutResourcePolicyMiddlewares(stack *middleware.Stac if err = addOpPutResourcePolicyValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "PutResourcePolicy"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Query.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Query.go index a7dce4efc89..936f9e79df1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Query.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Query.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // You must provide the name of the partition key attribute and a single value for @@ -464,25 +463,13 @@ func (c *Client) addOperationQueryMiddlewares(stack *middleware.Stack, options O return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpQueryDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -497,9 +484,6 @@ func (c *Client) addOperationQueryMiddlewares(stack *middleware.Stack, options O if err = addOpQueryValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "Query"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableFromBackup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableFromBackup.go index 66b1258a610..e942867bbd6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableFromBackup.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableFromBackup.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates a new table from an existing backup. Any number of users can execute up @@ -80,6 +79,12 @@ type RestoreTableFromBackupInput struct { // The new server-side encryption settings for the restored table. SSESpecificationOverride *types.SSESpecification + // The vector indexes for the restored table. If not specified, all vector indexes + // from the backup are restored. The indexes provided must match existing vector + // indexes from the backup. You can choose to exclude some or all of the vector + // indexes at the time of restore. + VectorIndexOverride []types.VectorIndex + noSmithyDocumentSerde } @@ -110,25 +115,13 @@ func (c *Client) addOperationRestoreTableFromBackupMiddlewares(stack *middleware return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpRestoreTableFromBackupDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -143,9 +136,6 @@ func (c *Client) addOperationRestoreTableFromBackupMiddlewares(stack *middleware if err = addOpRestoreTableFromBackupValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "RestoreTableFromBackup"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableToPointInTime.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableToPointInTime.go index 263225c9381..01ff52a2d98 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableToPointInTime.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_RestoreTableToPointInTime.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" "time" ) @@ -80,6 +79,11 @@ type RestoreTableToPointInTimeInput struct { // List of global secondary indexes for the restored table. The indexes provided // should match existing secondary indexes. You can choose to exclude some or all // of the indexes at the time of restore. + // + // The WarmThroughput setting is not supported on global secondary indexes when + // you use RestoreTableToPointInTime . Although WarmThroughput appears in the + // shared index definition, including it in a GlobalSecondaryIndexOverride entry + // causes the request to fail with a validation error. GlobalSecondaryIndexOverride []types.GlobalSecondaryIndex // List of local secondary indexes for the restored table. The indexes provided @@ -112,6 +116,12 @@ type RestoreTableToPointInTimeInput struct { // typically 5 minutes before the current time. UseLatestRestorableTime *bool + // The vector indexes for the restored table. If not specified, all vector indexes + // from the source table are restored. The indexes provided must match existing + // vector indexes from the source table. You can choose to exclude some or all of + // the vector indexes at the time of restore. + VectorIndexOverride []types.VectorIndex + noSmithyDocumentSerde } @@ -142,25 +152,13 @@ func (c *Client) addOperationRestoreTableToPointInTimeMiddlewares(stack *middlew return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpRestoreTableToPointInTimeDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -175,9 +173,6 @@ func (c *Client) addOperationRestoreTableToPointInTimeMiddlewares(stack *middlew if err = addOpRestoreTableToPointInTimeValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "RestoreTableToPointInTime"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Scan.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Scan.go index 9d4b1805b7b..8cf89dcd0d4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Scan.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_Scan.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The Scan operation returns one or more items and item attributes by accessing @@ -395,25 +394,13 @@ func (c *Client) addOperationScanMiddlewares(stack *middleware.Stack, options Op return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpScanDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -428,9 +415,6 @@ func (c *Client) addOperationScanMiddlewares(stack *middleware.Stack, options Op if err = addOpScanValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "Scan"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_SearchVectors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_SearchVectors.go new file mode 100644 index 00000000000..61b1568c610 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_SearchVectors.go @@ -0,0 +1,184 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package dynamodb + +import ( + "context" + "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" +) + +// Performs a vector similarity search on a vector index associated with an Amazon +// DynamoDB table, and returns the most similar items sorted by similarity score +// based on the distance function configured for the index. +// +// Score interpretation depends on the distance function: +// +// - COSINE - Returns the items with the k smallest scores. Scores range from 0 +// (identical) to 2 (opposite). Lower scores indicate higher similarity. +// +// - EUCLIDEAN - Returns the items with the k smallest scores. Scores represent +// the Euclidean distance between vectors. Lower scores indicate higher similarity. +// +// - DOT_PRODUCT - Returns the items with the k highest scores. Higher scores +// indicate higher similarity. +func (c *Client) SearchVectors(ctx context.Context, params *SearchVectorsInput, optFns ...func(*Options)) (*SearchVectorsOutput, error) { + if params == nil { + params = &SearchVectorsInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "SearchVectors", params, optFns, c.addOperationSearchVectorsMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*SearchVectorsOutput) + out.ResultMetadata = metadata + return out, nil +} + +type SearchVectorsInput struct { + + // The name of the vector index to search. The index must be in the ACTIVE state. + // + // This member is required. + IndexName *string + + // The search vector to compare against the indexed vectors. Each element is a + // 32-bit IEEE-754 floating point number, provided in DynamoDB list format. + // + // The number of dimensions must match the number of dimensions configured for the + // vector index. + // + // This member is required. + SearchVector []types.AttributeValue + + // The name or Amazon Resource Name (ARN) of the table containing the vector index. + // + // This member is required. + TableName *string + + // The number of most similar results to return. + // + // This member is required. + TopK *int32 + + // One or more substitution tokens for attribute names in an expression. Use the # + // character in an expression to dereference an attribute name. + ExpressionAttributeNames map[string]string + + // One or more values that can be substituted in an expression. Use the : + // character in an expression to dereference an attribute value. + ExpressionAttributeValues map[string]types.AttributeValue + + // A string that identifies one or more attributes to retrieve from the index. + // Separate attribute names with commas. If not specified, the operation returns + // all attributes projected into the vector index. + // + // Only attributes projected into the vector index can be retrieved. + ProjectionExpression *string + + // Determines the level of detail about either provisioned or on-demand throughput + // consumption that is returned in the response: + // + // - INDEXES - The response includes the aggregate ConsumedCapacity for the + // operation, together with ConsumedCapacity for each table and secondary index + // that was accessed. + // + // Note that some operations, such as GetItem and BatchGetItem , do not access any + // indexes at all. In these cases, specifying INDEXES will only return + // ConsumedCapacity information for table(s). + // + // - TOTAL - The response includes only the aggregate ConsumedCapacity for the + // operation. + // + // - NONE - No ConsumedCapacity details are included in the response. + ReturnConsumedCapacity types.ReturnConsumedCapacity + + // A condition expression used to filter the vector search results. The expression + // can reference attributes defined in the vector index search schema, including + // HASH and INLINE_FILTER key elements. + // + // Only the equality operator ( = ) is supported for HASH attributes. Comparison + // and range operators are supported for INLINE_FILTER attributes. Only top-level + // attributes from the search schema can be referenced. + SearchConditionExpression *string + + noSmithyDocumentSerde +} + +func (in *SearchVectorsInput) bindEndpointParams(p *EndpointParameters) { + + p.ResourceArn = in.TableName + p.IsSearchOperation = ptr.Bool(true) +} + +type SearchVectorsOutput struct { + + // The capacity units consumed by the SearchVectors operation. Contains + // VectorSearchRequestBytes , which represents the vector search capacity consumed. + ConsumedCapacity *types.VectorCapacity + + // A list of items returned by the vector similarity search, sorted by similarity + // with the most similar item first. Each item contains the projected attributes + // and a similarity score. + SearchResults []types.SearchResultItem + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationSearchVectorsMiddlewares(stack *middleware.Stack, options Options) (err error) { + err = stack.Serialize.Add(&awsAwsjson10_serializeOpSearchVectors{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsjson10_deserializeOpSearchVectors{}, middleware.After) + if err != nil { + return err + } + + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack, options); err != nil { + return err + } + if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpSearchVectorsValidationMiddleware(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addValidateResponseChecksum(stack, options); err != nil { + return err + } + if err = addAcceptEncodingGzip(stack, options); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TagResource.go index 21c620e2223..9ea0433846d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TagResource.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Associate a set of tags with an Amazon DynamoDB resource. You can then activate @@ -85,25 +84,13 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpTagResourceDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -118,9 +105,6 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "TagResource"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactGetItems.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactGetItems.go index a38cd39d6da..02cd3e0b5b0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactGetItems.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactGetItems.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // TransactGetItems is a synchronous operation that atomically retrieves multiple @@ -115,25 +114,13 @@ func (c *Client) addOperationTransactGetItemsMiddlewares(stack *middleware.Stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpTransactGetItemsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -148,9 +135,6 @@ func (c *Client) addOperationTransactGetItemsMiddlewares(stack *middleware.Stack if err = addOpTransactGetItemsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "TransactGetItems"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactWriteItems.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactWriteItems.go index 645f3c25c33..98e5e6b265a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactWriteItems.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_TransactWriteItems.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // TransactWriteItems is a synchronous write operation that groups up to 100 @@ -194,6 +193,9 @@ type TransactWriteItemsOutput struct { // The capacity units consumed by the entire TransactWriteItems operation. The // values of the list are ordered according to the ordering of the TransactItems // request parameter. + // + // If the table has vector indexes, each element also includes a VectorIndexes + // field with VectorWriteRequestBytes consumed for each affected vector index. ConsumedCapacity []types.ConsumedCapacity // A list of tables that were processed by TransactWriteItems and, for each table, @@ -217,25 +219,13 @@ func (c *Client) addOperationTransactWriteItemsMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpTransactWriteItemsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -253,9 +243,6 @@ func (c *Client) addOperationTransactWriteItemsMiddlewares(stack *middleware.Sta if err = addOpTransactWriteItemsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "TransactWriteItems"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UntagResource.go index 14e72c040fe..61e52687ad4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UntagResource.go @@ -7,7 +7,6 @@ import ( "fmt" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Removes the association of tags from an Amazon DynamoDB resource. You can call @@ -83,25 +82,13 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUntagResourceDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -116,9 +103,6 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UntagResource"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContinuousBackups.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContinuousBackups.go index 752380475c5..bef35500ac8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContinuousBackups.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContinuousBackups.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // UpdateContinuousBackups enables or disables point in time recovery for the @@ -83,25 +82,13 @@ func (c *Client) addOperationUpdateContinuousBackupsMiddlewares(stack *middlewar return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateContinuousBackupsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -116,9 +103,6 @@ func (c *Client) addOperationUpdateContinuousBackupsMiddlewares(stack *middlewar if err = addOpUpdateContinuousBackupsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateContinuousBackups"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContributorInsights.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContributorInsights.go index 1e3c0fe374e..ff8bcb8046b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContributorInsights.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateContributorInsights.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Updates the status for contributor insights for a specific table or index. @@ -92,25 +91,13 @@ func (c *Client) addOperationUpdateContributorInsightsMiddlewares(stack *middlew return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -122,9 +109,6 @@ func (c *Client) addOperationUpdateContributorInsightsMiddlewares(stack *middlew if err = addOpUpdateContributorInsightsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateContributorInsights"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTable.go index 7b445278f60..bf885caec77 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTable.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Adds or removes replicas in the specified global table. The global table must @@ -104,25 +103,13 @@ func (c *Client) addOperationUpdateGlobalTableMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateGlobalTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -137,9 +124,6 @@ func (c *Client) addOperationUpdateGlobalTableMiddlewares(stack *middleware.Stac if err = addOpUpdateGlobalTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateGlobalTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTableSettings.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTableSettings.go index 70dc9187772..89d35b5933d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTableSettings.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateGlobalTableSettings.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Updates settings for a global table. @@ -107,25 +106,13 @@ func (c *Client) addOperationUpdateGlobalTableSettingsMiddlewares(stack *middlew return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateGlobalTableSettingsDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -140,9 +127,6 @@ func (c *Client) addOperationUpdateGlobalTableSettingsMiddlewares(stack *middlew if err = addOpUpdateGlobalTableSettingsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateGlobalTableSettings"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateItem.go index 3d30a2c4ffc..aba232e0389 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateItem.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateItem.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Edits an existing item's attributes, or adds a new item to the table if it does @@ -306,6 +305,9 @@ type UpdateItemOutput struct { // returned if the ReturnConsumedCapacity parameter was specified. For more // information, see [Capacity unity consumption for write operations]in the Amazon DynamoDB Developer Guide. // + // If the table has vector indexes, the response includes a VectorIndexes field + // with VectorWriteRequestBytes consumed for each affected vector index. + // // [Capacity unity consumption for write operations]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/read-write-operations.html#write-operation-consumption ConsumedCapacity *types.ConsumedCapacity @@ -346,25 +348,13 @@ func (c *Client) addOperationUpdateItemMiddlewares(stack *middleware.Stack, opti return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateItemDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -379,9 +369,6 @@ func (c *Client) addOperationUpdateItemMiddlewares(stack *middleware.Stack, opti if err = addOpUpdateItemValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateItem"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateKinesisStreamingDestination.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateKinesisStreamingDestination.go index 0dafb8e9607..eedb8bb9592 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateKinesisStreamingDestination.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateKinesisStreamingDestination.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The command to update the Kinesis stream destination. @@ -82,25 +81,13 @@ func (c *Client) addOperationUpdateKinesisStreamingDestinationMiddlewares(stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateKinesisStreamingDestinationDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -115,9 +102,6 @@ func (c *Client) addOperationUpdateKinesisStreamingDestinationMiddlewares(stack if err = addOpUpdateKinesisStreamingDestinationValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateKinesisStreamingDestination"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTable.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTable.go index 3f7b4f6c691..04ae779f3e3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTable.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTable.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Modifies the provisioned throughput settings, global secondary indexes, or @@ -170,6 +169,14 @@ type UpdateTableInput struct { // STANDARD_INFREQUENT_ACCESS . TableClass types.TableClass + // A list of vector indexes to be added to or removed from the table. You can add + // or remove one vector index for each UpdateTable operation. + // + // To add a vector index, specify IndexName , VectorAttribute , Dimensions , + // DistanceFunction , and Projection . To remove a vector index, specify only the + // IndexName . + VectorIndexUpdates []types.VectorIndexUpdate + // Represents the warm throughput (in read units per second and write units per // second) for updating a table. WarmThroughput *types.WarmThroughput @@ -205,25 +212,13 @@ func (c *Client) addOperationUpdateTableMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateTableDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -238,9 +233,6 @@ func (c *Client) addOperationUpdateTableMiddlewares(stack *middleware.Stack, opt if err = addOpUpdateTableValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateTable"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTableReplicaAutoScaling.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTableReplicaAutoScaling.go index b5170fad1d1..8eb215f120a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTableReplicaAutoScaling.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTableReplicaAutoScaling.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Updates auto scaling settings on your global tables at once. @@ -75,25 +74,13 @@ func (c *Client) addOperationUpdateTableReplicaAutoScalingMiddlewares(stack *mid return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addUserAgentAccountIDEndpointMode(stack, options); err != nil { @@ -105,9 +92,6 @@ func (c *Client) addOperationUpdateTableReplicaAutoScalingMiddlewares(stack *mid if err = addOpUpdateTableReplicaAutoScalingValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateTableReplicaAutoScaling"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTimeToLive.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTimeToLive.go index 09b6eec480d..41834f0ecaa 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTimeToLive.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/api_op_UpdateTimeToLive.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" internalEndpointDiscovery "github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // The UpdateTimeToLive method enables or disables Time to Live (TTL) for the @@ -100,25 +99,13 @@ func (c *Client) addOperationUpdateTimeToLiveMiddlewares(stack *middleware.Stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addOpUpdateTimeToLiveDiscoverEndpointMiddleware(stack, options, c); err != nil { @@ -133,9 +120,6 @@ func (c *Client) addOperationUpdateTimeToLiveMiddlewares(stack *middleware.Stack if err = addOpUpdateTimeToLiveValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "UpdateTimeToLive"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/deserializers.go index 9574e794057..db5cd2e7fea 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/deserializers.go @@ -37,15 +37,18 @@ func (m *awsAwsjson10_deserializeOpBatchExecuteStatement) HandleDeserialize(ctx return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorBatchExecuteStatement(response, &metadata) } @@ -154,15 +157,18 @@ func (m *awsAwsjson10_deserializeOpBatchGetItem) HandleDeserialize(ctx context.C return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorBatchGetItem(response, &metadata) } @@ -280,15 +286,18 @@ func (m *awsAwsjson10_deserializeOpBatchWriteItem) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorBatchWriteItem(response, &metadata) } @@ -412,15 +421,18 @@ func (m *awsAwsjson10_deserializeOpCreateBackup) HandleDeserialize(ctx context.C return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorCreateBackup(response, &metadata) } @@ -541,15 +553,18 @@ func (m *awsAwsjson10_deserializeOpCreateGlobalTable) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorCreateGlobalTable(response, &metadata) } @@ -664,15 +679,18 @@ func (m *awsAwsjson10_deserializeOpCreateTable) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorCreateTable(response, &metadata) } @@ -784,15 +802,18 @@ func (m *awsAwsjson10_deserializeOpDeleteBackup) HandleDeserialize(ctx context.C return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDeleteBackup(response, &metadata) } @@ -907,15 +928,18 @@ func (m *awsAwsjson10_deserializeOpDeleteItem) HandleDeserialize(ctx context.Con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDeleteItem(response, &metadata) } @@ -1045,15 +1069,18 @@ func (m *awsAwsjson10_deserializeOpDeleteResourcePolicy) HandleDeserialize(ctx c return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDeleteResourcePolicy(response, &metadata) } @@ -1171,15 +1198,18 @@ func (m *awsAwsjson10_deserializeOpDeleteTable) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDeleteTable(response, &metadata) } @@ -1294,15 +1324,18 @@ func (m *awsAwsjson10_deserializeOpDescribeBackup) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeBackup(response, &metadata) } @@ -1411,15 +1444,18 @@ func (m *awsAwsjson10_deserializeOpDescribeContinuousBackups) HandleDeserialize( return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeContinuousBackups(response, &metadata) } @@ -1528,15 +1564,18 @@ func (m *awsAwsjson10_deserializeOpDescribeContributorInsights) HandleDeserializ return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeContributorInsights(response, &metadata) } @@ -1642,15 +1681,18 @@ func (m *awsAwsjson10_deserializeOpDescribeEndpoints) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeEndpoints(response, &metadata) } @@ -1750,15 +1792,18 @@ func (m *awsAwsjson10_deserializeOpDescribeExport) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeExport(response, &metadata) } @@ -1867,15 +1912,18 @@ func (m *awsAwsjson10_deserializeOpDescribeGlobalTable) HandleDeserialize(ctx co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeGlobalTable(response, &metadata) } @@ -1984,15 +2032,18 @@ func (m *awsAwsjson10_deserializeOpDescribeGlobalTableSettings) HandleDeserializ return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeGlobalTableSettings(response, &metadata) } @@ -2101,15 +2152,18 @@ func (m *awsAwsjson10_deserializeOpDescribeImport) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeImport(response, &metadata) } @@ -2212,15 +2266,18 @@ func (m *awsAwsjson10_deserializeOpDescribeKinesisStreamingDestination) HandleDe return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeKinesisStreamingDestination(response, &metadata) } @@ -2329,15 +2386,18 @@ func (m *awsAwsjson10_deserializeOpDescribeLimits) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeLimits(response, &metadata) } @@ -2443,15 +2503,18 @@ func (m *awsAwsjson10_deserializeOpDescribeTable) HandleDeserialize(ctx context. return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeTable(response, &metadata) } @@ -2560,15 +2623,18 @@ func (m *awsAwsjson10_deserializeOpDescribeTableReplicaAutoScaling) HandleDeseri return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeTableReplicaAutoScaling(response, &metadata) } @@ -2674,15 +2740,18 @@ func (m *awsAwsjson10_deserializeOpDescribeTimeToLive) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDescribeTimeToLive(response, &metadata) } @@ -2791,15 +2860,18 @@ func (m *awsAwsjson10_deserializeOpDisableKinesisStreamingDestination) HandleDes return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorDisableKinesisStreamingDestination(response, &metadata) } @@ -2914,15 +2986,18 @@ func (m *awsAwsjson10_deserializeOpEnableKinesisStreamingDestination) HandleDese return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorEnableKinesisStreamingDestination(response, &metadata) } @@ -3037,17 +3112,20 @@ func (m *awsAwsjson10_deserializeOpExecuteStatement) HandleDeserialize(ctx conte return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson10_deserializeOpErrorExecuteStatement(response, &metadata) + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsjson10_deserializeOpErrorExecuteStatement(response, &metadata) } output := &ExecuteStatementOutput{} out.Result = output @@ -3172,15 +3250,18 @@ func (m *awsAwsjson10_deserializeOpExecuteTransaction) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorExecuteTransaction(response, &metadata) } @@ -3304,15 +3385,18 @@ func (m *awsAwsjson10_deserializeOpExportTableToPointInTime) HandleDeserialize(c return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorExportTableToPointInTime(response, &metadata) } @@ -3430,15 +3514,18 @@ func (m *awsAwsjson10_deserializeOpGetItem) HandleDeserialize(ctx context.Contex return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorGetItem(response, &metadata) } @@ -3556,15 +3643,18 @@ func (m *awsAwsjson10_deserializeOpGetResourcePolicy) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorGetResourcePolicy(response, &metadata) } @@ -3676,15 +3766,18 @@ func (m *awsAwsjson10_deserializeOpImportTable) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorImportTable(response, &metadata) } @@ -3793,15 +3886,18 @@ func (m *awsAwsjson10_deserializeOpListBackups) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListBackups(response, &metadata) } @@ -3907,15 +4003,18 @@ func (m *awsAwsjson10_deserializeOpListContributorInsights) HandleDeserialize(ct return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListContributorInsights(response, &metadata) } @@ -4021,15 +4120,18 @@ func (m *awsAwsjson10_deserializeOpListExports) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListExports(response, &metadata) } @@ -4135,15 +4237,18 @@ func (m *awsAwsjson10_deserializeOpListGlobalTables) HandleDeserialize(ctx conte return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListGlobalTables(response, &metadata) } @@ -4249,15 +4354,18 @@ func (m *awsAwsjson10_deserializeOpListImports) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListImports(response, &metadata) } @@ -4360,15 +4468,18 @@ func (m *awsAwsjson10_deserializeOpListTables) HandleDeserialize(ctx context.Con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListTables(response, &metadata) } @@ -4474,15 +4585,18 @@ func (m *awsAwsjson10_deserializeOpListTagsOfResource) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorListTagsOfResource(response, &metadata) } @@ -4591,15 +4705,18 @@ func (m *awsAwsjson10_deserializeOpPutItem) HandleDeserialize(ctx context.Contex return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorPutItem(response, &metadata) } @@ -4729,15 +4846,18 @@ func (m *awsAwsjson10_deserializeOpPutResourcePolicy) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorPutResourcePolicy(response, &metadata) } @@ -4855,15 +4975,18 @@ func (m *awsAwsjson10_deserializeOpQuery) HandleDeserialize(ctx context.Context, return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorQuery(response, &metadata) } @@ -4981,15 +5104,18 @@ func (m *awsAwsjson10_deserializeOpRestoreTableFromBackup) HandleDeserialize(ctx return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorRestoreTableFromBackup(response, &metadata) } @@ -5110,15 +5236,18 @@ func (m *awsAwsjson10_deserializeOpRestoreTableToPointInTime) HandleDeserialize( return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorRestoreTableToPointInTime(response, &metadata) } @@ -5242,15 +5371,18 @@ func (m *awsAwsjson10_deserializeOpScan) HandleDeserialize(ctx context.Context, return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorScan(response, &metadata) } @@ -5353,14 +5485,14 @@ func awsAwsjson10_deserializeOpErrorScan(response *smithyhttp.Response, metadata } } -type awsAwsjson10_deserializeOpTagResource struct { +type awsAwsjson10_deserializeOpSearchVectors struct { } -func (*awsAwsjson10_deserializeOpTagResource) ID() string { +func (*awsAwsjson10_deserializeOpSearchVectors) ID() string { return "OperationDeserializer" } -func (m *awsAwsjson10_deserializeOpTagResource) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( +func (m *awsAwsjson10_deserializeOpSearchVectors) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) @@ -5368,31 +5500,56 @@ func (m *awsAwsjson10_deserializeOpTagResource) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson10_deserializeOpErrorTagResource(response, &metadata) + return out, metadata, awsAwsjson10_deserializeOpErrorSearchVectors(response, &metadata) } - output := &TagResourceOutput{} + output := &SearchVectorsOutput{} out.Result = output - if _, err = io.Copy(io.Discard, response.Body); err != nil { - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to discard response body, %w", err), + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(response.Body, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + err = awsAwsjson10_deserializeOpDocumentSearchVectorsOutput(&output, shape) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), } + return out, metadata, err } return out, metadata, err } -func awsAwsjson10_deserializeOpErrorTagResource(response *smithyhttp.Response, metadata *middleware.Metadata) error { +func awsAwsjson10_deserializeOpErrorSearchVectors(response *smithyhttp.Response, metadata *middleware.Metadata) error { var errorBuffer bytes.Buffer if _, err := io.Copy(&errorBuffer, response.Body); err != nil { return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} @@ -5432,18 +5589,15 @@ func awsAwsjson10_deserializeOpErrorTagResource(response *smithyhttp.Response, m case strings.EqualFold("InternalServerError", errorCode): return awsAwsjson10_deserializeErrorInternalServerError(response, errorBody) - case strings.EqualFold("InvalidEndpointException", errorCode): - return awsAwsjson10_deserializeErrorInvalidEndpointException(response, errorBody) - - case strings.EqualFold("LimitExceededException", errorCode): - return awsAwsjson10_deserializeErrorLimitExceededException(response, errorBody) - - case strings.EqualFold("ResourceInUseException", errorCode): - return awsAwsjson10_deserializeErrorResourceInUseException(response, errorBody) + case strings.EqualFold("RequestLimitExceeded", errorCode): + return awsAwsjson10_deserializeErrorRequestLimitExceeded(response, errorBody) case strings.EqualFold("ResourceNotFoundException", errorCode): return awsAwsjson10_deserializeErrorResourceNotFoundException(response, errorBody) + case strings.EqualFold("ThrottlingException", errorCode): + return awsAwsjson10_deserializeErrorThrottlingException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -5454,14 +5608,14 @@ func awsAwsjson10_deserializeOpErrorTagResource(response *smithyhttp.Response, m } } -type awsAwsjson10_deserializeOpTransactGetItems struct { +type awsAwsjson10_deserializeOpTagResource struct { } -func (*awsAwsjson10_deserializeOpTransactGetItems) ID() string { +func (*awsAwsjson10_deserializeOpTagResource) ID() string { return "OperationDeserializer" } -func (m *awsAwsjson10_deserializeOpTransactGetItems) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( +func (m *awsAwsjson10_deserializeOpTagResource) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) @@ -5469,17 +5623,124 @@ func (m *awsAwsjson10_deserializeOpTransactGetItems) HandleDeserialize(ctx conte return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson10_deserializeOpErrorTransactGetItems(response, &metadata) + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsjson10_deserializeOpErrorTagResource(response, &metadata) + } + output := &TagResourceOutput{} + out.Result = output + + if _, err = io.Copy(io.Discard, response.Body); err != nil { + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to discard response body, %w", err), + } + } + + return out, metadata, err +} + +func awsAwsjson10_deserializeOpErrorTagResource(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + bodyInfo, err := getProtocolErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) + } + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message + } + switch { + case strings.EqualFold("InternalServerError", errorCode): + return awsAwsjson10_deserializeErrorInternalServerError(response, errorBody) + + case strings.EqualFold("InvalidEndpointException", errorCode): + return awsAwsjson10_deserializeErrorInvalidEndpointException(response, errorBody) + + case strings.EqualFold("LimitExceededException", errorCode): + return awsAwsjson10_deserializeErrorLimitExceededException(response, errorBody) + + case strings.EqualFold("ResourceInUseException", errorCode): + return awsAwsjson10_deserializeErrorResourceInUseException(response, errorBody) + + case strings.EqualFold("ResourceNotFoundException", errorCode): + return awsAwsjson10_deserializeErrorResourceNotFoundException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + +type awsAwsjson10_deserializeOpTransactGetItems struct { +} + +func (*awsAwsjson10_deserializeOpTransactGetItems) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsjson10_deserializeOpTransactGetItems) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsjson10_deserializeOpErrorTransactGetItems(response, &metadata) } output := &TransactGetItemsOutput{} out.Result = output @@ -5598,15 +5859,18 @@ func (m *awsAwsjson10_deserializeOpTransactWriteItems) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorTransactWriteItems(response, &metadata) } @@ -5733,15 +5997,18 @@ func (m *awsAwsjson10_deserializeOpUntagResource) HandleDeserialize(ctx context. return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUntagResource(response, &metadata) } @@ -5834,15 +6101,18 @@ func (m *awsAwsjson10_deserializeOpUpdateContinuousBackups) HandleDeserialize(ct return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateContinuousBackups(response, &metadata) } @@ -5954,15 +6224,18 @@ func (m *awsAwsjson10_deserializeOpUpdateContributorInsights) HandleDeserialize( return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateContributorInsights(response, &metadata) } @@ -6068,15 +6341,18 @@ func (m *awsAwsjson10_deserializeOpUpdateGlobalTable) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateGlobalTable(response, &metadata) } @@ -6194,15 +6470,18 @@ func (m *awsAwsjson10_deserializeOpUpdateGlobalTableSettings) HandleDeserialize( return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateGlobalTableSettings(response, &metadata) } @@ -6323,15 +6602,18 @@ func (m *awsAwsjson10_deserializeOpUpdateItem) HandleDeserialize(ctx context.Con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateItem(response, &metadata) } @@ -6461,15 +6743,18 @@ func (m *awsAwsjson10_deserializeOpUpdateKinesisStreamingDestination) HandleDese return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateKinesisStreamingDestination(response, &metadata) } @@ -6584,15 +6869,18 @@ func (m *awsAwsjson10_deserializeOpUpdateTable) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateTable(response, &metadata) } @@ -6707,15 +6995,18 @@ func (m *awsAwsjson10_deserializeOpUpdateTableReplicaAutoScaling) HandleDeserial return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateTableReplicaAutoScaling(response, &metadata) } @@ -6827,15 +7118,18 @@ func (m *awsAwsjson10_deserializeOpUpdateTimeToLive) HandleDeserialize(ctx conte return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsjson10_deserializeOpErrorUpdateTimeToLive(response, &metadata) } @@ -9865,6 +10159,11 @@ func awsAwsjson10_deserializeDocumentConsumedCapacity(v **types.ConsumedCapacity sv.TableName = ptr.String(jtv) } + case "VectorIndexes": + if err := awsAwsjson10_deserializeDocumentVectorIndexesCapacityMap(&sv.VectorIndexes, value); err != nil { + return err + } + case "WriteCapacityUnits": if value != nil { switch jtv := value.(type) { @@ -15334,7 +15633,7 @@ func awsAwsjson10_deserializeDocumentS3BucketSource(v **types.S3BucketSource, va return nil } -func awsAwsjson10_deserializeDocumentSecondaryIndexesCapacityMap(v *map[string]types.Capacity, value interface{}) error { +func awsAwsjson10_deserializeDocumentSearchResultItem(v **types.SearchResultItem, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -15347,31 +15646,218 @@ func awsAwsjson10_deserializeDocumentSecondaryIndexesCapacityMap(v *map[string]t return fmt.Errorf("unexpected JSON type %v", value) } - var mv map[string]types.Capacity + var sv *types.SearchResultItem if *v == nil { - mv = map[string]types.Capacity{} + sv = &types.SearchResultItem{} } else { - mv = *v + sv = *v } for key, value := range shape { - var parsedVal types.Capacity - mapVar := parsedVal - destAddr := &mapVar - if err := awsAwsjson10_deserializeDocumentCapacity(&destAddr, value); err != nil { - return err - } - parsedVal = *destAddr - mv[key] = parsedVal + switch key { + case "Item": + if err := awsAwsjson10_deserializeDocumentAttributeMap(&sv.Item, value); err != nil { + return err + } - } - *v = mv - return nil -} + case "Score": + if value != nil { + switch jtv := value.(type) { + case json.Number: + f64, err := jtv.Float64() + if err != nil { + return err + } + sv.Score = f64 -func awsAwsjson10_deserializeDocumentSourceTableDetails(v **types.SourceTableDetails, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) + case string: + var f64 float64 + switch { + case strings.EqualFold(jtv, "NaN"): + f64 = math.NaN() + + case strings.EqualFold(jtv, "Infinity"): + f64 = math.Inf(1) + + case strings.EqualFold(jtv, "-Infinity"): + f64 = math.Inf(-1) + + default: + return fmt.Errorf("unknown JSON number value: %s", jtv) + + } + sv.Score = f64 + + default: + return fmt.Errorf("expected ScoreNumber to be a JSON Number, got %T instead", value) + + } + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentSearchResultList(v *[]types.SearchResultItem, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.([]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var cv []types.SearchResultItem + if *v == nil { + cv = []types.SearchResultItem{} + } else { + cv = *v + } + + for _, value := range shape { + var col types.SearchResultItem + destAddr := &col + if err := awsAwsjson10_deserializeDocumentSearchResultItem(&destAddr, value); err != nil { + return err + } + col = *destAddr + cv = append(cv, col) + + } + *v = cv + return nil +} + +func awsAwsjson10_deserializeDocumentSearchSchema(v *[]types.SearchSchemaElement, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.([]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var cv []types.SearchSchemaElement + if *v == nil { + cv = []types.SearchSchemaElement{} + } else { + cv = *v + } + + for _, value := range shape { + var col types.SearchSchemaElement + destAddr := &col + if err := awsAwsjson10_deserializeDocumentSearchSchemaElement(&destAddr, value); err != nil { + return err + } + col = *destAddr + cv = append(cv, col) + + } + *v = cv + return nil +} + +func awsAwsjson10_deserializeDocumentSearchSchemaElement(v **types.SearchSchemaElement, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.SearchSchemaElement + if *v == nil { + sv = &types.SearchSchemaElement{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "AttributeName": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected AttributeName to be of type string, got %T instead", value) + } + sv.AttributeName = ptr.String(jtv) + } + + case "SearchSchemaElementType": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected SearchSchemaElementType to be of type string, got %T instead", value) + } + sv.SearchSchemaElementType = types.SearchSchemaElementType(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentSecondaryIndexesCapacityMap(v *map[string]types.Capacity, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var mv map[string]types.Capacity + if *v == nil { + mv = map[string]types.Capacity{} + } else { + mv = *v + } + + for key, value := range shape { + var parsedVal types.Capacity + mapVar := parsedVal + destAddr := &mapVar + if err := awsAwsjson10_deserializeDocumentCapacity(&destAddr, value); err != nil { + return err + } + parsedVal = *destAddr + mv[key] = parsedVal + + } + *v = mv + return nil +} + +func awsAwsjson10_deserializeDocumentSourceTableDetails(v **types.SourceTableDetails, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) } if value == nil { return nil @@ -15540,6 +16026,11 @@ func awsAwsjson10_deserializeDocumentSourceTableFeatureDetails(v **types.SourceT return err } + case "VectorIndexes": + if err := awsAwsjson10_deserializeDocumentVectorIndexes(&sv.VectorIndexes, value); err != nil { + return err + } + default: _, _ = key, value @@ -15986,6 +16477,11 @@ func awsAwsjson10_deserializeDocumentTableCreationParameters(v **types.TableCrea sv.TableName = ptr.String(jtv) } + case "VectorIndexes": + if err := awsAwsjson10_deserializeDocumentVectorIndexList(&sv.VectorIndexes, value); err != nil { + return err + } + default: _, _ = key, value @@ -16219,6 +16715,11 @@ func awsAwsjson10_deserializeDocumentTableDescription(v **types.TableDescription sv.TableStatus = types.TableStatus(jtv) } + case "VectorIndexes": + if err := awsAwsjson10_deserializeDocumentVectorIndexDescriptionList(&sv.VectorIndexes, value); err != nil { + return err + } + case "WarmThroughput": if err := awsAwsjson10_deserializeDocumentTableWarmThroughputDescription(&sv.WarmThroughput, value); err != nil { return err @@ -16574,13 +17075,656 @@ func awsAwsjson10_deserializeDocumentThrottlingReason(v **types.ThrottlingReason sv.Reason = ptr.String(jtv) } - case "resource": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Resource to be of type string, got %T instead", value) - } - sv.Resource = ptr.String(jtv) + case "resource": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected Resource to be of type string, got %T instead", value) + } + sv.Resource = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentThrottlingReasonList(v *[]types.ThrottlingReason, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.([]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var cv []types.ThrottlingReason + if *v == nil { + cv = []types.ThrottlingReason{} + } else { + cv = *v + } + + for _, value := range shape { + var col types.ThrottlingReason + destAddr := &col + if err := awsAwsjson10_deserializeDocumentThrottlingReason(&destAddr, value); err != nil { + return err + } + col = *destAddr + cv = append(cv, col) + + } + *v = cv + return nil +} + +func awsAwsjson10_deserializeDocumentTimeToLiveDescription(v **types.TimeToLiveDescription, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.TimeToLiveDescription + if *v == nil { + sv = &types.TimeToLiveDescription{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "AttributeName": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TimeToLiveAttributeName to be of type string, got %T instead", value) + } + sv.AttributeName = ptr.String(jtv) + } + + case "TimeToLiveStatus": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TimeToLiveStatus to be of type string, got %T instead", value) + } + sv.TimeToLiveStatus = types.TimeToLiveStatus(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentTimeToLiveSpecification(v **types.TimeToLiveSpecification, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.TimeToLiveSpecification + if *v == nil { + sv = &types.TimeToLiveSpecification{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "AttributeName": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TimeToLiveAttributeName to be of type string, got %T instead", value) + } + sv.AttributeName = ptr.String(jtv) + } + + case "Enabled": + if value != nil { + jtv, ok := value.(bool) + if !ok { + return fmt.Errorf("expected TimeToLiveEnabled to be of type *bool, got %T instead", value) + } + sv.Enabled = ptr.Bool(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentTransactionCanceledException(v **types.TransactionCanceledException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.TransactionCanceledException + if *v == nil { + sv = &types.TransactionCanceledException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "CancellationReasons": + if err := awsAwsjson10_deserializeDocumentCancellationReasonList(&sv.CancellationReasons, value); err != nil { + return err + } + + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ErrorMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentTransactionConflictException(v **types.TransactionConflictException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.TransactionConflictException + if *v == nil { + sv = &types.TransactionConflictException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ErrorMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentTransactionInProgressException(v **types.TransactionInProgressException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.TransactionInProgressException + if *v == nil { + sv = &types.TransactionInProgressException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ErrorMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentUpdateKinesisStreamingConfiguration(v **types.UpdateKinesisStreamingConfiguration, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.UpdateKinesisStreamingConfiguration + if *v == nil { + sv = &types.UpdateKinesisStreamingConfiguration{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "ApproximateCreationDateTimePrecision": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ApproximateCreationDateTimePrecision to be of type string, got %T instead", value) + } + sv.ApproximateCreationDateTimePrecision = types.ApproximateCreationDateTimePrecision(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentVectorAttributeDefinition(v **types.VectorAttributeDefinition, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.VectorAttributeDefinition + if *v == nil { + sv = &types.VectorAttributeDefinition{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "AttributeName": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected VectorAttributeName to be of type string, got %T instead", value) + } + sv.AttributeName = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentVectorCapacity(v **types.VectorCapacity, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.VectorCapacity + if *v == nil { + sv = &types.VectorCapacity{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "VectorSearchRequestBytes": + if value != nil { + switch jtv := value.(type) { + case json.Number: + f64, err := jtv.Float64() + if err != nil { + return err + } + sv.VectorSearchRequestBytes = ptr.Float64(f64) + + case string: + var f64 float64 + switch { + case strings.EqualFold(jtv, "NaN"): + f64 = math.NaN() + + case strings.EqualFold(jtv, "Infinity"): + f64 = math.Inf(1) + + case strings.EqualFold(jtv, "-Infinity"): + f64 = math.Inf(-1) + + default: + return fmt.Errorf("unknown JSON number value: %s", jtv) + + } + sv.VectorSearchRequestBytes = ptr.Float64(f64) + + default: + return fmt.Errorf("expected ConsumedCapacityUnits to be a JSON Number, got %T instead", value) + + } + } + + case "VectorWriteRequestBytes": + if value != nil { + switch jtv := value.(type) { + case json.Number: + f64, err := jtv.Float64() + if err != nil { + return err + } + sv.VectorWriteRequestBytes = ptr.Float64(f64) + + case string: + var f64 float64 + switch { + case strings.EqualFold(jtv, "NaN"): + f64 = math.NaN() + + case strings.EqualFold(jtv, "Infinity"): + f64 = math.Inf(1) + + case strings.EqualFold(jtv, "-Infinity"): + f64 = math.Inf(-1) + + default: + return fmt.Errorf("unknown JSON number value: %s", jtv) + + } + sv.VectorWriteRequestBytes = ptr.Float64(f64) + + default: + return fmt.Errorf("expected ConsumedCapacityUnits to be a JSON Number, got %T instead", value) + + } + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentVectorIndex(v **types.VectorIndex, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.VectorIndex + if *v == nil { + sv = &types.VectorIndex{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "Dimensions": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected PositiveLongObject to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.Dimensions = ptr.Int64(i64) + } + + case "DistanceFunction": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected VectorDistanceFunction to be of type string, got %T instead", value) + } + sv.DistanceFunction = types.VectorDistanceFunction(jtv) + } + + case "IndexName": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected IndexName to be of type string, got %T instead", value) + } + sv.IndexName = ptr.String(jtv) + } + + case "Projection": + if err := awsAwsjson10_deserializeDocumentProjection(&sv.Projection, value); err != nil { + return err + } + + case "SearchSchema": + if err := awsAwsjson10_deserializeDocumentSearchSchema(&sv.SearchSchema, value); err != nil { + return err + } + + case "VectorAttribute": + if err := awsAwsjson10_deserializeDocumentVectorAttributeDefinition(&sv.VectorAttribute, value); err != nil { + return err + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson10_deserializeDocumentVectorIndexDescription(v **types.VectorIndexDescription, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.VectorIndexDescription + if *v == nil { + sv = &types.VectorIndexDescription{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "Backfilling": + if value != nil { + jtv, ok := value.(bool) + if !ok { + return fmt.Errorf("expected Backfilling to be of type *bool, got %T instead", value) + } + sv.Backfilling = ptr.Bool(jtv) + } + + case "Dimensions": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected PositiveLongObject to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.Dimensions = ptr.Int64(i64) + } + + case "DistanceFunction": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected VectorDistanceFunction to be of type string, got %T instead", value) + } + sv.DistanceFunction = types.VectorDistanceFunction(jtv) + } + + case "IndexArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.IndexArn = ptr.String(jtv) + } + + case "IndexName": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected IndexName to be of type string, got %T instead", value) + } + sv.IndexName = ptr.String(jtv) + } + + case "IndexSizeBytes": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected LongObject to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.IndexSizeBytes = ptr.Int64(i64) + } + + case "IndexStatus": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected IndexStatus to be of type string, got %T instead", value) + } + sv.IndexStatus = types.IndexStatus(jtv) + } + + case "ItemCount": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected LongObject to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.ItemCount = ptr.Int64(i64) + } + + case "Projection": + if err := awsAwsjson10_deserializeDocumentProjection(&sv.Projection, value); err != nil { + return err + } + + case "SearchSchema": + if err := awsAwsjson10_deserializeDocumentSearchSchema(&sv.SearchSchema, value); err != nil { + return err + } + + case "VectorAttribute": + if err := awsAwsjson10_deserializeDocumentVectorAttributeDefinition(&sv.VectorAttribute, value); err != nil { + return err } default: @@ -16592,7 +17736,7 @@ func awsAwsjson10_deserializeDocumentThrottlingReason(v **types.ThrottlingReason return nil } -func awsAwsjson10_deserializeDocumentThrottlingReasonList(v *[]types.ThrottlingReason, value interface{}) error { +func awsAwsjson10_deserializeDocumentVectorIndexDescriptionList(v *[]types.VectorIndexDescription, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -16605,17 +17749,17 @@ func awsAwsjson10_deserializeDocumentThrottlingReasonList(v *[]types.ThrottlingR return fmt.Errorf("unexpected JSON type %v", value) } - var cv []types.ThrottlingReason + var cv []types.VectorIndexDescription if *v == nil { - cv = []types.ThrottlingReason{} + cv = []types.VectorIndexDescription{} } else { cv = *v } for _, value := range shape { - var col types.ThrottlingReason + var col types.VectorIndexDescription destAddr := &col - if err := awsAwsjson10_deserializeDocumentThrottlingReason(&destAddr, value); err != nil { + if err := awsAwsjson10_deserializeDocumentVectorIndexDescription(&destAddr, value); err != nil { return err } col = *destAddr @@ -16626,7 +17770,7 @@ func awsAwsjson10_deserializeDocumentThrottlingReasonList(v *[]types.ThrottlingR return nil } -func awsAwsjson10_deserializeDocumentTimeToLiveDescription(v **types.TimeToLiveDescription, value interface{}) error { +func awsAwsjson10_deserializeDocumentVectorIndexes(v *[]types.VectorIndexInfo, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -16634,48 +17778,33 @@ func awsAwsjson10_deserializeDocumentTimeToLiveDescription(v **types.TimeToLiveD return nil } - shape, ok := value.(map[string]interface{}) + shape, ok := value.([]interface{}) if !ok { return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.TimeToLiveDescription + var cv []types.VectorIndexInfo if *v == nil { - sv = &types.TimeToLiveDescription{} + cv = []types.VectorIndexInfo{} } else { - sv = *v + cv = *v } - for key, value := range shape { - switch key { - case "AttributeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TimeToLiveAttributeName to be of type string, got %T instead", value) - } - sv.AttributeName = ptr.String(jtv) - } - - case "TimeToLiveStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TimeToLiveStatus to be of type string, got %T instead", value) - } - sv.TimeToLiveStatus = types.TimeToLiveStatus(jtv) - } - - default: - _, _ = key, value - + for _, value := range shape { + var col types.VectorIndexInfo + destAddr := &col + if err := awsAwsjson10_deserializeDocumentVectorIndexInfo(&destAddr, value); err != nil { + return err } + col = *destAddr + cv = append(cv, col) + } - *v = sv + *v = cv return nil } -func awsAwsjson10_deserializeDocumentTimeToLiveSpecification(v **types.TimeToLiveSpecification, value interface{}) error { +func awsAwsjson10_deserializeDocumentVectorIndexesCapacityMap(v *map[string]types.VectorCapacity, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -16688,43 +17817,29 @@ func awsAwsjson10_deserializeDocumentTimeToLiveSpecification(v **types.TimeToLiv return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.TimeToLiveSpecification + var mv map[string]types.VectorCapacity if *v == nil { - sv = &types.TimeToLiveSpecification{} + mv = map[string]types.VectorCapacity{} } else { - sv = *v + mv = *v } for key, value := range shape { - switch key { - case "AttributeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TimeToLiveAttributeName to be of type string, got %T instead", value) - } - sv.AttributeName = ptr.String(jtv) - } - - case "Enabled": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected TimeToLiveEnabled to be of type *bool, got %T instead", value) - } - sv.Enabled = ptr.Bool(jtv) - } - - default: - _, _ = key, value - + var parsedVal types.VectorCapacity + mapVar := parsedVal + destAddr := &mapVar + if err := awsAwsjson10_deserializeDocumentVectorCapacity(&destAddr, value); err != nil { + return err } + parsedVal = *destAddr + mv[key] = parsedVal + } - *v = sv + *v = mv return nil } -func awsAwsjson10_deserializeDocumentTransactionCanceledException(v **types.TransactionCanceledException, value interface{}) error { +func awsAwsjson10_deserializeDocumentVectorIndexInfo(v **types.VectorIndexInfo, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -16737,107 +17852,59 @@ func awsAwsjson10_deserializeDocumentTransactionCanceledException(v **types.Tran return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.TransactionCanceledException + var sv *types.VectorIndexInfo if *v == nil { - sv = &types.TransactionCanceledException{} + sv = &types.VectorIndexInfo{} } else { sv = *v } for key, value := range shape { switch key { - case "CancellationReasons": - if err := awsAwsjson10_deserializeDocumentCancellationReasonList(&sv.CancellationReasons, value); err != nil { - return err + case "Dimensions": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected PositiveLongObject to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.Dimensions = ptr.Int64(i64) } - case "message", "Message": + case "DistanceFunction": if value != nil { jtv, ok := value.(string) if !ok { - return fmt.Errorf("expected ErrorMessage to be of type string, got %T instead", value) + return fmt.Errorf("expected VectorDistanceFunction to be of type string, got %T instead", value) } - sv.Message = ptr.String(jtv) + sv.DistanceFunction = types.VectorDistanceFunction(jtv) } - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson10_deserializeDocumentTransactionConflictException(v **types.TransactionConflictException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TransactionConflictException - if *v == nil { - sv = &types.TransactionConflictException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message", "Message": + case "IndexName": if value != nil { jtv, ok := value.(string) if !ok { - return fmt.Errorf("expected ErrorMessage to be of type string, got %T instead", value) + return fmt.Errorf("expected IndexName to be of type string, got %T instead", value) } - sv.Message = ptr.String(jtv) + sv.IndexName = ptr.String(jtv) } - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson10_deserializeDocumentTransactionInProgressException(v **types.TransactionInProgressException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } + case "Projection": + if err := awsAwsjson10_deserializeDocumentProjection(&sv.Projection, value); err != nil { + return err + } - var sv *types.TransactionInProgressException - if *v == nil { - sv = &types.TransactionInProgressException{} - } else { - sv = *v - } + case "SearchSchema": + if err := awsAwsjson10_deserializeDocumentSearchSchema(&sv.SearchSchema, value); err != nil { + return err + } - for key, value := range shape { - switch key { - case "message", "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorMessage to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) + case "VectorAttribute": + if err := awsAwsjson10_deserializeDocumentVectorAttributeDefinition(&sv.VectorAttribute, value); err != nil { + return err } default: @@ -16849,7 +17916,7 @@ func awsAwsjson10_deserializeDocumentTransactionInProgressException(v **types.Tr return nil } -func awsAwsjson10_deserializeDocumentUpdateKinesisStreamingConfiguration(v **types.UpdateKinesisStreamingConfiguration, value interface{}) error { +func awsAwsjson10_deserializeDocumentVectorIndexList(v *[]types.VectorIndex, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -16857,35 +17924,29 @@ func awsAwsjson10_deserializeDocumentUpdateKinesisStreamingConfiguration(v **typ return nil } - shape, ok := value.(map[string]interface{}) + shape, ok := value.([]interface{}) if !ok { return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.UpdateKinesisStreamingConfiguration + var cv []types.VectorIndex if *v == nil { - sv = &types.UpdateKinesisStreamingConfiguration{} + cv = []types.VectorIndex{} } else { - sv = *v + cv = *v } - for key, value := range shape { - switch key { - case "ApproximateCreationDateTimePrecision": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ApproximateCreationDateTimePrecision to be of type string, got %T instead", value) - } - sv.ApproximateCreationDateTimePrecision = types.ApproximateCreationDateTimePrecision(jtv) - } - - default: - _, _ = key, value - + for _, value := range shape { + var col types.VectorIndex + destAddr := &col + if err := awsAwsjson10_deserializeDocumentVectorIndex(&destAddr, value); err != nil { + return err } + col = *destAddr + cv = append(cv, col) + } - *v = sv + *v = cv return nil } @@ -19011,6 +20072,47 @@ func awsAwsjson10_deserializeOpDocumentScanOutput(v **ScanOutput, value interfac return nil } +func awsAwsjson10_deserializeOpDocumentSearchVectorsOutput(v **SearchVectorsOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *SearchVectorsOutput + if *v == nil { + sv = &SearchVectorsOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "ConsumedCapacity": + if err := awsAwsjson10_deserializeDocumentVectorCapacity(&sv.ConsumedCapacity, value); err != nil { + return err + } + + case "SearchResults": + if err := awsAwsjson10_deserializeDocumentSearchResultList(&sv.SearchResults, value); err != nil { + return err + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + func awsAwsjson10_deserializeOpDocumentTransactGetItemsOutput(v **TransactGetItemsOutput, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/endpoints.go index 4cf69274193..96da0657c65 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/endpoints.go @@ -296,6 +296,12 @@ type EndpointParameters struct { // // Parameter is required. ResourceArnList []string + + // Set to true for SearchVectors to route to the Search FQDN + // + // Parameter is + // required. + IsSearchOperation *bool } // ValidateRequired validates required parameters are set. @@ -326,11 +332,12 @@ func (p EndpointParameters) WithDefaults() EndpointParameters { const bddRoot int32 = 2 -var bddNodes = [201]int32{ - -1, 1, -1, 0, 5, 3, 1, 4, 100000025, 2, 100000001, 65, 1, 63, 6, 2, 52, 7, 3, 8, 100000025, 4, 51, 9, 6, 30, 10, 9, 11, 100000011, 10, 13, 12, 26, 100000019, 100000011, 11, 29, 14, 12, 15, 20, 13, 16, 20, 14, 17, 20, 15, 18, 20, 16, 19, 20, 17, 100000022, 20, 18, 21, 27, 19, 22, 27, 20, 23, 27, 21, 24, 27, 22, 25, 27, 23, 26, 27, 24, 100000023, 27, 25, 28, 29, 27, 100000024, 100000017, 26, 100000018, 100000011, 7, 31, 100000021, 9, 32, 100000020, 10, 34, 33, 26, 100000019, 100000020, 11, 50, 35, 12, 36, 41, 13, 37, 41, 14, 38, 41, 15, 39, 41, 16, 40, 41, 17, 100000014, 41, 18, 42, 48, 19, 43, 48, 20, 44, 48, 21, 45, 48, 22, 46, 48, 23, 47, 48, 24, 100000015, 48, 25, 49, 50, 27, 100000016, 100000017, 26, 100000018, 100000020, 6, 100000006, 100000007, 3, 53, 100000025, 4, 100000005, 54, 5, 56, 55, 6, 100000010, 100000013, 6, 60, 57, 9, 58, 59, 26, 100000008, 59, 28, 100000011, 100000012, 7, 61, 100000010, 9, 62, 100000009, 26, 100000008, 100000009, 2, 100000001, 64, 3, 66, 65, 6, 100000002, 100000004, 6, 100000002, 67, 8, 100000003, 100000004} +var bddNodes = [246]int32{ + -1, 1, -1, 0, 6, 3, 1, 4, 100000035, 2, 100000001, 5, 3, 100000002, 100000004, 1, 77, 7, 2, 61, 8, 3, 34, 9, 4, 10, 100000035, 5, 100000007, 11, 11, 12, 69, 12, 14, 13, 28, 100000025, 69, 13, 33, 15, 14, 16, 21, 15, 17, 21, 16, 18, 21, 17, 19, 21, 18, 20, 21, 19, 32, 21, 20, 22, 28, 21, 23, 28, 22, 24, 28, 23, 25, 28, 24, 26, 28, 25, 27, 28, 26, 31, 28, 27, 29, 33, 29, 30, 100000023, 31, 100000033, 100000034, 31, 100000031, 100000032, 31, 100000029, 100000030, 28, 100000024, 69, 4, 35, 100000035, 5, 100000006, 36, 9, 37, 100000028, 11, 38, 60, 12, 40, 39, 28, 100000025, 60, 13, 59, 41, 14, 42, 47, 15, 43, 47, 16, 44, 47, 17, 45, 47, 18, 46, 47, 19, 58, 47, 20, 48, 54, 21, 49, 54, 22, 50, 54, 23, 51, 54, 24, 52, 54, 25, 53, 54, 26, 57, 54, 27, 55, 59, 29, 56, 100000023, 31, 100000021, 100000022, 31, 100000019, 100000020, 31, 100000017, 100000018, 28, 100000024, 60, 31, 100000026, 100000027, 3, 70, 62, 4, 63, 100000035, 5, 100000005, 64, 6, 65, 100000016, 11, 66, 67, 28, 100000008, 67, 30, 69, 68, 31, 100000014, 100000015, 31, 100000012, 100000013, 4, 71, 100000035, 5, 100000005, 72, 6, 73, 100000011, 9, 74, 100000011, 11, 75, 76, 28, 100000008, 76, 31, 100000009, 100000010, 2, 100000001, 78, 3, 100000002, 79, 4, 80, 100000004, 7, 81, 100000004, 8, 100000003, 82, 10, 100000003, 100000004} type conditionContext struct { PartitionResult *awsrulesfn.PartitionConfig + parsedEndpoint *rulesfn.URL ParsedArn_ssa_2 *awsrulesfn.ARN FirstArn *string ParsedArn_ssa_1 *awsrulesfn.ARN @@ -345,80 +352,102 @@ func evalCondition(idx int, params *EndpointParameters, c *conditionContext) boo case 2: return *params.UseFIPS == true case 3: + return *params.UseDualStack == true + case 4: if v := awsrulesfn.GetPartition(*params.Region); v != nil { c.PartitionResult = v return true } return false - case 4: - return *params.Region == "local" case 5: - return c.PartitionResult.SupportsFIPS == true + return *params.Region == "local" case 6: - return *params.UseDualStack == true + return c.PartitionResult.SupportsFIPS == true case 7: - return c.PartitionResult.SupportsDualStack == true + if v := rulesfn.ParseURL(*params.Endpoint); v != nil { + c.parsedEndpoint = v + return true + } + return false case 8: return func() string { var out strings.Builder - out.WriteString("https://dynamodb.") + out.WriteString("dynamodb.") out.WriteString(*params.Region) out.WriteString(".") out.WriteString(c.PartitionResult.DualStackDnsSuffix) return out.String() - }() == *params.Endpoint + }() == c.parsedEndpoint.Authority case 9: - return params.AccountIdEndpointMode != nil + return c.PartitionResult.SupportsDualStack == true case 10: - return c.PartitionResult.Name == "aws" + return func() string { + var out strings.Builder + out.WriteString("search-dynamodb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DualStackDnsSuffix) + return out.String() + }() == c.parsedEndpoint.Authority case 11: - return *params.AccountIdEndpointMode == "disabled" + return params.AccountIdEndpointMode != nil case 12: - return params.ResourceArn != nil + return c.PartitionResult.Name == "aws" case 13: + return *params.AccountIdEndpointMode == "disabled" + case 14: + return params.ResourceArn != nil + case 15: if v := awsrulesfn.ParseARN(*params.ResourceArn); v != nil { c.ParsedArn_ssa_2 = v return true } return false - case 14: - return c.ParsedArn_ssa_2.Region == *params.Region - case 15: - return c.ParsedArn_ssa_2.Service == "dynamodb" case 16: - return rulesfn.IsValidHostLabel(c.ParsedArn_ssa_2.AccountId, false) + return c.ParsedArn_ssa_2.Region == *params.Region case 17: - return rulesfn.IsValidHostLabel(c.ParsedArn_ssa_2.Region, false) + return c.ParsedArn_ssa_2.Service == "dynamodb" case 18: - return params.ResourceArnList != nil + return rulesfn.IsValidHostLabel(c.ParsedArn_ssa_2.Region, false) case 19: + return rulesfn.IsValidHostLabel(c.ParsedArn_ssa_2.AccountId, false) + case 20: + return params.ResourceArnList != nil + case 21: if v := rulesfn.StringSlice(params.ResourceArnList).Get(0); v != nil { c.FirstArn = v return true } return false - case 20: + case 22: if v := awsrulesfn.ParseARN(*c.FirstArn); v != nil { c.ParsedArn_ssa_1 = v return true } return false - case 21: + case 23: return c.ParsedArn_ssa_1.Region == *params.Region - case 22: + case 24: return c.ParsedArn_ssa_1.Service == "dynamodb" - case 23: + case 25: return rulesfn.IsValidHostLabel(c.ParsedArn_ssa_1.AccountId, false) - case 24: + case 26: return rulesfn.IsValidHostLabel(c.ParsedArn_ssa_1.Region, false) - case 25: + case 27: return params.AccountId != nil - case 26: + case 28: return *params.AccountIdEndpointMode == "required" - case 27: + case 29: return rulesfn.IsValidHostLabel(*params.AccountId, false) - case 28: + case 30: return c.PartitionResult.Name == "aws-us-gov" + case 31: + return func() bool { + if v := params.IsSearchOperation; v != nil { + return *v + } + return false + }() == true } return false } @@ -463,10 +492,10 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( SchemeID: "sigv4", SignerProperties: func() smithy.Properties { var sp smithy.Properties + smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") + smithyhttp.SetSigV4SigningName(&sp, "dynamodb") smithyhttp.SetSigV4ASigningName(&sp, "dynamodb") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") return sp }(), }, @@ -479,7 +508,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( case 9: uriString := func() string { var out strings.Builder - out.WriteString("https://dynamodb-fips.") + out.WriteString("https://search-dynamodb-fips.") out.WriteString(*params.Region) out.WriteString(".") out.WriteString(c.PartitionResult.DualStackDnsSuffix) @@ -494,8 +523,42 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( Headers: http.Header{}, }, nil case 10: - return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") + uriString := func() string { + var out strings.Builder + out.WriteString("https://dynamodb-fips.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DualStackDnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil case 11: + return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") + case 12: + uriString := func() string { + var out strings.Builder + out.WriteString("https://search-dynamodb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + case 13: uriString := func() string { var out strings.Builder out.WriteString("https://dynamodb.") @@ -512,7 +575,24 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 12: + case 14: + uriString := func() string { + var out strings.Builder + out.WriteString("https://search-dynamodb-fips.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + case 15: uriString := func() string { var out strings.Builder out.WriteString("https://dynamodb-fips.") @@ -529,9 +609,35 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 13: + case 16: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") - case 14: + case 17: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(c.ParsedArn_ssa_2.AccountId) + out.WriteString(".search-ddb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DualStackDnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("metricValues", []interface{}{ + "O", + }) + return out + }(), + }, nil + case 18: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -557,7 +663,33 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( return out }(), }, nil - case 15: + case 19: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(c.ParsedArn_ssa_1.AccountId) + out.WriteString(".search-ddb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DualStackDnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("metricValues", []interface{}{ + "O", + }) + return out + }(), + }, nil + case 20: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -583,7 +715,33 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( return out }(), }, nil - case 16: + case 21: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(*params.AccountId) + out.WriteString(".search-ddb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DualStackDnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("metricValues", []interface{}{ + "O", + }) + return out + }(), + }, nil + case 22: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -609,13 +767,30 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( return out }(), }, nil - case 17: + case 23: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "Credentials-sourced account ID parameter is invalid") - case 18: + case 24: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "AccountIdEndpointMode is required but no AccountID was provided or able to be loaded") - case 19: + case 25: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required but account endpoints are not supported in this partition") - case 20: + case 26: + uriString := func() string { + var out strings.Builder + out.WriteString("https://search-dynamodb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DualStackDnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + case 27: uriString := func() string { var out strings.Builder out.WriteString("https://dynamodb.") @@ -632,9 +807,35 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 21: + case 28: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") - case 22: + case 29: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(c.ParsedArn_ssa_2.AccountId) + out.WriteString(".search-ddb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("metricValues", []interface{}{ + "O", + }) + return out + }(), + }, nil + case 30: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -660,7 +861,33 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( return out }(), }, nil - case 23: + case 31: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(c.ParsedArn_ssa_1.AccountId) + out.WriteString(".search-ddb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("metricValues", []interface{}{ + "O", + }) + return out + }(), + }, nil + case 32: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -686,7 +913,33 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( return out }(), }, nil - case 24: + case 33: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(*params.AccountId) + out.WriteString(".search-ddb.") + out.WriteString(*params.Region) + out.WriteString(".") + out.WriteString(c.PartitionResult.DnsSuffix) + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + out.Set("metricValues", []interface{}{ + "O", + }) + return out + }(), + }, nil + case 34: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -712,7 +965,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( return out }(), }, nil - case 25: + case 35: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") } return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, invalid result index: %d", idx) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/generated.json index f306b0cb12e..8725d337e50 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/generated.json @@ -54,6 +54,7 @@ "api_op_RestoreTableFromBackup.go", "api_op_RestoreTableToPointInTime.go", "api_op_Scan.go", + "api_op_SearchVectors.go", "api_op_TagResource.go", "api_op_TransactGetItems.go", "api_op_TransactWriteItems.go", @@ -77,6 +78,8 @@ "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", "options.go", + "request_snapshot_test.go", + "response_snapshot_test.go", "serializers.go", "snapshot_test.go", "sra_operation_order_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/go_module_metadata.go index 5c7766d0f2a..27e07a3e1e6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/go_module_metadata.go @@ -3,4 +3,4 @@ package dynamodb // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.59.1" +const goModuleVersion = "1.65.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/options.go index 5db1ed2b917..c74fb1f830b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/options.go @@ -47,6 +47,11 @@ type Options struct { // clients initial default settings. DefaultsMode aws.DefaultsMode + // Disables SDK clock skew correction. When set, the SDK will not adjust request + // signing timestamps to compensate for clock drift between the client and the + // service. + DisableClockSkewCorrection bool + // Allows you to disable the client's validation of response integrity using CRC32 // checksum. Enabled by default. DisableValidateResponseChecksum bool diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/serializers.go index 5316f9f4abd..a425e77f8b8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/serializers.go @@ -2702,6 +2702,67 @@ func (m *awsAwsjson10_serializeOpScan) HandleSerialize(ctx context.Context, in m return next.HandleSerialize(ctx, in) } +type awsAwsjson10_serializeOpSearchVectors struct { +} + +func (*awsAwsjson10_serializeOpSearchVectors) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsjson10_serializeOpSearchVectors) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*SearchVectorsInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.0") + httpBindingEncoder.SetHeader("X-Amz-Target").String("DynamoDB_20120810.SearchVectors") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsAwsjson10_serializeOpDocumentSearchVectorsInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} + type awsAwsjson10_serializeOpTagResource struct { } @@ -3988,6 +4049,49 @@ func awsAwsjson10_serializeDocumentCreateReplicationGroupMemberAction(v *types.C return nil } +func awsAwsjson10_serializeDocumentCreateVectorIndexAction(v *types.CreateVectorIndexAction, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Dimensions != nil { + ok := object.Key("Dimensions") + ok.Long(*v.Dimensions) + } + + if len(v.DistanceFunction) > 0 { + ok := object.Key("DistanceFunction") + ok.String(string(v.DistanceFunction)) + } + + if v.IndexName != nil { + ok := object.Key("IndexName") + ok.String(*v.IndexName) + } + + if v.Projection != nil { + ok := object.Key("Projection") + if err := awsAwsjson10_serializeDocumentProjection(v.Projection, ok); err != nil { + return err + } + } + + if v.SearchSchema != nil { + ok := object.Key("SearchSchema") + if err := awsAwsjson10_serializeDocumentSearchSchema(v.SearchSchema, ok); err != nil { + return err + } + } + + if v.VectorAttribute != nil { + ok := object.Key("VectorAttribute") + if err := awsAwsjson10_serializeDocumentVectorAttributeDefinition(v.VectorAttribute, ok); err != nil { + return err + } + } + + return nil +} + func awsAwsjson10_serializeDocumentCsvHeaderList(v []string, value smithyjson.Value) error { array := value.Array() defer array.Close() @@ -4123,6 +4227,18 @@ func awsAwsjson10_serializeDocumentDeleteRequest(v *types.DeleteRequest, value s return nil } +func awsAwsjson10_serializeDocumentDeleteVectorIndexAction(v *types.DeleteVectorIndexAction, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.IndexName != nil { + ok := object.Key("IndexName") + ok.String(*v.IndexName) + } + + return nil +} + func awsAwsjson10_serializeDocumentEnableKinesisStreamingConfiguration(v *types.EnableKinesisStreamingConfiguration, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -5250,6 +5366,52 @@ func awsAwsjson10_serializeDocumentS3BucketSource(v *types.S3BucketSource, value return nil } +func awsAwsjson10_serializeDocumentSearchSchema(v []types.SearchSchemaElement, value smithyjson.Value) error { + array := value.Array() + defer array.Close() + + for i := range v { + av := array.Value() + if err := awsAwsjson10_serializeDocumentSearchSchemaElement(&v[i], av); err != nil { + return err + } + } + return nil +} + +func awsAwsjson10_serializeDocumentSearchSchemaElement(v *types.SearchSchemaElement, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.AttributeName != nil { + ok := object.Key("AttributeName") + ok.String(*v.AttributeName) + } + + if len(v.SearchSchemaElementType) > 0 { + ok := object.Key("SearchSchemaElementType") + ok.String(string(v.SearchSchemaElementType)) + } + + return nil +} + +func awsAwsjson10_serializeDocumentSearchVectorList(v []types.AttributeValue, value smithyjson.Value) error { + array := value.Array() + defer array.Close() + + for i := range v { + av := array.Value() + if vv := v[i]; vv == nil { + continue + } + if err := awsAwsjson10_serializeDocumentAttributeValue(v[i], av); err != nil { + return err + } + } + return nil +} + func awsAwsjson10_serializeDocumentSSESpecification(v *types.SSESpecification, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -5356,6 +5518,13 @@ func awsAwsjson10_serializeDocumentTableCreationParameters(v *types.TableCreatio ok.String(*v.TableName) } + if v.VectorIndexes != nil { + ok := object.Key("VectorIndexes") + if err := awsAwsjson10_serializeDocumentVectorIndexList(v.VectorIndexes, ok); err != nil { + return err + } + } + return nil } @@ -5628,6 +5797,108 @@ func awsAwsjson10_serializeDocumentUpdateReplicationGroupMemberAction(v *types.U return nil } +func awsAwsjson10_serializeDocumentVectorAttributeDefinition(v *types.VectorAttributeDefinition, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.AttributeName != nil { + ok := object.Key("AttributeName") + ok.String(*v.AttributeName) + } + + return nil +} + +func awsAwsjson10_serializeDocumentVectorIndex(v *types.VectorIndex, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Dimensions != nil { + ok := object.Key("Dimensions") + ok.Long(*v.Dimensions) + } + + if len(v.DistanceFunction) > 0 { + ok := object.Key("DistanceFunction") + ok.String(string(v.DistanceFunction)) + } + + if v.IndexName != nil { + ok := object.Key("IndexName") + ok.String(*v.IndexName) + } + + if v.Projection != nil { + ok := object.Key("Projection") + if err := awsAwsjson10_serializeDocumentProjection(v.Projection, ok); err != nil { + return err + } + } + + if v.SearchSchema != nil { + ok := object.Key("SearchSchema") + if err := awsAwsjson10_serializeDocumentSearchSchema(v.SearchSchema, ok); err != nil { + return err + } + } + + if v.VectorAttribute != nil { + ok := object.Key("VectorAttribute") + if err := awsAwsjson10_serializeDocumentVectorAttributeDefinition(v.VectorAttribute, ok); err != nil { + return err + } + } + + return nil +} + +func awsAwsjson10_serializeDocumentVectorIndexList(v []types.VectorIndex, value smithyjson.Value) error { + array := value.Array() + defer array.Close() + + for i := range v { + av := array.Value() + if err := awsAwsjson10_serializeDocumentVectorIndex(&v[i], av); err != nil { + return err + } + } + return nil +} + +func awsAwsjson10_serializeDocumentVectorIndexUpdate(v *types.VectorIndexUpdate, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Create != nil { + ok := object.Key("Create") + if err := awsAwsjson10_serializeDocumentCreateVectorIndexAction(v.Create, ok); err != nil { + return err + } + } + + if v.Delete != nil { + ok := object.Key("Delete") + if err := awsAwsjson10_serializeDocumentDeleteVectorIndexAction(v.Delete, ok); err != nil { + return err + } + } + + return nil +} + +func awsAwsjson10_serializeDocumentVectorIndexUpdateList(v []types.VectorIndexUpdate, value smithyjson.Value) error { + array := value.Array() + defer array.Close() + + for i := range v { + av := array.Value() + if err := awsAwsjson10_serializeDocumentVectorIndexUpdate(&v[i], av); err != nil { + return err + } + } + return nil +} + func awsAwsjson10_serializeDocumentWarmThroughput(v *types.WarmThroughput, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -5879,6 +6150,13 @@ func awsAwsjson10_serializeOpDocumentCreateTableInput(v *CreateTableInput, value } } + if v.VectorIndexes != nil { + ok := object.Key("VectorIndexes") + if err := awsAwsjson10_serializeDocumentVectorIndexList(v.VectorIndexes, ok); err != nil { + return err + } + } + if v.WarmThroughput != nil { ok := object.Key("WarmThroughput") if err := awsAwsjson10_serializeDocumentWarmThroughput(v.WarmThroughput, ok); err != nil { @@ -6848,6 +7126,13 @@ func awsAwsjson10_serializeOpDocumentRestoreTableFromBackupInput(v *RestoreTable ok.String(*v.TargetTableName) } + if v.VectorIndexOverride != nil { + ok := object.Key("VectorIndexOverride") + if err := awsAwsjson10_serializeDocumentVectorIndexList(v.VectorIndexOverride, ok); err != nil { + return err + } + } + return nil } @@ -6920,6 +7205,13 @@ func awsAwsjson10_serializeOpDocumentRestoreTableToPointInTimeInput(v *RestoreTa ok.Boolean(*v.UseLatestRestorableTime) } + if v.VectorIndexOverride != nil { + ok := object.Key("VectorIndexOverride") + if err := awsAwsjson10_serializeDocumentVectorIndexList(v.VectorIndexOverride, ok); err != nil { + return err + } + } + return nil } @@ -7020,6 +7312,64 @@ func awsAwsjson10_serializeOpDocumentScanInput(v *ScanInput, value smithyjson.Va return nil } +func awsAwsjson10_serializeOpDocumentSearchVectorsInput(v *SearchVectorsInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.ExpressionAttributeNames != nil { + ok := object.Key("ExpressionAttributeNames") + if err := awsAwsjson10_serializeDocumentExpressionAttributeNameMap(v.ExpressionAttributeNames, ok); err != nil { + return err + } + } + + if v.ExpressionAttributeValues != nil { + ok := object.Key("ExpressionAttributeValues") + if err := awsAwsjson10_serializeDocumentExpressionAttributeValueMap(v.ExpressionAttributeValues, ok); err != nil { + return err + } + } + + if v.IndexName != nil { + ok := object.Key("IndexName") + ok.String(*v.IndexName) + } + + if v.ProjectionExpression != nil { + ok := object.Key("ProjectionExpression") + ok.String(*v.ProjectionExpression) + } + + if len(v.ReturnConsumedCapacity) > 0 { + ok := object.Key("ReturnConsumedCapacity") + ok.String(string(v.ReturnConsumedCapacity)) + } + + if v.SearchConditionExpression != nil { + ok := object.Key("SearchConditionExpression") + ok.String(*v.SearchConditionExpression) + } + + if v.SearchVector != nil { + ok := object.Key("SearchVector") + if err := awsAwsjson10_serializeDocumentSearchVectorList(v.SearchVector, ok); err != nil { + return err + } + } + + if v.TableName != nil { + ok := object.Key("TableName") + ok.String(*v.TableName) + } + + if v.TopK != nil { + ok := object.Key("TopK") + ok.Integer(*v.TopK) + } + + return nil +} + func awsAwsjson10_serializeOpDocumentTagResourceInput(v *TagResourceInput, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -7410,6 +7760,13 @@ func awsAwsjson10_serializeOpDocumentUpdateTableInput(v *UpdateTableInput, value ok.String(*v.TableName) } + if v.VectorIndexUpdates != nil { + ok := object.Key("VectorIndexUpdates") + if err := awsAwsjson10_serializeDocumentVectorIndexUpdateList(v.VectorIndexUpdates, ok); err != nil { + return err + } + } + if v.WarmThroughput != nil { ok := object.Key("WarmThroughput") if err := awsAwsjson10_serializeDocumentWarmThroughput(v.WarmThroughput, ok); err != nil { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/enums.go index c9beca8696c..8bd97fef518 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/enums.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/enums.go @@ -784,6 +784,25 @@ func (ScalarAttributeType) Values() []ScalarAttributeType { } } +type SearchSchemaElementType string + +// Enum values for SearchSchemaElementType +const ( + SearchSchemaElementTypeHash SearchSchemaElementType = "HASH" + SearchSchemaElementTypeInlineFilter SearchSchemaElementType = "INLINE_FILTER" +) + +// Values returns all known values for SearchSchemaElementType. Note that this can +// be expanded in the future, and so it is only as up to date as the client. +// +// The ordering of this slice is not guaranteed to be stable across updates. +func (SearchSchemaElementType) Values() []SearchSchemaElementType { + return []SearchSchemaElementType{ + "HASH", + "INLINE_FILTER", + } +} + type Select string // Enum values for Select @@ -947,6 +966,27 @@ func (TimeToLiveStatus) Values() []TimeToLiveStatus { } } +type VectorDistanceFunction string + +// Enum values for VectorDistanceFunction +const ( + VectorDistanceFunctionCosine VectorDistanceFunction = "COSINE" + VectorDistanceFunctionDotProduct VectorDistanceFunction = "DOT_PRODUCT" + VectorDistanceFunctionEuclidean VectorDistanceFunction = "EUCLIDEAN" +) + +// Values returns all known values for VectorDistanceFunction. Note that this can +// be expanded in the future, and so it is only as up to date as the client. +// +// The ordering of this slice is not guaranteed to be stable across updates. +func (VectorDistanceFunction) Values() []VectorDistanceFunction { + return []VectorDistanceFunction{ + "COSINE", + "DOT_PRODUCT", + "EUCLIDEAN", + } +} + type WitnessStatus string // Enum values for WitnessStatus diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/errors.go index 3774a406e5f..3d62100e2ee 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/errors.go @@ -961,7 +961,10 @@ func (e *ThrottlingException) ErrorFault() smithy.ErrorFault { return smithy.Fau // // DynamoDB lists the cancellation reasons on the CancellationReasons property. // Transaction cancellation reasons are ordered in the order of requested items, if -// an item has no error it will have None code and Null message. +// an item has no error it will have None code and Null message. The None code is +// returned as the literal string "None" , not a null or absent value; the message +// field is omitted entirely for an item that has no error. This is important to +// note when using an SDK that surfaces the code as an optional or nullable type. // // Cancellation reason codes and possible error messages: // diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/types.go index cfcc5041669..c595325e485 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/types/types.go @@ -897,6 +897,11 @@ type ConsumedCapacity struct { // in the response. TableName *string + // The amount of throughput consumed on each vector index affected by the + // operation. Each entry contains VectorWriteRequestBytes (for write operations) + // or VectorSearchRequestBytes (for search operations). + VectorIndexes map[string]VectorCapacity + // The total number of write capacity units consumed by the operation. WriteCapacityUnits *float64 @@ -1049,6 +1054,43 @@ type CreateReplicationGroupMemberAction struct { noSmithyDocumentSerde } +// A new vector index to be added to a table. +type CreateVectorIndexAction struct { + + // The number of dimensions in each vector. + // + // This member is required. + Dimensions *int64 + + // The distance function used to calculate similarity. Valid values: COSINE , + // EUCLIDEAN , DOT_PRODUCT . + // + // This member is required. + DistanceFunction VectorDistanceFunction + + // The name of the vector index. Must be unique within the table. + // + // This member is required. + IndexName *string + + // Specifies attributes that are copied (projected) from the table into the vector + // index. + // + // This member is required. + Projection *Projection + + // The attribute that contains vector embeddings. If multiple vector indexes + // reference the same attribute, they must all use the same number of dimensions. + // + // This member is required. + VectorAttribute *VectorAttributeDefinition + + // The partition key and inline filter attribute definitions for the vector index. + SearchSchema []SearchSchemaElement + + noSmithyDocumentSerde +} + // Processing options for the CSV file being imported. type CsvOptions struct { @@ -1156,6 +1198,17 @@ type DeleteRequest struct { noSmithyDocumentSerde } +// A vector index to be removed from a table. +type DeleteVectorIndexAction struct { + + // The name of the vector index to delete. + // + // This member is required. + IndexName *string + + noSmithyDocumentSerde +} + // Enables setting the configuration for Kinesis Streaming. type EnableKinesisStreamingConfiguration struct { @@ -1885,8 +1938,7 @@ type ImportSummary struct { // this import task. CloudWatchLogGroupArn *string - // The time at which this import task ended. (Does this include the successful - // complete creation of the table it was imported to?) + // The time at which this import task ended. EndTime *time.Time // The Amazon Resource Number (ARN) corresponding to the import request. @@ -2001,6 +2053,14 @@ type IncrementalExportSpecification struct { // The view type that was chosen for the export. Valid values are // NEW_AND_OLD_IMAGES and NEW_IMAGES . The default value is NEW_AND_OLD_IMAGES . + // + // NEW_AND_OLD_IMAGES exports both the new and old images of each changed item, + // while NEW_IMAGES exports only the new (latest) image. The view type you choose + // determines the structure of each item in the output for insert , update , and + // delete operations. For details and examples of how each view type shapes the + // export output, see [DynamoDB table export output format]in the Amazon DynamoDB Developer Guide. + // + // [DynamoDB table export output format]: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/S3DataExport.Output.html ExportViewType ExportViewType noSmithyDocumentSerde @@ -2488,10 +2548,18 @@ type ProvisionedThroughputDescription struct { // DynamoDB returns a ThrottlingException . Eventually consistent reads require // less effort than strongly consistent reads, so a setting of 50 ReadCapacityUnits // per second provides 100 eventually consistent ReadCapacityUnits per second. + // + // For a table or global secondary index that uses on-demand capacity mode ( + // PAY_PER_REQUEST ), this value is 0 , because on-demand mode does not use + // provisioned throughput. ReadCapacityUnits *int64 // The maximum number of writes consumed per second before DynamoDB returns a // ThrottlingException . + // + // For a table or global secondary index that uses on-demand capacity mode ( + // PAY_PER_REQUEST ), this value is 0 , because on-demand mode does not use + // provisioned throughput. WriteCapacityUnits *int64 noSmithyDocumentSerde @@ -3006,6 +3074,44 @@ type S3BucketSource struct { noSmithyDocumentSerde } +// A single result from a SearchVectors operation. +type SearchResultItem struct { + + // A map of attribute names to AttributeValue objects, representing the projected + // attributes of the item returned by the vector search. + Item map[string]AttributeValue + + // The similarity score for this item relative to the search vector. The + // interpretation depends on the distance function configured for the vector index. + Score float64 + + noSmithyDocumentSerde +} + +// An element in the search schema of a vector index. +type SearchSchemaElement struct { + + // The name of the attribute. + // + // This member is required. + AttributeName *string + + // The role of the attribute in the search schema. Valid values: + // + // - HASH - A partition key that partitions the vector index for independent + // scaling. When specified, you must provide this attribute's value in the + // SearchConditionExpression . + // + // - INLINE_FILTER - An attribute projected into the vector index for filtering + // at the storage layer during search. Inline filters are optional in the + // SearchConditionExpression . + // + // This member is required. + SearchSchemaElementType SearchSchemaElementType + + noSmithyDocumentSerde +} + // Contains the details of the table when the backup was created. type SourceTableDetails struct { @@ -3085,6 +3191,11 @@ type SourceTableFeatureDetails struct { // Time to Live settings on the table when the backup was created. TimeToLiveDescription *TimeToLiveDescription + // The vector index properties for the table at the time the backup was created, + // including the index name, vector attribute, dimensions, distance function, + // search schema, and projection. + VectorIndexes []VectorIndexInfo + noSmithyDocumentSerde } @@ -3253,6 +3364,9 @@ type TableCreationParameters struct { // Represents the settings used to enable server-side encryption. SSESpecification *SSESpecification + // The vector indexes of the table to be created as part of the import operation. + VectorIndexes []VectorIndex + noSmithyDocumentSerde } @@ -3512,7 +3626,8 @@ type TableDescription struct { // Contains details of the table class. TableClassSummary *TableClassSummary - // Unique identifier for the table for which the backup was created. + // A unique identifier for the table, in UUID format, generated by DynamoDB when + // the table is created. TableId *string // The name of the table. @@ -3546,6 +3661,40 @@ type TableDescription struct { // information. TableStatus TableStatus + // The vector indexes, if any, on the table. Each element is composed of: + // + // - IndexName - The name of the vector index. + // + // - IndexStatus - The current status of the vector index: CREATING , ACTIVE , or + // DELETING . + // + // - Backfilling - Specifies whether the index is currently backfilling. During + // backfill, SearchVectors operations might return incomplete results. + // + // - VectorAttribute - The attribute that contains vector embeddings. + // + // - Dimensions - The number of dimensions in each vector. + // + // - DistanceFunction - The distance function used to calculate similarity ( + // COSINE , EUCLIDEAN , or DOT_PRODUCT ). + // + // - SearchSchema - The partition key and inline filter attributes for the vector + // index. + // + // - Projection - Specifies attributes that are copied (projected) from the table + // into the vector index. + // + // - IndexArn - The Amazon Resource Name (ARN) that uniquely identifies the index. + // + // - IndexSizeBytes - The total size of the vector index, in bytes. Amazon + // DynamoDB updates this value approximately every six hours. Recent changes might + // not be reflected in this value. + // + // - ItemCount - The number of items indexed in the vector index. Amazon DynamoDB + // updates this value approximately every six hours. Recent changes might not be + // reflected in this value. + VectorIndexes []VectorIndexDescription + // Describes the warm throughput value of the base table. WarmThroughput *TableWarmThroughputDescription @@ -3821,6 +3970,163 @@ type UpdateReplicationGroupMemberAction struct { noSmithyDocumentSerde } +// The definition of a vector attribute for a vector index. +type VectorAttributeDefinition struct { + + // The name of the vector attribute. + // + // This member is required. + AttributeName *string + + noSmithyDocumentSerde +} + +// The consumed capacity for vector index operations, including vector search +// request bytes and vector write request bytes. +type VectorCapacity struct { + + // The number of vector search request bytes consumed by a SearchVectors operation. + VectorSearchRequestBytes *float64 + + // The number of vector write request bytes consumed when writing to a vector + // index. Reported for write operations that modify attributes indexed by a vector + // index. + VectorWriteRequestBytes *float64 + + noSmithyDocumentSerde +} + +// Contains the configuration settings for a vector index, including the index +// name, vector attribute, dimensions, distance function, search schema, and +// projection. +type VectorIndex struct { + + // The number of dimensions in each vector. + // + // This member is required. + Dimensions *int64 + + // The distance function used to calculate similarity between vectors. Valid + // values: COSINE , EUCLIDEAN , DOT_PRODUCT . + // + // This member is required. + DistanceFunction VectorDistanceFunction + + // The name of the vector index. + // + // This member is required. + IndexName *string + + // Specifies attributes that are copied (projected) from the table into the vector + // index. + // + // This member is required. + Projection *Projection + + // The vector attribute configuration for the index. + // + // This member is required. + VectorAttribute *VectorAttributeDefinition + + // The search schema that defines partition key and inline filter attributes for + // the vector index. + SearchSchema []SearchSchemaElement + + noSmithyDocumentSerde +} + +// Contains the current state and configuration of a vector index, including its +// status, size, item count, and the settings specified when the index was created. +type VectorIndexDescription struct { + + // Specifies whether the index is currently backfilling. During backfill, + // SearchVectors operations might return incomplete results. + Backfilling *bool + + // The number of dimensions in each vector. + Dimensions *int64 + + // The distance function used to calculate similarity between vectors. + DistanceFunction VectorDistanceFunction + + // The Amazon Resource Name (ARN) that uniquely identifies the vector index. + IndexArn *string + + // The name of the vector index. + IndexName *string + + // The total size of the vector index, in bytes. Amazon DynamoDB updates this + // value approximately every six hours. Recent changes might not be reflected in + // this value. + IndexSizeBytes *int64 + + // The current state of the vector index: + // + // - CREATING - The index is being created. + // + // - ACTIVE - The index is ready for use. + // + // - DELETING - The index is being deleted. + IndexStatus IndexStatus + + // The number of items indexed in the vector index. Amazon DynamoDB updates this + // value approximately every six hours. Recent changes might not be reflected in + // this value. + ItemCount *int64 + + // Specifies attributes that are copied (projected) from the table into the vector + // index. + Projection *Projection + + // The search schema that defines partition key and inline filter attributes for + // the vector index. + SearchSchema []SearchSchemaElement + + // The vector attribute configuration for the index. + VectorAttribute *VectorAttributeDefinition + + noSmithyDocumentSerde +} + +// Contains the configuration of a vector index as it existed at the time a backup +// was created. +type VectorIndexInfo struct { + + // The number of dimensions in each vector. + Dimensions *int64 + + // The distance function used to calculate similarity between vectors. + DistanceFunction VectorDistanceFunction + + // The name of the vector index. + IndexName *string + + // Specifies attributes that are copied (projected) from the table into the vector + // index. + Projection *Projection + + // The search schema that defines partition key and inline filter attributes for + // the vector index. + SearchSchema []SearchSchemaElement + + // The vector attribute configuration for the index. + VectorAttribute *VectorAttributeDefinition + + noSmithyDocumentSerde +} + +// A vector index to be added to or removed from a table. +type VectorIndexUpdate struct { + + // The configuration for creating a new vector index on the table. + Create *CreateVectorIndexAction + + // The configuration for deleting an existing vector index from the table. + Delete *DeleteVectorIndexAction + + noSmithyDocumentSerde +} + // Provides visibility into the number of read and write operations your table or // secondary index can instantaneously support. The settings can be modified using // the UpdateTable operation to meet the throughput requirements of an upcoming diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/validators.go index cd5187a3076..435b56e94c6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/dynamodb/validators.go @@ -730,6 +730,26 @@ func (m *validateOpScan) HandleInitialize(ctx context.Context, in middleware.Ini return next.HandleInitialize(ctx, in) } +type validateOpSearchVectors struct { +} + +func (*validateOpSearchVectors) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpSearchVectors) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*SearchVectorsInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpSearchVectorsInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + type validateOpTagResource struct { } @@ -1134,6 +1154,10 @@ func addOpScanValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpScan{}, middleware.After) } +func addOpSearchVectorsValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpSearchVectors{}, middleware.After) +} + func addOpTagResourceValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpTagResource{}, middleware.After) } @@ -1438,6 +1462,42 @@ func validateCreateReplicationGroupMemberAction(v *types.CreateReplicationGroupM } } +func validateCreateVectorIndexAction(v *types.CreateVectorIndexAction) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "CreateVectorIndexAction"} + if v.IndexName == nil { + invalidParams.Add(smithy.NewErrParamRequired("IndexName")) + } + if v.VectorAttribute == nil { + invalidParams.Add(smithy.NewErrParamRequired("VectorAttribute")) + } else if v.VectorAttribute != nil { + if err := validateVectorAttributeDefinition(v.VectorAttribute); err != nil { + invalidParams.AddNested("VectorAttribute", err.(smithy.InvalidParamsError)) + } + } + if v.SearchSchema != nil { + if err := validateSearchSchema(v.SearchSchema); err != nil { + invalidParams.AddNested("SearchSchema", err.(smithy.InvalidParamsError)) + } + } + if v.Projection == nil { + invalidParams.Add(smithy.NewErrParamRequired("Projection")) + } + if v.Dimensions == nil { + invalidParams.Add(smithy.NewErrParamRequired("Dimensions")) + } + if len(v.DistanceFunction) == 0 { + invalidParams.Add(smithy.NewErrParamRequired("DistanceFunction")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateDelete(v *types.Delete) error { if v == nil { return nil @@ -1531,6 +1591,21 @@ func validateDeleteRequest(v *types.DeleteRequest) error { } } +func validateDeleteVectorIndexAction(v *types.DeleteVectorIndexAction) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "DeleteVectorIndexAction"} + if v.IndexName == nil { + invalidParams.Add(smithy.NewErrParamRequired("IndexName")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateFilterConditionMap(v map[string]types.Condition) error { if v == nil { return nil @@ -2278,6 +2353,41 @@ func validateS3BucketSource(v *types.S3BucketSource) error { } } +func validateSearchSchema(v []types.SearchSchemaElement) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "SearchSchema"} + for i := range v { + if err := validateSearchSchemaElement(&v[i]); err != nil { + invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateSearchSchemaElement(v *types.SearchSchemaElement) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "SearchSchemaElement"} + if v.AttributeName == nil { + invalidParams.Add(smithy.NewErrParamRequired("AttributeName")) + } + if len(v.SearchSchemaElementType) == 0 { + invalidParams.Add(smithy.NewErrParamRequired("SearchSchemaElementType")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateStreamSpecification(v *types.StreamSpecification) error { if v == nil { return nil @@ -2325,6 +2435,11 @@ func validateTableCreationParameters(v *types.TableCreationParameters) error { invalidParams.AddNested("GlobalSecondaryIndexes", err.(smithy.InvalidParamsError)) } } + if v.VectorIndexes != nil { + if err := validateVectorIndexList(v.VectorIndexes); err != nil { + invalidParams.AddNested("VectorIndexes", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { @@ -2531,6 +2646,113 @@ func validateUpdateReplicationGroupMemberAction(v *types.UpdateReplicationGroupM } } +func validateVectorAttributeDefinition(v *types.VectorAttributeDefinition) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "VectorAttributeDefinition"} + if v.AttributeName == nil { + invalidParams.Add(smithy.NewErrParamRequired("AttributeName")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateVectorIndex(v *types.VectorIndex) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "VectorIndex"} + if v.IndexName == nil { + invalidParams.Add(smithy.NewErrParamRequired("IndexName")) + } + if v.VectorAttribute == nil { + invalidParams.Add(smithy.NewErrParamRequired("VectorAttribute")) + } else if v.VectorAttribute != nil { + if err := validateVectorAttributeDefinition(v.VectorAttribute); err != nil { + invalidParams.AddNested("VectorAttribute", err.(smithy.InvalidParamsError)) + } + } + if v.SearchSchema != nil { + if err := validateSearchSchema(v.SearchSchema); err != nil { + invalidParams.AddNested("SearchSchema", err.(smithy.InvalidParamsError)) + } + } + if v.Projection == nil { + invalidParams.Add(smithy.NewErrParamRequired("Projection")) + } + if v.Dimensions == nil { + invalidParams.Add(smithy.NewErrParamRequired("Dimensions")) + } + if len(v.DistanceFunction) == 0 { + invalidParams.Add(smithy.NewErrParamRequired("DistanceFunction")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateVectorIndexList(v []types.VectorIndex) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "VectorIndexList"} + for i := range v { + if err := validateVectorIndex(&v[i]); err != nil { + invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateVectorIndexUpdate(v *types.VectorIndexUpdate) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "VectorIndexUpdate"} + if v.Create != nil { + if err := validateCreateVectorIndexAction(v.Create); err != nil { + invalidParams.AddNested("Create", err.(smithy.InvalidParamsError)) + } + } + if v.Delete != nil { + if err := validateDeleteVectorIndexAction(v.Delete); err != nil { + invalidParams.AddNested("Delete", err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateVectorIndexUpdateList(v []types.VectorIndexUpdate) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "VectorIndexUpdateList"} + for i := range v { + if err := validateVectorIndexUpdate(&v[i]); err != nil { + invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateWriteRequest(v *types.WriteRequest) error { if v == nil { return nil @@ -2706,6 +2928,11 @@ func validateOpCreateTableInput(v *CreateTableInput) error { invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) } } + if v.VectorIndexes != nil { + if err := validateVectorIndexList(v.VectorIndexes); err != nil { + invalidParams.AddNested("VectorIndexes", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { @@ -3193,6 +3420,11 @@ func validateOpRestoreTableFromBackupInput(v *RestoreTableFromBackupInput) error invalidParams.AddNested("ProvisionedThroughputOverride", err.(smithy.InvalidParamsError)) } } + if v.VectorIndexOverride != nil { + if err := validateVectorIndexList(v.VectorIndexOverride); err != nil { + invalidParams.AddNested("VectorIndexOverride", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { @@ -3223,6 +3455,11 @@ func validateOpRestoreTableToPointInTimeInput(v *RestoreTableToPointInTimeInput) invalidParams.AddNested("ProvisionedThroughputOverride", err.(smithy.InvalidParamsError)) } } + if v.VectorIndexOverride != nil { + if err := validateVectorIndexList(v.VectorIndexOverride); err != nil { + invalidParams.AddNested("VectorIndexOverride", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { @@ -3250,6 +3487,30 @@ func validateOpScanInput(v *ScanInput) error { } } +func validateOpSearchVectorsInput(v *SearchVectorsInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "SearchVectorsInput"} + if v.TableName == nil { + invalidParams.Add(smithy.NewErrParamRequired("TableName")) + } + if v.IndexName == nil { + invalidParams.Add(smithy.NewErrParamRequired("IndexName")) + } + if v.SearchVector == nil { + invalidParams.Add(smithy.NewErrParamRequired("SearchVector")) + } + if v.TopK == nil { + invalidParams.Add(smithy.NewErrParamRequired("TopK")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateOpTagResourceInput(v *TagResourceInput) error { if v == nil { return nil @@ -3494,6 +3755,11 @@ func validateOpUpdateTableInput(v *UpdateTableInput) error { invalidParams.AddNested("GlobalTableWitnessUpdates", err.(smithy.InvalidParamsError)) } } + if v.VectorIndexUpdates != nil { + if err := validateVectorIndexUpdateList(v.VectorIndexUpdates); err != nil { + invalidParams.AddNested("VectorIndexUpdates", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md index 2fb0269e710..6723895d1a0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md @@ -1,3 +1,31 @@ +# v1.13.19 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. + +# v1.13.18 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. + +# v1.13.17 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. + +# v1.13.16 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. + +# v1.13.15 (2026-07-31.2) + +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.13.14 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. + +# v1.13.13 (2026-07-01) + +* No change notes available for this release. + # v1.13.12 (2026-06-04) * **Dependency Update**: Update to smithy-go v1.27.1 to fix several union-related deserialization bugs in schema-serde-enabled services. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go index b769e842733..f5bc392a462 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go @@ -3,4 +3,4 @@ package acceptencoding // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.12" +const goModuleVersion = "1.13.19" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/CHANGELOG.md index cfcd48ae2b1..885b7257bc6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/CHANGELOG.md @@ -1,3 +1,62 @@ +# v1.13.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.17 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.16 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.15 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.14 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.13 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.12 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.11 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.12.10 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.9 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.8 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.7 (2026-07-01) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.12.6 (2026-06-08) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/go_module_metadata.go index 19fd00e2c08..ef8bfe05c07 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery/go_module_metadata.go @@ -3,4 +3,4 @@ package endpointdiscovery // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.6" +const goModuleVersion = "1.13.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md index 2a082b44f71..97ee82b1658 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md @@ -1,3 +1,62 @@ +# v1.14.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.14.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.40 (2026-08-26) + +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.39 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.38 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.37 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.36 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.35 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.34 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.13.33 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.32 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.31 (2026-07-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.30 (2026-07-01) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.13.29 (2026-06-08) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go index 84b406a7846..f6014e050d0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go @@ -3,4 +3,4 @@ package presignedurl // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.29" +const goModuleVersion = "1.14.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md index cf926f5bc5a..522a96fd6d5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md @@ -1,3 +1,77 @@ +# v1.7.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.7.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.6.0 (2026-08-26) + +* **Feature**: Stop registering the `ComputeContentLength` middleware in generated clients. `Content-Length` is now set when the request body is set via `SetStream`. +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.8 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.7 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.6 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.5 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.4 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.3 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.5.2 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.1 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.5.0 (2026-07-21) + +* **Feature**: Add an option to clients to disable clock skew +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.1 (2026-07-13) + +* No change notes available for this release. + +# v1.4.0 (2026-07-08.2) + +* **Feature**: Adds support for OAuth 2.0 token operations in AWS Sign-In, CreateOAuth2TokenWithIAM (client credentials flow), IntrospectOAuth2TokenWithIAM (token inspection), and RevokeOAuth2TokenWithIAM (token revocation). + +# v1.3.0 (2026-07-06) + +* **Feature**: Add request serialization snapshot tests. + +# v1.2.2 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.2.1 (2026-06-29) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go index 545b8f1066b..683d2fdb093 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go @@ -16,6 +16,7 @@ import ( internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/timeouts" smithy "github.com/aws/smithy-go" smithydocument "github.com/aws/smithy-go/document" "github.com/aws/smithy-go/logging" @@ -263,6 +264,10 @@ func (c *Client) invokeOperation( finalizeClientEndpointResolverOptions(&options) + ctx = setLoggerContext(ctx, options, opID) + + ctx = resolveServiceMetadata(ctx, options, opID) + if err := c.addCommonMiddlewares(stack, options, opID); err != nil { return nil, metadata, err } @@ -379,9 +384,6 @@ func (c *Client) addCommonMiddlewares(stack *middleware.Stack, options Options, if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { return fmt.Errorf("add protocol finalizers: %v", err) } - if err := addSetLoggerMiddleware(stack, options); err != nil { - return err - } if err := addClientRequestID(stack); err != nil { return err } @@ -434,30 +436,6 @@ func resolveAuthSchemes(options *Options) { type noSmithyDocumentSerde = smithydocument.NoSerde -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -465,8 +443,9 @@ func resolveDefaultLogger(o *Options) { o.Logger = logging.Nop{} } -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) +func setLoggerContext(ctx context.Context, options Options, operation string) context.Context { + _ = operation + return middleware.SetLogger(ctx, options.Logger) } func setResolvedDefaultsMode(o *Options) { @@ -487,16 +466,17 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - AuthSchemePreference: cfg.AuthSchemePreference, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + DisableClockSkewCorrection: cfg.DisableClockSkewCorrection, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -544,6 +524,12 @@ func resolveHTTPClient(o *Options) { }) } + if _, ok := buildable.GetReadTimeout(); !ok { + if timeout, ok := timeouts.GetServiceReadTimeout(ServiceID); ok { + buildable = buildable.WithReadTimeout(timeout) + } + } + o.HTTPClient = buildable } @@ -685,16 +671,14 @@ func addClientRequestID(stack *middleware.Stack) error { return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) } -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Insert(&smithyhttp.ComputeContentLength{}, "ClientRequestID", middleware.After) -} - func addRawResponseToMetadata(stack *middleware.Stack) error { return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) } -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +func addRecordResponseTiming(stack *middleware.Stack, options Options) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{ + DisableClockSkewCorrection: options.DisableClockSkewCorrection, + }, middleware.After) } func addSpanRetryLoop(stack *middleware.Stack, options Options) error { @@ -772,6 +756,7 @@ func addRetry(stack *middleware.Stack, o Options, c *Client) error { m.LogAttempts = o.ClientLogMode.IsRetries() m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/signin") m.ClientSkew = c.timeOffset + m.DisableClockSkewCorrection = o.DisableClockSkewCorrection }) if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { return err @@ -879,12 +864,16 @@ type IdempotencyTokenProvider interface { GetIdempotencyToken() (string, error) } -func newServiceMetadataMiddleware(region, operation string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: operation, +func resolveServiceMetadata(ctx context.Context, options Options, operation string) context.Context { + ctx = awsmiddleware.SetServiceID(ctx, ServiceID) + if options.Region != "" { + ctx = awsmiddleware.SetRegion(ctx, options.Region) + } + ctx = awsmiddleware.SetOperationName(ctx, operation) + if options.EndpointResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) } + return ctx } func addRecursionDetection(stack *middleware.Stack) error { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go index 415f9a2b4d5..d58473ac8d2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/signin/types" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // CreateOAuth2Token API @@ -117,22 +116,10 @@ func (c *Client) addOperationCreateOAuth2TokenMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -141,9 +128,6 @@ func (c *Client) addOperationCreateOAuth2TokenMiddlewares(stack *middleware.Stac if err = addOpCreateOAuth2TokenValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "CreateOAuth2Token"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2TokenWithIAM.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2TokenWithIAM.go new file mode 100644 index 00000000000..ee19239b258 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2TokenWithIAM.go @@ -0,0 +1,118 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" +) + +// Grants permission to exchange client credentials for an OAuth 2.0 access token +// scoped to a resource that can be used to access AWS services from applications +func (c *Client) CreateOAuth2TokenWithIAM(ctx context.Context, params *CreateOAuth2TokenWithIAMInput, optFns ...func(*Options)) (*CreateOAuth2TokenWithIAMOutput, error) { + if params == nil { + params = &CreateOAuth2TokenWithIAMInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "CreateOAuth2TokenWithIAM", params, optFns, c.addOperationCreateOAuth2TokenWithIAMMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*CreateOAuth2TokenWithIAMOutput) + out.ResultMetadata = metadata + return out, nil +} + +// Input structure for CreateOAuth2TokenWithIAM operation +type CreateOAuth2TokenWithIAMInput struct { + + // OAuth 2.0 grant type. Must be "client_credentials". + // + // This member is required. + GrantType *string + + // The OAuth resource for which the access token is requested. Example: + // "aws-mcp.amazonaws.com". + // + // This member is required. + Resource *string + + noSmithyDocumentSerde +} + +func (in *CreateOAuth2TokenWithIAMInput) bindEndpointParams(p *EndpointParameters) { + + p.IsOAuthEndpoint = ptr.Bool(true) +} + +// Output structure for CreateOAuth2TokenWithIAM operation +// +// Contains the JWT access token, token type, and expiration per RFC 6749 §5.1. +type CreateOAuth2TokenWithIAMOutput struct { + + // JWT access token containing principal identity, resource scope, and session + // metadata + // + // This member is required. + AccessToken *string + + // Token lifetime in seconds. Value is the minimum of session validity and 1 hour. + // + // This member is required. + ExpiresIn *int32 + + // Always "Bearer" per OAuth 2.1 specification + // + // This member is required. + TokenType *string + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationCreateOAuth2TokenWithIAMMiddlewares(stack *middleware.Stack, options Options) (err error) { + err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateOAuth2TokenWithIAM{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateOAuth2TokenWithIAM{}, middleware.After) + if err != nil { + return err + } + + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpCreateOAuth2TokenWithIAMValidationMiddleware(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteConsoleAuthorizationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteConsoleAuthorizationConfiguration.go index a9c42942acb..0471b9c5692 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteConsoleAuthorizationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteConsoleAuthorizationConfiguration.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Delete console authorization configuration with automatic scope detection @@ -73,33 +72,18 @@ func (c *Client) addOperationDeleteConsoleAuthorizationConfigurationMiddlewares( return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DeleteConsoleAuthorizationConfiguration"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteResourcePermissionStatement.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteResourcePermissionStatement.go index add06008dbf..513a82481d7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteResourcePermissionStatement.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_DeleteResourcePermissionStatement.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Remove a permission statement from the account's SignIn resource-based policy @@ -63,25 +62,13 @@ func (c *Client) addOperationDeleteResourcePermissionStatementMiddlewares(stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -93,9 +80,6 @@ func (c *Client) addOperationDeleteResourcePermissionStatementMiddlewares(stack if err = addOpDeleteResourcePermissionStatementValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DeleteResourcePermissionStatement"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetConsoleAuthorizationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetConsoleAuthorizationConfiguration.go index 2def43d98e5..90498a68c1a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetConsoleAuthorizationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetConsoleAuthorizationConfiguration.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Get console authorization configuration with automatic scope detection @@ -73,33 +72,18 @@ func (c *Client) addOperationGetConsoleAuthorizationConfigurationMiddlewares(sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetConsoleAuthorizationConfiguration"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetResourcePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetResourcePolicy.go index 9b571203c5d..087ff167f51 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetResourcePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_GetResourcePolicy.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/signin/types" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Retrieve the account's consolidated SignIn resource-based policy @@ -60,33 +59,18 @@ func (c *Client) addOperationGetResourcePolicyMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetResourcePolicy"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_IntrospectOAuth2TokenWithIAM.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_IntrospectOAuth2TokenWithIAM.go new file mode 100644 index 00000000000..a2894eca9bf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_IntrospectOAuth2TokenWithIAM.go @@ -0,0 +1,168 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" +) + +// Grants permission to inspect the metadata and state of an OAuth 2.0 access +// token or refresh token +// +// Implements RFC 7662 OAuth 2.0 Token Introspection over a SigV4-authenticated +// endpoint. Inspects the metadata of an access_token or refresh_token issued by +// AWS Sign-In and returns the claims associated with it. +// +// Inactive token semantics (RFC 7662 §2.2): when the supplied token is unknown, +// expired, revoked, malformed, or owned by a different account, the response body +// is exactly { "active": false } with all other claims omitted. +func (c *Client) IntrospectOAuth2TokenWithIAM(ctx context.Context, params *IntrospectOAuth2TokenWithIAMInput, optFns ...func(*Options)) (*IntrospectOAuth2TokenWithIAMOutput, error) { + if params == nil { + params = &IntrospectOAuth2TokenWithIAMInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "IntrospectOAuth2TokenWithIAM", params, optFns, c.addOperationIntrospectOAuth2TokenWithIAMMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*IntrospectOAuth2TokenWithIAMOutput) + out.ResultMetadata = metadata + return out, nil +} + +// Input structure for IntrospectOAuth2TokenWithIAM operation +// +// RFC 7662 §2.1 introspection request. Contains the token to inspect and an +// optional hint about the token's type. +type IntrospectOAuth2TokenWithIAMInput struct { + + // The string value of the token to introspect. May be either an access_token or a + // refresh_token issued by AWS Sign-In. + // + // This member is required. + Token *string + + // Optional hint about the type of the token submitted for introspection. The + // server uses this hint to optimize lookup, but still falls back to the other + // token type on miss. Allowed values: access_token, refresh_token. + TokenTypeHint *string + + noSmithyDocumentSerde +} + +func (in *IntrospectOAuth2TokenWithIAMInput) bindEndpointParams(p *EndpointParameters) { + + p.IsOAuthEndpoint = ptr.Bool(true) +} + +// Output structure for IntrospectOAuth2TokenWithIAM operation +// +// RFC 7662 §2.2 introspection response. Only active is required; all other claims +// are omitted when the token is inactive. +type IntrospectOAuth2TokenWithIAMOutput struct { + + // Indicates whether the token is currently active. true only when the token is + // valid, has not expired, has not been revoked, and belongs to the caller's + // account. + // + // This member is required. + Active *bool + + // 12-digit AWS account ID of the token's subject principal. + AccountId *string + + // Audience of the token: the OAuth resource the token is scoped to (for example, + // "aws-mcp.amazonaws.com"). Omitted for refresh tokens. + Aud *string + + // Client identifier for the OAuth 2.0 client that requested the token. + ClientId *string + + // Token expiration time as a NumericDate (Unix epoch seconds). + Exp *int64 + + // Token issuance time as a NumericDate (Unix epoch seconds). + Iat *int64 + + // Issuer of the token. Always "signin.amazonaws.com" for AWS Sign-In. + Iss *string + + // Unique identifier for the token. + Jti *string + + // Token "not before" time as a NumericDate (Unix epoch seconds). + Nbf *int64 + + // The OAuth resource the token is scoped to during Human OAuth flow. Only present + // for refresh token introspection. + Resource *string + + // AWS Sign-In session ARN bound to the token, of the form + // arn:aws:signin:{region}:{account}:session/{uuid}. + SigninSession *string + + // Subject of the token: the IAM principal ARN. For assumed-role sessions, this is + // the session ARN (matches sts:GetCallerIdentity's Arn field), e.g. + // arn:aws:sts::123456789012:assumed-role/MyRole/session-name. + Sub *string + + // Indicates which kind of token was introspected. One of "access_token" or + // "refresh_token". + TokenType *string + + // User identifier matching sts:GetCallerIdentity's UserId field for the token's + // subject principal (e.g. "AIDAEXAMPLE" for an IAM user, or + // "AROAEXAMPLE:session-name" for an assumed role). + UserId *string + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationIntrospectOAuth2TokenWithIAMMiddlewares(stack *middleware.Stack, options Options) (err error) { + err = stack.Serialize.Add(&awsRestjson1_serializeOpIntrospectOAuth2TokenWithIAM{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsRestjson1_deserializeOpIntrospectOAuth2TokenWithIAM{}, middleware.After) + if err != nil { + return err + } + + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpIntrospectOAuth2TokenWithIAMValidationMiddleware(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_ListResourcePermissionStatements.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_ListResourcePermissionStatements.go index 46a4c6c89f2..22d0b58a915 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_ListResourcePermissionStatements.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_ListResourcePermissionStatements.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/signin/types" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Retrieve all permission statements in the account's SignIn resource-based policy @@ -71,33 +70,18 @@ func (c *Client) addOperationListResourcePermissionStatementsMiddlewares(stack * return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListResourcePermissionStatements"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutConsoleAuthorizationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutConsoleAuthorizationConfiguration.go index d54b0d42190..ab698a339f8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutConsoleAuthorizationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutConsoleAuthorizationConfiguration.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Enable console authorization configuration with automatic scope detection @@ -73,33 +72,18 @@ func (c *Client) addOperationPutConsoleAuthorizationConfigurationMiddlewares(sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "PutConsoleAuthorizationConfiguration"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutResourcePermissionStatement.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutResourcePermissionStatement.go index e04aaba5c2c..7013ae576d8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutResourcePermissionStatement.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_PutResourcePermissionStatement.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Create a permission statement in the account's SignIn resource-based policy @@ -86,25 +85,13 @@ func (c *Client) addOperationPutResourcePermissionStatementMiddlewares(stack *mi return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -113,9 +100,6 @@ func (c *Client) addOperationPutResourcePermissionStatementMiddlewares(stack *mi if err = addIdempotencyToken_opPutResourcePermissionStatementMiddleware(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "PutResourcePermissionStatement"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_RevokeOAuth2TokenWithIAM.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_RevokeOAuth2TokenWithIAM.go new file mode 100644 index 00000000000..366d76c4936 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_RevokeOAuth2TokenWithIAM.go @@ -0,0 +1,106 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" +) + +// Grants permission to revoke an OAuth 2.0 refresh token and its associated +// refresh tokens +// +// Revokes a refresh_token issued by AWS Sign-In, invalidating the entire token +// chain so that the refresh_token can no longer be used to mint new access_tokens. +// +// Idempotency: revoking an already-revoked, expired, or otherwise invalid token +// still returns 200 OK with an empty body. Only the refresh_token type is +// accepted. +func (c *Client) RevokeOAuth2TokenWithIAM(ctx context.Context, params *RevokeOAuth2TokenWithIAMInput, optFns ...func(*Options)) (*RevokeOAuth2TokenWithIAMOutput, error) { + if params == nil { + params = &RevokeOAuth2TokenWithIAMInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "RevokeOAuth2TokenWithIAM", params, optFns, c.addOperationRevokeOAuth2TokenWithIAMMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*RevokeOAuth2TokenWithIAMOutput) + out.ResultMetadata = metadata + return out, nil +} + +// Input structure for RevokeOAuth2TokenWithIAM operation +// +// RFC 7009 §2.1 revocation request. Contains the refresh_token to revoke. +type RevokeOAuth2TokenWithIAMInput struct { + + // The refresh_token to revoke. Must be a refresh_token issued by AWS Sign-In + // (prefix "ASOR"); access_tokens are not accepted for revocation. + // + // This member is required. + Token *string + + noSmithyDocumentSerde +} + +func (in *RevokeOAuth2TokenWithIAMInput) bindEndpointParams(p *EndpointParameters) { + + p.IsOAuthEndpoint = ptr.Bool(true) +} + +// Output structure for RevokeOAuth2TokenWithIAM operation +// +// RFC 7009 §2.2 revocation response. The endpoint returns 200 OK with an empty +// body on success; there are no response fields. +type RevokeOAuth2TokenWithIAMOutput struct { + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationRevokeOAuth2TokenWithIAMMiddlewares(stack *middleware.Stack, options Options) (err error) { + err = stack.Serialize.Add(&awsRestjson1_serializeOpRevokeOAuth2TokenWithIAM{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsRestjson1_deserializeOpRevokeOAuth2TokenWithIAM{}, middleware.After) + if err != nil { + return err + } + + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpRevokeOAuth2TokenWithIAMValidationMiddleware(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go index 12208eaafaa..cc6b07d95cc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go @@ -34,15 +34,18 @@ func (m *awsRestjson1_deserializeOpCreateOAuth2Token) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorCreateOAuth2Token(response, &metadata) } @@ -180,14 +183,14 @@ func awsRestjson1_deserializeOpDocumentCreateOAuth2TokenOutput(v **CreateOAuth2T return nil } -type awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration struct { +type awsRestjson1_deserializeOpCreateOAuth2TokenWithIAM struct { } -func (*awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration) ID() string { +func (*awsRestjson1_deserializeOpCreateOAuth2TokenWithIAM) ID() string { return "OperationDeserializer" } -func (m *awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( +func (m *awsRestjson1_deserializeOpCreateOAuth2TokenWithIAM) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) @@ -195,15 +198,208 @@ func (m *awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration) Hand return out, metadata, err } + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + _, span := tracing.StartSpan(ctx, "OperationDeserializer") endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") defer endTimer() defer span.End() + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsRestjson1_deserializeOpErrorCreateOAuth2TokenWithIAM(response, &metadata) + } + output := &CreateOAuth2TokenWithIAMOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(response.Body, ringBuffer) + + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + err = awsRestjson1_deserializeOpDocumentCreateOAuth2TokenWithIAMOutput(&output, shape) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + span.End() + return out, metadata, err +} + +func awsRestjson1_deserializeOpErrorCreateOAuth2TokenWithIAM(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) + } + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + jsonCode, message, err := restjson.GetErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) + } + if len(message) != 0 { + errorMessage = message + } + + switch { + case strings.EqualFold("AccessDeniedException", errorCode): + return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody) + + case strings.EqualFold("InternalServerException", errorCode): + return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) + + case strings.EqualFold("TooManyRequestsError", errorCode): + return awsRestjson1_deserializeErrorTooManyRequestsError(response, errorBody) + + case strings.EqualFold("ValidationException", errorCode): + return awsRestjson1_deserializeErrorValidationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + +func awsRestjson1_deserializeOpDocumentCreateOAuth2TokenWithIAMOutput(v **CreateOAuth2TokenWithIAMOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *CreateOAuth2TokenWithIAMOutput + if *v == nil { + sv = &CreateOAuth2TokenWithIAMOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "access_token": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected OAuthAccessToken to be of type string, got %T instead", value) + } + sv.AccessToken = ptr.String(jtv) + } + + case "expires_in": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected TokenExpiresIn to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.ExpiresIn = ptr.Int32(int32(i64)) + } + + case "token_type": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected BearerTokenType to be of type string, got %T instead", value) + } + sv.TokenType = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +type awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration struct { +} + +func (*awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration) ID() string { + return "OperationDeserializer" +} + +func (m *awsRestjson1_deserializeOpDeleteConsoleAuthorizationConfiguration) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorDeleteConsoleAuthorizationConfiguration(response, &metadata) } @@ -381,15 +577,18 @@ func (m *awsRestjson1_deserializeOpDeleteResourcePermissionStatement) HandleDese return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorDeleteResourcePermissionStatement(response, &metadata) } @@ -481,15 +680,18 @@ func (m *awsRestjson1_deserializeOpGetConsoleAuthorizationConfiguration) HandleD return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorGetConsoleAuthorizationConfiguration(response, &metadata) } @@ -667,15 +869,18 @@ func (m *awsRestjson1_deserializeOpGetResourcePolicy) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorGetResourcePolicy(response, &metadata) } @@ -813,14 +1018,14 @@ func awsRestjson1_deserializeOpDocumentGetResourcePolicyOutput(v **GetResourcePo return nil } -type awsRestjson1_deserializeOpListResourcePermissionStatements struct { +type awsRestjson1_deserializeOpIntrospectOAuth2TokenWithIAM struct { } -func (*awsRestjson1_deserializeOpListResourcePermissionStatements) ID() string { +func (*awsRestjson1_deserializeOpIntrospectOAuth2TokenWithIAM) ID() string { return "OperationDeserializer" } -func (m *awsRestjson1_deserializeOpListResourcePermissionStatements) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( +func (m *awsRestjson1_deserializeOpIntrospectOAuth2TokenWithIAM) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) @@ -828,19 +1033,22 @@ func (m *awsRestjson1_deserializeOpListResourcePermissionStatements) HandleDeser return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorListResourcePermissionStatements(response, &metadata) + return out, metadata, awsRestjson1_deserializeOpErrorIntrospectOAuth2TokenWithIAM(response, &metadata) } - output := &ListResourcePermissionStatementsOutput{} + output := &IntrospectOAuth2TokenWithIAMOutput{} out.Result = output var buff [1024]byte @@ -861,7 +1069,7 @@ func (m *awsRestjson1_deserializeOpListResourcePermissionStatements) HandleDeser return out, metadata, err } - err = awsRestjson1_deserializeOpDocumentListResourcePermissionStatementsOutput(&output, shape) + err = awsRestjson1_deserializeOpDocumentIntrospectOAuth2TokenWithIAMOutput(&output, shape) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -875,7 +1083,7 @@ func (m *awsRestjson1_deserializeOpListResourcePermissionStatements) HandleDeser return out, metadata, err } -func awsRestjson1_deserializeOpErrorListResourcePermissionStatements(response *smithyhttp.Response, metadata *middleware.Metadata) error { +func awsRestjson1_deserializeOpErrorIntrospectOAuth2TokenWithIAM(response *smithyhttp.Response, metadata *middleware.Metadata) error { var errorBuffer bytes.Buffer if _, err := io.Copy(&errorBuffer, response.Body); err != nil { return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} @@ -922,9 +1130,6 @@ func awsRestjson1_deserializeOpErrorListResourcePermissionStatements(response *s case strings.EqualFold("InternalServerException", errorCode): return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) - case strings.EqualFold("ResourceNotFoundException", errorCode): - return awsRestjson1_deserializeErrorResourceNotFoundException(response, errorBody) - case strings.EqualFold("TooManyRequestsError", errorCode): return awsRestjson1_deserializeErrorTooManyRequestsError(response, errorBody) @@ -941,7 +1146,7 @@ func awsRestjson1_deserializeOpErrorListResourcePermissionStatements(response *s } } -func awsRestjson1_deserializeOpDocumentListResourcePermissionStatementsOutput(v **ListResourcePermissionStatementsOutput, value interface{}) error { +func awsRestjson1_deserializeOpDocumentIntrospectOAuth2TokenWithIAMOutput(v **IntrospectOAuth2TokenWithIAMOutput, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -954,31 +1159,155 @@ func awsRestjson1_deserializeOpDocumentListResourcePermissionStatementsOutput(v return fmt.Errorf("unexpected JSON type %v", value) } - var sv *ListResourcePermissionStatementsOutput + var sv *IntrospectOAuth2TokenWithIAMOutput if *v == nil { - sv = &ListResourcePermissionStatementsOutput{} + sv = &IntrospectOAuth2TokenWithIAMOutput{} } else { sv = *v } for key, value := range shape { switch key { - case "nextToken": + case "account_id": if value != nil { jtv, ok := value.(string) if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) + return fmt.Errorf("expected AccountId to be of type string, got %T instead", value) } - sv.NextToken = ptr.String(jtv) + sv.AccountId = ptr.String(jtv) } - case "permissionStatements": - if err := awsRestjson1_deserializeDocumentPermissionStatementSummaries(&sv.PermissionStatements, value); err != nil { - return err + case "active": + if value != nil { + jtv, ok := value.(bool) + if !ok { + return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) + } + sv.Active = ptr.Bool(jtv) } - default: - _, _ = key, value + case "aud": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Aud = ptr.String(jtv) + } + + case "client_id": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.ClientId = ptr.String(jtv) + } + + case "exp": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected Long to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.Exp = ptr.Int64(i64) + } + + case "iat": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected Long to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.Iat = ptr.Int64(i64) + } + + case "iss": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Iss = ptr.String(jtv) + } + + case "jti": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Jti = ptr.String(jtv) + } + + case "nbf": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected Long to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.Nbf = ptr.Int64(i64) + } + + case "resource": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Resource = ptr.String(jtv) + } + + case "signin_session": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.SigninSession = ptr.String(jtv) + } + + case "sub": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Sub = ptr.String(jtv) + } + + case "token_type": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected IntrospectedTokenType to be of type string, got %T instead", value) + } + sv.TokenType = ptr.String(jtv) + } + + case "user_id": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.UserId = ptr.String(jtv) + } + + default: + _, _ = key, value } } @@ -986,14 +1315,14 @@ func awsRestjson1_deserializeOpDocumentListResourcePermissionStatementsOutput(v return nil } -type awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration struct { +type awsRestjson1_deserializeOpListResourcePermissionStatements struct { } -func (*awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration) ID() string { +func (*awsRestjson1_deserializeOpListResourcePermissionStatements) ID() string { return "OperationDeserializer" } -func (m *awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( +func (m *awsRestjson1_deserializeOpListResourcePermissionStatements) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) @@ -1001,15 +1330,194 @@ func (m *awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration) HandleD return out, metadata, err } + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + _, span := tracing.StartSpan(ctx, "OperationDeserializer") endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") defer endTimer() defer span.End() + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsRestjson1_deserializeOpErrorListResourcePermissionStatements(response, &metadata) + } + output := &ListResourcePermissionStatementsOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(response.Body, ringBuffer) + + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + err = awsRestjson1_deserializeOpDocumentListResourcePermissionStatementsOutput(&output, shape) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + span.End() + return out, metadata, err +} + +func awsRestjson1_deserializeOpErrorListResourcePermissionStatements(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) + } + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + jsonCode, message, err := restjson.GetErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) + } + if len(message) != 0 { + errorMessage = message + } + + switch { + case strings.EqualFold("AccessDeniedException", errorCode): + return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody) + + case strings.EqualFold("InternalServerException", errorCode): + return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) + + case strings.EqualFold("ResourceNotFoundException", errorCode): + return awsRestjson1_deserializeErrorResourceNotFoundException(response, errorBody) + + case strings.EqualFold("TooManyRequestsError", errorCode): + return awsRestjson1_deserializeErrorTooManyRequestsError(response, errorBody) + + case strings.EqualFold("ValidationException", errorCode): + return awsRestjson1_deserializeErrorValidationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + +func awsRestjson1_deserializeOpDocumentListResourcePermissionStatementsOutput(v **ListResourcePermissionStatementsOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *ListResourcePermissionStatementsOutput + if *v == nil { + sv = &ListResourcePermissionStatementsOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "nextToken": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) + } + sv.NextToken = ptr.String(jtv) + } + + case "permissionStatements": + if err := awsRestjson1_deserializeDocumentPermissionStatementSummaries(&sv.PermissionStatements, value); err != nil { + return err + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +type awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration struct { +} + +func (*awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration) ID() string { + return "OperationDeserializer" +} + +func (m *awsRestjson1_deserializeOpPutConsoleAuthorizationConfiguration) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorPutConsoleAuthorizationConfiguration(response, &metadata) } @@ -1190,15 +1698,18 @@ func (m *awsRestjson1_deserializeOpPutResourcePermissionStatement) HandleDeseria return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorPutResourcePermissionStatement(response, &metadata) } @@ -1346,6 +1857,106 @@ func awsRestjson1_deserializeOpDocumentPutResourcePermissionStatementOutput(v ** return nil } +type awsRestjson1_deserializeOpRevokeOAuth2TokenWithIAM struct { +} + +func (*awsRestjson1_deserializeOpRevokeOAuth2TokenWithIAM) ID() string { + return "OperationDeserializer" +} + +func (m *awsRestjson1_deserializeOpRevokeOAuth2TokenWithIAM) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsRestjson1_deserializeOpErrorRevokeOAuth2TokenWithIAM(response, &metadata) + } + output := &RevokeOAuth2TokenWithIAMOutput{} + out.Result = output + + span.End() + return out, metadata, err +} + +func awsRestjson1_deserializeOpErrorRevokeOAuth2TokenWithIAM(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) + } + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + jsonCode, message, err := restjson.GetErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) + } + if len(message) != 0 { + errorMessage = message + } + + switch { + case strings.EqualFold("AccessDeniedException", errorCode): + return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody) + + case strings.EqualFold("InternalServerException", errorCode): + return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) + + case strings.EqualFold("TooManyRequestsError", errorCode): + return awsRestjson1_deserializeErrorTooManyRequestsError(response, errorBody) + + case strings.EqualFold("ValidationException", errorCode): + return awsRestjson1_deserializeErrorValidationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + func awsRestjson1_deserializeErrorAccessDeniedException(response *smithyhttp.Response, errorBody *bytes.Reader) error { output := &types.AccessDeniedException{} var buff [1024]byte diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go index 16944632691..52c68b3570a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go @@ -276,6 +276,12 @@ type EndpointParameters struct { // Parameter is // required. IsControlPlane *bool + + // Indicates if the operation targets the OAuth token endpoint + // + // Parameter is + // required. + IsOAuthEndpoint *bool } // ValidateRequired validates required parameters are set. @@ -306,8 +312,8 @@ func (p EndpointParameters) WithDefaults() EndpointParameters { const bddRoot int32 = 2 -var bddNodes = [99]int32{ - -1, 1, -1, 0, 4, 3, 2, 30, 100000025, 1, 24, 5, 2, 30, 6, 3, 7, 26, 4, 18, 8, 5, 17, 9, 6, 100000004, 10, 7, 100000005, 11, 10, 100000006, 12, 12, 100000007, 13, 13, 100000008, 14, 14, 100000009, 15, 15, 100000010, 16, 16, 100000011, 100000014, 8, 100000022, 100000023, 5, 22, 19, 9, 100000012, 20, 10, 100000013, 21, 11, 100000020, 100000021, 8, 23, 100000019, 11, 100000018, 100000019, 2, 29, 25, 3, 32, 26, 4, 27, 100000025, 5, 100000025, 28, 9, 100000012, 100000025, 3, 32, 30, 4, 100000015, 31, 5, 100000016, 100000017, 6, 100000001, 33, 7, 100000002, 100000003} +var bddNodes = [120]int32{ + -1, 1, -1, 0, 6, 3, 2, 36, 4, 4, 5, 100000027, 6, 100000004, 100000027, 1, 29, 7, 2, 36, 8, 3, 9, 31, 4, 22, 10, 5, 19, 11, 7, 21, 12, 8, 100000007, 13, 10, 100000008, 14, 12, 100000009, 15, 13, 100000010, 16, 14, 100000011, 17, 15, 100000012, 18, 16, 100000013, 100000016, 6, 100000005, 20, 7, 21, 100000006, 17, 100000024, 100000025, 6, 100000004, 23, 7, 27, 24, 9, 100000014, 25, 10, 100000015, 26, 11, 100000022, 100000023, 11, 28, 100000021, 17, 100000020, 100000021, 2, 35, 30, 3, 39, 31, 4, 32, 100000027, 6, 100000004, 33, 7, 100000027, 34, 9, 100000014, 100000027, 3, 39, 36, 4, 38, 37, 7, 100000018, 100000019, 6, 100000004, 100000017, 5, 100000001, 40, 8, 100000002, 100000003} type conditionContext struct { PartitionResult *awsrulesfn.PartitionConfig @@ -335,13 +341,18 @@ func evalCondition(idx int, params *EndpointParameters, c *conditionContext) boo case 4: return *params.UseFIPS == true case 5: - return *params.UseDualStack == true - case 6: return c.PartitionResult.Name == "aws" + case 6: + return func() bool { + if v := params.IsOAuthEndpoint; v != nil { + return *v + } + return false + }() == true case 7: - return c.PartitionResult.Name == "aws-cn" + return *params.UseDualStack == true case 8: - return c.PartitionResult.SupportsDualStack == true + return c.PartitionResult.Name == "aws-cn" case 9: return *params.Region == "us-gov-west-1" case 10: @@ -358,6 +369,8 @@ func evalCondition(idx int, params *EndpointParameters, c *conditionContext) boo return c.PartitionResult.Name == "aws-iso-e" case 16: return c.PartitionResult.Name == "aws-eusc" + case 17: + return c.PartitionResult.SupportsDualStack == true } return false } @@ -467,6 +480,41 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( }(), }, nil case 4: + return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "FIPS endpoints are not supported for OAuth operations. Disable FIPS or use a non-OAuth operation.") + case 5: + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(*params.Region) + out.WriteString(".oauth.signin.aws") + return out.String() + }() + uri, err := url.Parse(uriString) + if err != nil { + return smithyendpoints.Endpoint{}, fmt.Errorf("Failed to parse uri: %s", uriString) + } + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + Properties: func() smithy.Properties { + var out smithy.Properties + smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ + { + SchemeID: "sigv4", + SignerProperties: func() smithy.Properties { + var sp smithy.Properties + smithyhttp.SetSigV4SigningName(&sp, "signin") + smithyhttp.SetSigV4ASigningName(&sp, "signin") + + smithyhttp.SetSigV4SigningRegion(&sp, *params.Region) + return sp + }(), + }, + }) + return out + }(), + }, nil + case 6: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -482,7 +530,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 5: + case 7: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -498,7 +546,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 6: + case 8: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -514,7 +562,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 7: + case 9: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -530,7 +578,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 8: + case 10: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -546,7 +594,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 9: + case 11: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -562,7 +610,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 10: + case 12: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -578,7 +626,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 11: + case 13: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -594,7 +642,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 12: + case 14: uriString := "https://signin-fips.amazonaws-us-gov.com" uri, err := url.Parse(uriString) if err != nil { @@ -604,7 +652,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 13: + case 15: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -620,7 +668,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 14: + case 16: uriString := func() string { var out strings.Builder out.WriteString("https://") @@ -637,11 +685,11 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 15: + case 17: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") - case 16: + case 18: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") - case 17: + case 19: uriString := *params.Endpoint uri, err := url.Parse(uriString) if err != nil { @@ -651,7 +699,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 18: + case 20: uriString := func() string { var out strings.Builder out.WriteString("https://signin-fips.") @@ -668,9 +716,9 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 19: + case 21: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") - case 20: + case 22: uriString := func() string { var out strings.Builder out.WriteString("https://signin-fips.") @@ -687,9 +735,9 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 21: + case 23: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") - case 22: + case 24: uriString := func() string { var out strings.Builder out.WriteString("https://signin.") @@ -706,9 +754,9 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 23: + case 25: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") - case 24: + case 26: uriString := func() string { var out strings.Builder out.WriteString("https://signin.") @@ -725,7 +773,7 @@ func resolveResult(idx int32, params *EndpointParameters, c *conditionContext) ( URI: *uri, Headers: http.Header{}, }, nil - case 25: + case 27: return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") } return smithyendpoints.Endpoint{}, fmt.Errorf("endpoint rule error, invalid result index: %d", idx) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json index 4965af44178..762cc709c93 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json @@ -9,13 +9,16 @@ "api_client.go", "api_client_test.go", "api_op_CreateOAuth2Token.go", + "api_op_CreateOAuth2TokenWithIAM.go", "api_op_DeleteConsoleAuthorizationConfiguration.go", "api_op_DeleteResourcePermissionStatement.go", "api_op_GetConsoleAuthorizationConfiguration.go", "api_op_GetResourcePolicy.go", + "api_op_IntrospectOAuth2TokenWithIAM.go", "api_op_ListResourcePermissionStatements.go", "api_op_PutConsoleAuthorizationConfiguration.go", "api_op_PutResourcePermissionStatement.go", + "api_op_RevokeOAuth2TokenWithIAM.go", "auth.go", "deserializers.go", "doc.go", @@ -26,6 +29,8 @@ "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", "options.go", + "request_snapshot_test.go", + "response_snapshot_test.go", "serializers.go", "snapshot_test.go", "sra_operation_order_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go index 685df38e364..b4c425dbbb3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go @@ -3,4 +3,4 @@ package signin // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.2.1" +const goModuleVersion = "1.7.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go index 551d20c28cd..9b7248ff303 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go @@ -44,6 +44,11 @@ type Options struct { // clients initial default settings. DefaultsMode aws.DefaultsMode + // Disables SDK clock skew correction. When set, the SDK will not adjust request + // signing timestamps to compensate for clock drift between the client and the + // service. + DisableClockSkewCorrection bool + // The endpoint options to be used when attempting to resolve an endpoint. EndpointOptions EndpointResolverOptions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go index fe87e71f886..d245732cccd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go @@ -97,6 +97,92 @@ func awsRestjson1_serializeOpHttpBindingsCreateOAuth2TokenInput(v *CreateOAuth2T return nil } +type awsRestjson1_serializeOpCreateOAuth2TokenWithIAM struct { +} + +func (*awsRestjson1_serializeOpCreateOAuth2TokenWithIAM) ID() string { + return "OperationSerializer" +} + +func (m *awsRestjson1_serializeOpCreateOAuth2TokenWithIAM) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*CreateOAuth2TokenWithIAMInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + opPath, opQuery := httpbinding.SplitURI("/v1/token?x-amz-client-auth-method=iam") + request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) + request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) + request.Method = "POST" + var restEncoder *httpbinding.Encoder + if request.URL.RawPath == "" { + restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + } else { + request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) + restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) + } + + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + restEncoder.SetHeader("Content-Type").String("application/json") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsRestjson1_serializeOpDocumentCreateOAuth2TokenWithIAMInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = restEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} +func awsRestjson1_serializeOpHttpBindingsCreateOAuth2TokenWithIAMInput(v *CreateOAuth2TokenWithIAMInput, encoder *httpbinding.Encoder) error { + if v == nil { + return fmt.Errorf("unsupported serialization of nil %T", v) + } + + return nil +} + +func awsRestjson1_serializeOpDocumentCreateOAuth2TokenWithIAMInput(v *CreateOAuth2TokenWithIAMInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.GrantType != nil { + ok := object.Key("grant_type") + ok.String(*v.GrantType) + } + + if v.Resource != nil { + ok := object.Key("resource") + ok.String(*v.Resource) + } + + return nil +} + type awsRestjson1_serializeOpDeleteConsoleAuthorizationConfiguration struct { } @@ -403,6 +489,92 @@ func awsRestjson1_serializeOpHttpBindingsGetResourcePolicyInput(v *GetResourcePo return nil } +type awsRestjson1_serializeOpIntrospectOAuth2TokenWithIAM struct { +} + +func (*awsRestjson1_serializeOpIntrospectOAuth2TokenWithIAM) ID() string { + return "OperationSerializer" +} + +func (m *awsRestjson1_serializeOpIntrospectOAuth2TokenWithIAM) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*IntrospectOAuth2TokenWithIAMInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + opPath, opQuery := httpbinding.SplitURI("/v1/introspect?x-amz-client-auth-method=iam") + request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) + request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) + request.Method = "POST" + var restEncoder *httpbinding.Encoder + if request.URL.RawPath == "" { + restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + } else { + request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) + restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) + } + + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + restEncoder.SetHeader("Content-Type").String("application/json") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsRestjson1_serializeOpDocumentIntrospectOAuth2TokenWithIAMInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = restEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} +func awsRestjson1_serializeOpHttpBindingsIntrospectOAuth2TokenWithIAMInput(v *IntrospectOAuth2TokenWithIAMInput, encoder *httpbinding.Encoder) error { + if v == nil { + return fmt.Errorf("unsupported serialization of nil %T", v) + } + + return nil +} + +func awsRestjson1_serializeOpDocumentIntrospectOAuth2TokenWithIAMInput(v *IntrospectOAuth2TokenWithIAMInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Token != nil { + ok := object.Key("token") + ok.String(*v.Token) + } + + if v.TokenTypeHint != nil { + ok := object.Key("token_type_hint") + ok.String(*v.TokenTypeHint) + } + + return nil +} + type awsRestjson1_serializeOpListResourcePermissionStatements struct { } @@ -686,6 +858,87 @@ func awsRestjson1_serializeOpDocumentPutResourcePermissionStatementInput(v *PutR return nil } +type awsRestjson1_serializeOpRevokeOAuth2TokenWithIAM struct { +} + +func (*awsRestjson1_serializeOpRevokeOAuth2TokenWithIAM) ID() string { + return "OperationSerializer" +} + +func (m *awsRestjson1_serializeOpRevokeOAuth2TokenWithIAM) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*RevokeOAuth2TokenWithIAMInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + opPath, opQuery := httpbinding.SplitURI("/v1/revoke?x-amz-client-auth-method=iam") + request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) + request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) + request.Method = "POST" + var restEncoder *httpbinding.Encoder + if request.URL.RawPath == "" { + restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + } else { + request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) + restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) + } + + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + restEncoder.SetHeader("Content-Type").String("application/json") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsRestjson1_serializeOpDocumentRevokeOAuth2TokenWithIAMInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = restEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} +func awsRestjson1_serializeOpHttpBindingsRevokeOAuth2TokenWithIAMInput(v *RevokeOAuth2TokenWithIAMInput, encoder *httpbinding.Encoder) error { + if v == nil { + return fmt.Errorf("unsupported serialization of nil %T", v) + } + + return nil +} + +func awsRestjson1_serializeOpDocumentRevokeOAuth2TokenWithIAMInput(v *RevokeOAuth2TokenWithIAMInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Token != nil { + ok := object.Key("token") + ok.String(*v.Token) + } + + return nil +} + func awsRestjson1_serializeDocumentCreateOAuth2TokenRequestBody(v *types.CreateOAuth2TokenRequestBody, value smithyjson.Value) error { object := value.Object() defer object.Close() diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go index aa4f7ecbe40..9e8bab7577c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go @@ -8,9 +8,7 @@ import ( // AWS credentials structure containing temporary access credentials // -// The scoped-down, 15 minute duration AWS credentials. Scoping down will be based -// on CLI policy (CLI team needs to create it). Similar to cloud shell -// implementation. +// Scoped, temporary AWS credentials with a 15-minute duration. type AccessToken struct { // AWS access key ID for temporary credentials diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go index 8570cc5dbb5..8049ca28508 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go @@ -30,6 +30,26 @@ func (m *validateOpCreateOAuth2Token) HandleInitialize(ctx context.Context, in m return next.HandleInitialize(ctx, in) } +type validateOpCreateOAuth2TokenWithIAM struct { +} + +func (*validateOpCreateOAuth2TokenWithIAM) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpCreateOAuth2TokenWithIAM) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*CreateOAuth2TokenWithIAMInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpCreateOAuth2TokenWithIAMInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + type validateOpDeleteResourcePermissionStatement struct { } @@ -50,14 +70,66 @@ func (m *validateOpDeleteResourcePermissionStatement) HandleInitialize(ctx conte return next.HandleInitialize(ctx, in) } +type validateOpIntrospectOAuth2TokenWithIAM struct { +} + +func (*validateOpIntrospectOAuth2TokenWithIAM) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpIntrospectOAuth2TokenWithIAM) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*IntrospectOAuth2TokenWithIAMInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpIntrospectOAuth2TokenWithIAMInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + +type validateOpRevokeOAuth2TokenWithIAM struct { +} + +func (*validateOpRevokeOAuth2TokenWithIAM) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpRevokeOAuth2TokenWithIAM) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*RevokeOAuth2TokenWithIAMInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpRevokeOAuth2TokenWithIAMInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + func addOpCreateOAuth2TokenValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpCreateOAuth2Token{}, middleware.After) } +func addOpCreateOAuth2TokenWithIAMValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpCreateOAuth2TokenWithIAM{}, middleware.After) +} + func addOpDeleteResourcePermissionStatementValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpDeleteResourcePermissionStatement{}, middleware.After) } +func addOpIntrospectOAuth2TokenWithIAMValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpIntrospectOAuth2TokenWithIAM{}, middleware.After) +} + +func addOpRevokeOAuth2TokenWithIAMValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpRevokeOAuth2TokenWithIAM{}, middleware.After) +} + func validateCreateOAuth2TokenRequestBody(v *types.CreateOAuth2TokenRequestBody) error { if v == nil { return nil @@ -95,6 +167,24 @@ func validateOpCreateOAuth2TokenInput(v *CreateOAuth2TokenInput) error { } } +func validateOpCreateOAuth2TokenWithIAMInput(v *CreateOAuth2TokenWithIAMInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "CreateOAuth2TokenWithIAMInput"} + if v.GrantType == nil { + invalidParams.Add(smithy.NewErrParamRequired("GrantType")) + } + if v.Resource == nil { + invalidParams.Add(smithy.NewErrParamRequired("Resource")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateOpDeleteResourcePermissionStatementInput(v *DeleteResourcePermissionStatementInput) error { if v == nil { return nil @@ -109,3 +199,33 @@ func validateOpDeleteResourcePermissionStatementInput(v *DeleteResourcePermissio return nil } } + +func validateOpIntrospectOAuth2TokenWithIAMInput(v *IntrospectOAuth2TokenWithIAMInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "IntrospectOAuth2TokenWithIAMInput"} + if v.Token == nil { + invalidParams.Add(smithy.NewErrParamRequired("Token")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateOpRevokeOAuth2TokenWithIAMInput(v *RevokeOAuth2TokenWithIAMInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "RevokeOAuth2TokenWithIAMInput"} + if v.Token == nil { + invalidParams.Add(smithy.NewErrParamRequired("Token")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md index c15b7e19da8..9581729dbab 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md @@ -1,3 +1,73 @@ +# v1.35.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.0 (2026-08-26) + +* **Feature**: Stop registering the `ComputeContentLength` middleware in generated clients. `Content-Length` is now set when the request body is set via `SetStream`. +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.8 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.7 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.6 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.5 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.4 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.3 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.33.2 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.1 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.0 (2026-07-21) + +* **Feature**: Add an option to clients to disable clock skew +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.1 (2026-07-13) + +* No change notes available for this release. + +# v1.32.0 (2026-07-06) + +* **Feature**: Add request serialization snapshot tests. + +# v1.31.5 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.31.4 (2026-06-29) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go index 127944307d2..429e9469f1d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go @@ -15,6 +15,7 @@ import ( internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/timeouts" smithy "github.com/aws/smithy-go" smithydocument "github.com/aws/smithy-go/document" "github.com/aws/smithy-go/logging" @@ -259,6 +260,10 @@ func (c *Client) invokeOperation( finalizeClientEndpointResolverOptions(&options) + ctx = setLoggerContext(ctx, options, opID) + + ctx = resolveServiceMetadata(ctx, options, opID) + if err := c.addCommonMiddlewares(stack, options, opID); err != nil { return nil, metadata, err } @@ -375,9 +380,6 @@ func (c *Client) addCommonMiddlewares(stack *middleware.Stack, options Options, if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { return fmt.Errorf("add protocol finalizers: %v", err) } - if err := addSetLoggerMiddleware(stack, options); err != nil { - return err - } if err := addClientRequestID(stack); err != nil { return err } @@ -430,30 +432,6 @@ func resolveAuthSchemes(options *Options) { type noSmithyDocumentSerde = smithydocument.NoSerde -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -461,8 +439,9 @@ func resolveDefaultLogger(o *Options) { o.Logger = logging.Nop{} } -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) +func setLoggerContext(ctx context.Context, options Options, operation string) context.Context { + _ = operation + return middleware.SetLogger(ctx, options.Logger) } func setResolvedDefaultsMode(o *Options) { @@ -483,16 +462,17 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - AuthSchemePreference: cfg.AuthSchemePreference, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + DisableClockSkewCorrection: cfg.DisableClockSkewCorrection, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -540,6 +520,12 @@ func resolveHTTPClient(o *Options) { }) } + if _, ok := buildable.GetReadTimeout(); !ok { + if timeout, ok := timeouts.GetServiceReadTimeout(ServiceID); ok { + buildable = buildable.WithReadTimeout(timeout) + } + } + o.HTTPClient = buildable } @@ -681,16 +667,14 @@ func addClientRequestID(stack *middleware.Stack) error { return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) } -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Insert(&smithyhttp.ComputeContentLength{}, "ClientRequestID", middleware.After) -} - func addRawResponseToMetadata(stack *middleware.Stack) error { return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) } -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +func addRecordResponseTiming(stack *middleware.Stack, options Options) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{ + DisableClockSkewCorrection: options.DisableClockSkewCorrection, + }, middleware.After) } func addSpanRetryLoop(stack *middleware.Stack, options Options) error { @@ -761,6 +745,7 @@ func addRetry(stack *middleware.Stack, o Options, c *Client) error { m.LogAttempts = o.ClientLogMode.IsRetries() m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sso") m.ClientSkew = c.timeOffset + m.DisableClockSkewCorrection = o.DisableClockSkewCorrection }) if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { return err @@ -863,12 +848,16 @@ func resolveMeterProvider(options *Options) { } } -func newServiceMetadataMiddleware(region, operation string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: operation, +func resolveServiceMetadata(ctx context.Context, options Options, operation string) context.Context { + ctx = awsmiddleware.SetServiceID(ctx, ServiceID) + if options.Region != "" { + ctx = awsmiddleware.SetRegion(ctx, options.Region) + } + ctx = awsmiddleware.SetOperationName(ctx, operation) + if options.EndpointResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) } + return ctx } func addRecursionDetection(stack *middleware.Stack) error { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go index a6532c20f14..b26651c439d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sso/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the STS short-term credentials for a given role name that is assigned @@ -70,22 +69,10 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -94,9 +81,6 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta if err = addOpGetRoleCredentialsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetRoleCredentials"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go index b48097259ad..38fee5926c5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/sso/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Lists all roles that are assigned to the user for a given AWS account. @@ -76,22 +75,10 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -100,9 +87,6 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack if err = addOpListAccountRolesValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListAccountRoles"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go index 6142a5d39e9..342aa88e310 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/service/sso/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Lists all AWS accounts assigned to the user. These AWS accounts are assigned by @@ -75,22 +74,10 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -99,9 +86,6 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op if err = addOpListAccountsValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "ListAccounts"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go index ccafa26f4cf..44d1c57d5ac 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go @@ -5,7 +5,6 @@ package sso import ( "context" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Removes the locally stored SSO tokens from the client-side cache and sends an @@ -69,22 +68,10 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -93,9 +80,6 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options if err = addOpLogoutValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "Logout"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go index bfa1758c8a7..dbc691c49e8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go @@ -34,15 +34,18 @@ func (m *awsRestjson1_deserializeOpGetRoleCredentials) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorGetRoleCredentials(response, &metadata) } @@ -195,15 +198,18 @@ func (m *awsRestjson1_deserializeOpListAccountRoles) HandleDeserialize(ctx conte return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorListAccountRoles(response, &metadata) } @@ -365,15 +371,18 @@ func (m *awsRestjson1_deserializeOpListAccounts) HandleDeserialize(ctx context.C return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorListAccounts(response, &metadata) } @@ -535,15 +544,18 @@ func (m *awsRestjson1_deserializeOpLogout) HandleDeserialize(ctx context.Context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorLogout(response, &metadata) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json index 39a393d441c..7aca52b604f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json @@ -22,6 +22,8 @@ "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", "options.go", + "request_snapshot_test.go", + "response_snapshot_test.go", "serializers.go", "snapshot_test.go", "sra_operation_order_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go index 7bc725826c3..3020594029f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go @@ -3,4 +3,4 @@ package sso // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.31.4" +const goModuleVersion = "1.35.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go index 8b4e34d0642..fbe3ff2a2e2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go @@ -44,6 +44,11 @@ type Options struct { // clients initial default settings. DefaultsMode aws.DefaultsMode + // Disables SDK clock skew correction. When set, the SDK will not adjust request + // signing timestamps to compensate for clock drift between the client and the + // service. + DisableClockSkewCorrection bool + // The endpoint options to be used when attempting to resolve an endpoint. EndpointOptions EndpointResolverOptions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md index f0bac803b8a..94d1c67ddda 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md @@ -1,3 +1,73 @@ +# v1.40.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.40.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.39.0 (2026-08-26) + +* **Feature**: Stop registering the `ComputeContentLength` middleware in generated clients. `Content-Length` is now set when the request body is set via `SetStream`. +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.8 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.7 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.6 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.5 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.4 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.3 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.38.2 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.1 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.0 (2026-07-21) + +* **Feature**: Add an option to clients to disable clock skew +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.1 (2026-07-13) + +* No change notes available for this release. + +# v1.37.0 (2026-07-06) + +* **Feature**: Add request serialization snapshot tests. + +# v1.36.8 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.36.7 (2026-06-29) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go index ebdaff6e62e..c9b79402871 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go @@ -15,6 +15,7 @@ import ( internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/timeouts" smithy "github.com/aws/smithy-go" smithydocument "github.com/aws/smithy-go/document" "github.com/aws/smithy-go/logging" @@ -259,6 +260,10 @@ func (c *Client) invokeOperation( finalizeClientEndpointResolverOptions(&options) + ctx = setLoggerContext(ctx, options, opID) + + ctx = resolveServiceMetadata(ctx, options, opID) + if err := c.addCommonMiddlewares(stack, options, opID); err != nil { return nil, metadata, err } @@ -375,9 +380,6 @@ func (c *Client) addCommonMiddlewares(stack *middleware.Stack, options Options, if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { return fmt.Errorf("add protocol finalizers: %v", err) } - if err := addSetLoggerMiddleware(stack, options); err != nil { - return err - } if err := addClientRequestID(stack); err != nil { return err } @@ -430,30 +432,6 @@ func resolveAuthSchemes(options *Options) { type noSmithyDocumentSerde = smithydocument.NoSerde -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -461,8 +439,9 @@ func resolveDefaultLogger(o *Options) { o.Logger = logging.Nop{} } -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) +func setLoggerContext(ctx context.Context, options Options, operation string) context.Context { + _ = operation + return middleware.SetLogger(ctx, options.Logger) } func setResolvedDefaultsMode(o *Options) { @@ -483,16 +462,17 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - AuthSchemePreference: cfg.AuthSchemePreference, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + DisableClockSkewCorrection: cfg.DisableClockSkewCorrection, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -540,6 +520,12 @@ func resolveHTTPClient(o *Options) { }) } + if _, ok := buildable.GetReadTimeout(); !ok { + if timeout, ok := timeouts.GetServiceReadTimeout(ServiceID); ok { + buildable = buildable.WithReadTimeout(timeout) + } + } + o.HTTPClient = buildable } @@ -681,16 +667,14 @@ func addClientRequestID(stack *middleware.Stack) error { return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) } -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Insert(&smithyhttp.ComputeContentLength{}, "ClientRequestID", middleware.After) -} - func addRawResponseToMetadata(stack *middleware.Stack) error { return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) } -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +func addRecordResponseTiming(stack *middleware.Stack, options Options) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{ + DisableClockSkewCorrection: options.DisableClockSkewCorrection, + }, middleware.After) } func addSpanRetryLoop(stack *middleware.Stack, options Options) error { @@ -761,6 +745,7 @@ func addRetry(stack *middleware.Stack, o Options, c *Client) error { m.LogAttempts = o.ClientLogMode.IsRetries() m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc") m.ClientSkew = c.timeOffset + m.DisableClockSkewCorrection = o.DisableClockSkewCorrection }) if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { return err @@ -863,12 +848,16 @@ func resolveMeterProvider(options *Options) { } } -func newServiceMetadataMiddleware(region, operation string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: operation, +func resolveServiceMetadata(ctx context.Context, options Options, operation string) context.Context { + ctx = awsmiddleware.SetServiceID(ctx, ServiceID) + if options.Region != "" { + ctx = awsmiddleware.SetRegion(ctx, options.Region) + } + ctx = awsmiddleware.SetOperationName(ctx, operation) + if options.EndpointResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) } + return ctx } func addRecursionDetection(stack *middleware.Stack) error { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go index 5c1df1c088b..a770ccb54f5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go @@ -5,7 +5,6 @@ package ssooidc import ( "context" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates and returns access and refresh tokens for clients that are @@ -140,22 +139,10 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -164,9 +151,6 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt if err = addOpCreateTokenValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "CreateToken"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go index 088e7f2ec88..a7a7d761824 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/ssooidc/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Creates and returns access and refresh tokens for authorized client @@ -184,25 +183,13 @@ func (c *Client) addOperationCreateTokenWithIAMMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -211,9 +198,6 @@ func (c *Client) addOperationCreateTokenWithIAMMiddlewares(stack *middleware.Sta if err = addOpCreateTokenWithIAMValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "CreateTokenWithIAM"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go index 4632f365695..cdb1c3cfa9f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go @@ -5,7 +5,6 @@ package ssooidc import ( "context" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Registers a public client with IAM Identity Center. This allows clients to @@ -111,22 +110,10 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -135,9 +122,6 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, if err = addOpRegisterClientValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "RegisterClient"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go index 3417f8dbd33..3cec46e23aa 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go @@ -5,7 +5,6 @@ package ssooidc import ( "context" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Initiates device authorization by requesting a pair of verification codes from @@ -93,22 +92,10 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -117,9 +104,6 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa if err = addOpStartDeviceAuthorizationValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "StartDeviceAuthorization"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go index fb9a0df5194..da4a9e2f540 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go @@ -34,15 +34,18 @@ func (m *awsRestjson1_deserializeOpCreateToken) HandleDeserialize(ctx context.Co return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorCreateToken(response, &metadata) } @@ -260,15 +263,18 @@ func (m *awsRestjson1_deserializeOpCreateTokenWithIAM) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorCreateTokenWithIAM(response, &metadata) } @@ -508,15 +514,18 @@ func (m *awsRestjson1_deserializeOpRegisterClient) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorRegisterClient(response, &metadata) } @@ -735,15 +744,18 @@ func (m *awsRestjson1_deserializeOpStartDeviceAuthorization) HandleDeserialize(c return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsRestjson1_deserializeOpErrorStartDeviceAuthorization(response, &metadata) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json index 1e34b9a9d50..8f46b38d329 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json @@ -22,6 +22,8 @@ "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", "options.go", + "request_snapshot_test.go", + "response_snapshot_test.go", "serializers.go", "snapshot_test.go", "sra_operation_order_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go index d1f579cfae8..cb4d738d7d7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go @@ -3,4 +3,4 @@ package ssooidc // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.36.7" +const goModuleVersion = "1.40.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go index c2eac091904..73a47ccfb8c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go @@ -44,6 +44,11 @@ type Options struct { // clients initial default settings. DefaultsMode aws.DefaultsMode + // Disables SDK clock skew correction. When set, the SDK will not adjust request + // signing timestamps to compensate for clock drift between the client and the + // service. + DisableClockSkewCorrection bool + // The endpoint options to be used when attempting to resolve an endpoint. EndpointOptions EndpointResolverOptions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md index d0dbd1b80f9..ca18aed1c12 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md @@ -1,3 +1,73 @@ +# v1.47.1 (2026-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.47.0 (2026-08-27) + +* **Feature**: Support connection read timeouts in the SDK. This is currently available on an opt-in basis by setting env `AWS_ENABLE_DEFAULT_SOCKET_TIMEOUT_2026=true`. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.46.0 (2026-08-26) + +* **Feature**: Stop registering the `ComputeContentLength` middleware in generated clients. `Content-Length` is now set when the request body is set via `SetStream`. +* **Dependency Update**: Update to smithy-go v1.28.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.8 (2026-08-25) + +* **Dependency Update**: Update to smithy-go v1.27.10. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.7 (2026-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.6 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.5 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.4 (2026-08-05) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.3 (2026-07-31.2) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. + +# v1.45.2 (2026-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.1 (2026-07-28) + +* **Dependency Update**: Update to smithy-go v1.27.5. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.0 (2026-07-21) + +* **Feature**: Add an option to clients to disable clock skew +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.44.1 (2026-07-13) + +* No change notes available for this release. + +# v1.44.0 (2026-07-06) + +* **Feature**: Add request serialization snapshot tests. + +# v1.43.5 (2026-07-01) + +* **Bug Fix**: Bump smithy-go to 1.27.3, fix JSON encorder for document.Number, endpoint host label format validation and CBOR union serialization on new serde +* **Dependency Update**: Updated to the latest SDK module versions + # v1.43.4 (2026-06-29) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go index c0d927a0c8d..f599f824888 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go @@ -16,6 +16,7 @@ import ( internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/timeouts" "github.com/aws/aws-sdk-go-v2/internal/v4a" acceptencodingcust "github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding" presignedurlcust "github.com/aws/aws-sdk-go-v2/service/internal/presigned-url" @@ -268,6 +269,10 @@ func (c *Client) invokeOperation( finalizeClientEndpointResolverOptions(&options) + ctx = setLoggerContext(ctx, options, opID) + + ctx = resolveServiceMetadata(ctx, options, opID) + if err := c.addCommonMiddlewares(stack, options, opID); err != nil { return nil, metadata, err } @@ -384,9 +389,6 @@ func (c *Client) addCommonMiddlewares(stack *middleware.Stack, options Options, if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { return fmt.Errorf("add protocol finalizers: %v", err) } - if err := addSetLoggerMiddleware(stack, options); err != nil { - return err - } if err := addClientRequestID(stack); err != nil { return err } @@ -444,30 +446,6 @@ func resolveAuthSchemes(options *Options) { type noSmithyDocumentSerde = smithydocument.NoSerde -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -475,8 +453,9 @@ func resolveDefaultLogger(o *Options) { o.Logger = logging.Nop{} } -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) +func setLoggerContext(ctx context.Context, options Options, operation string) context.Context { + _ = operation + return middleware.SetLogger(ctx, options.Logger) } func setResolvedDefaultsMode(o *Options) { @@ -497,16 +476,17 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - AuthSchemePreference: cfg.AuthSchemePreference, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + DisableClockSkewCorrection: cfg.DisableClockSkewCorrection, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -554,6 +534,12 @@ func resolveHTTPClient(o *Options) { }) } + if _, ok := buildable.GetReadTimeout(); !ok { + if timeout, ok := timeouts.GetServiceReadTimeout(ServiceID); ok { + buildable = buildable.WithReadTimeout(timeout) + } + } + o.HTTPClient = buildable } @@ -695,16 +681,14 @@ func addClientRequestID(stack *middleware.Stack) error { return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) } -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Insert(&smithyhttp.ComputeContentLength{}, "ClientRequestID", middleware.After) -} - func addRawResponseToMetadata(stack *middleware.Stack) error { return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) } -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +func addRecordResponseTiming(stack *middleware.Stack, options Options) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{ + DisableClockSkewCorrection: options.DisableClockSkewCorrection, + }, middleware.After) } func addSpanRetryLoop(stack *middleware.Stack, options Options) error { @@ -775,6 +759,7 @@ func addRetry(stack *middleware.Stack, o Options, c *Client) error { m.LogAttempts = o.ClientLogMode.IsRetries() m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts") m.ClientSkew = c.timeOffset + m.DisableClockSkewCorrection = o.DisableClockSkewCorrection }) if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { return err @@ -901,12 +886,16 @@ func resolveMeterProvider(options *Options) { } } -func newServiceMetadataMiddleware(region, operation string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: operation, +func resolveServiceMetadata(ctx context.Context, options Options, operation string) context.Context { + ctx = awsmiddleware.SetServiceID(ctx, ServiceID) + if options.Region != "" { + ctx = awsmiddleware.SetRegion(ctx, options.Region) + } + ctx = awsmiddleware.SetOperationName(ctx, operation) + if options.EndpointResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) } + return ctx } func addRecursionDetection(stack *middleware.Stack) error { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go index a1c0534bc54..b1cd6756010 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a set of temporary security credentials that you can use to access @@ -422,25 +421,13 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -449,9 +436,6 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = addOpAssumeRoleValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "AssumeRole"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go index 16ffcf2efba..10f16e16559 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a set of temporary security credentials for users who have been @@ -360,22 +359,10 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -384,9 +371,6 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = addOpAssumeRoleWithSAMLValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "AssumeRoleWithSAML"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go index 2fe5f9284f1..97f51b8be70 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a set of temporary security credentials for users who have been @@ -377,22 +376,10 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -401,9 +388,6 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = addOpAssumeRoleWithWebIdentityValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "AssumeRoleWithWebIdentity"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go index 353512bb265..8946a9bb956 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a set of short term credentials you can use to perform privileged tasks @@ -131,25 +130,13 @@ func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, opti return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -158,9 +145,6 @@ func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, opti if err = addOpAssumeRootValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "AssumeRoot"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go index 2e54340ef41..41b3fe02f17 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go @@ -5,7 +5,6 @@ package sts import ( "context" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Decodes additional information about the authorization status of a request from @@ -91,25 +90,13 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -118,9 +105,6 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = addOpDecodeAuthorizationMessageValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "DecodeAuthorizationMessage"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go index c1e9af44033..da652ff1c74 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go @@ -5,7 +5,6 @@ package sts import ( "context" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns the account identifier for the specified access key ID. @@ -82,25 +81,13 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -109,9 +96,6 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = addOpGetAccessKeyInfoValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetAccessKeyInfo"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go index 7c2b4e92203..56dbdbf574f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns details about the IAM user or role whose credentials are used to call @@ -73,33 +72,18 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetCallerIdentity"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go index e00165161e3..33370240ff7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Exchanges a trade-in token for temporary Amazon Web Services credentials with @@ -71,25 +70,13 @@ func (c *Client) addOperationGetDelegatedAccessTokenMiddlewares(stack *middlewar return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -98,9 +85,6 @@ func (c *Client) addOperationGetDelegatedAccessTokenMiddlewares(stack *middlewar if err = addOpGetDelegatedAccessTokenValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetDelegatedAccessToken"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go index ba5f92bef8c..09e7ab30b7e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a set of temporary security credentials (consisting of an access key @@ -295,25 +294,13 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -322,9 +309,6 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = addOpGetFederationTokenValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetFederationToken"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go index 644e95ece86..ce0b895668e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" ) // Returns a set of temporary credentials for an Amazon Web Services account or @@ -144,33 +143,18 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetSessionToken"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go index 09cbebc2531..b36723d4756 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go @@ -6,7 +6,6 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/service/sts/types" "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" "time" ) @@ -94,25 +93,13 @@ func (c *Client) addOperationGetWebIdentityTokenMiddlewares(stack *middleware.St return err } - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + if err = addRecordResponseTiming(stack, options); err != nil { return err } if err = addCredentialSource(stack, options); err != nil { @@ -121,9 +108,6 @@ func (c *Client) addOperationGetWebIdentityTokenMiddlewares(stack *middleware.St if err = addOpGetWebIdentityTokenValidationMiddleware(stack); err != nil { return err } - if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "GetWebIdentityToken"), middleware.Before); err != nil { - return err - } if err = addRequestIDRetrieverMiddleware(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go index 8c1ce351616..45e073ffdc4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go @@ -38,15 +38,18 @@ func (m *awsAwsquery_deserializeOpAssumeRole) HandleDeserialize(ctx context.Cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorAssumeRole(response, &metadata) } @@ -159,15 +162,18 @@ func (m *awsAwsquery_deserializeOpAssumeRoleWithSAML) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoleWithSAML(response, &metadata) } @@ -286,15 +292,18 @@ func (m *awsAwsquery_deserializeOpAssumeRoleWithWebIdentity) HandleDeserialize(c return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoleWithWebIdentity(response, &metadata) } @@ -416,15 +425,18 @@ func (m *awsAwsquery_deserializeOpAssumeRoot) HandleDeserialize(ctx context.Cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoot(response, &metadata) } @@ -531,15 +543,18 @@ func (m *awsAwsquery_deserializeOpDecodeAuthorizationMessage) HandleDeserialize( return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorDecodeAuthorizationMessage(response, &metadata) } @@ -643,15 +658,18 @@ func (m *awsAwsquery_deserializeOpGetAccessKeyInfo) HandleDeserialize(ctx contex return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorGetAccessKeyInfo(response, &metadata) } @@ -752,15 +770,18 @@ func (m *awsAwsquery_deserializeOpGetCallerIdentity) HandleDeserialize(ctx conte return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorGetCallerIdentity(response, &metadata) } @@ -861,15 +882,18 @@ func (m *awsAwsquery_deserializeOpGetDelegatedAccessToken) HandleDeserialize(ctx return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response, &metadata) } @@ -979,15 +1003,18 @@ func (m *awsAwsquery_deserializeOpGetFederationToken) HandleDeserialize(ctx cont return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorGetFederationToken(response, &metadata) } @@ -1097,15 +1124,18 @@ func (m *awsAwsquery_deserializeOpGetSessionToken) HandleDeserialize(ctx context return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorGetSessionToken(response, &metadata) } @@ -1209,15 +1239,18 @@ func (m *awsAwsquery_deserializeOpGetWebIdentityToken) HandleDeserialize(ctx con return out, metadata, err } - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() response, ok := out.RawResponse.(*smithyhttp.Response) if !ok { return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} } + defer func() { smithyhttp.CloseResponseBody(ctx, response, false, err) }() + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + if response.StatusCode < 200 || response.StatusCode >= 300 { return out, metadata, awsAwsquery_deserializeOpErrorGetWebIdentityToken(response, &metadata) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json index 2fc7b400f7c..6a759b4cc20 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json @@ -32,6 +32,8 @@ "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", "options.go", + "request_snapshot_test.go", + "response_snapshot_test.go", "serializers.go", "snapshot_test.go", "sra_operation_order_test.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go index 92bbf3754ba..3bf0f0ef13b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go @@ -3,4 +3,4 @@ package sts // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.43.4" +const goModuleVersion = "1.47.1" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go index a9f2361fd32..b3c9df17f3c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go @@ -46,6 +46,11 @@ type Options struct { // clients initial default settings. DefaultsMode aws.DefaultsMode + // Disables SDK clock skew correction. When set, the SDK will not adjust request + // signing timestamps to compensate for clock drift between the client and the + // service. + DisableClockSkewCorrection bool + // The endpoint options to be used when attempting to resolve an endpoint. EndpointOptions EndpointResolverOptions diff --git a/vendor/github.com/aws/smithy-go/AGENTS.md b/vendor/github.com/aws/smithy-go/AGENTS.md index e2a75b8ea19..de1e3b2bbe9 100644 --- a/vendor/github.com/aws/smithy-go/AGENTS.md +++ b/vendor/github.com/aws/smithy-go/AGENTS.md @@ -68,8 +68,9 @@ cd codegen && ./gradlew build cd codegen && ./gradlew publishToMavenLocal ``` -The codegen artifact version is fixed at `0.1.0` and is not published to -Maven Central — you **MUST** `publishToMavenLocal`. +The codegen artifact version is published to Maven Central and bumped on each +release. For local development against unreleased codegen changes, use +`publishToMavenLocal` and point consumers at `mavenLocal()`. ## Runtime architecture diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md index 6ff611a8df0..0d26e973c5b 100644 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ b/vendor/github.com/aws/smithy-go/CHANGELOG.md @@ -1,3 +1,110 @@ +# Release (2026-08-26) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.28.1 + * **Bug Fix**: Fix broken AddLogger middleware since its insert point was removed. + +# Release (2026-08-25.2) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.28.0 + * **Feature**: Set `Content-Length` inline when the request body is set via `SetStream`. The `ComputeContentLength` middleware is now deprecated. + +# Release (2026-08-25) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.10 + * **Bug Fix**: Fix a data race on the underlying writer when an event stream is closed while an event write is in flight. + * **Bug Fix**: Restore draining the HTTP response body in `CloseResponseBody` to avoid issues with TCP connection reuse. + +# Release (2026-08-21) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.9 + * **Bug Fix**: Fix a generic event stream exception not carrying the error code and message from its payload. + * **Bug Fix**: Fix an event stream not being closed when its connection is lost, which would cause a caller writing to the stream to block indefinitely. + * **Bug Fix**: Fix deserialization of an empty list producing a nil slice instead of an empty one. + * **Bug Fix**: Restore draining the HTTP response body in `CloseResponseBody` to avoid issues with TCP connection reuse. + +# Release (2026-08-14) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.8 + * **Bug Fix**: Restore draining the HTTP response body in `CloseResponseBody` to avoid issues with TCP connection reuse. + +# Release (2026-08-07) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.7 + * **Bug Fix**: Don't serialize unset JSON documents as `nil` in structure members. + * **Bug Fix**: Fix a deserialization panic around collection members in recursive shape configs. + +# Release (2026-07-31) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.6 + * **Bug Fix**: Fix failure to deserialize any `@httpPayload` struct with a non-string member. + * **Bug Fix**: Fix failure to serialize any `@httpPayload` struct with a nested struct. + +# Release (2026-07-27) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.5 + * **Bug Fix**: Fix a performance issue in awsQuery with large response payloads. + +# Release (2026-07-16) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go/aws-http-auth`: [v1.2.1](aws-http-auth/CHANGELOG.md#v121-2026-07-16) + * **Bug Fix**: Use r.URL.Host when r.Host is unset. +* `github.com/aws/smithy-go/aws-http-auth-schemes`: [v1.0.0](aws-http-auth-schemes/CHANGELOG.md#v100-2026-07-16) + * **Release**: Module `github.com/aws/smithy-go/aws-http-auth-schemes` adds generic smithy-go client support for AWS Sigv4 and Sigv4a. + +# Release (2026-06-26) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.3 + * **Bug Fix**: Fix bug in JSON doc encoder and endpoint host label format validation + +# Release (2026-06-05) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.27.2 + * **Bug Fix**: Fix incorrect serialization of unions in CBOR-based protocols. + # Release (2026-06-04) ## General Highlights diff --git a/vendor/github.com/aws/smithy-go/README.md b/vendor/github.com/aws/smithy-go/README.md index c5e14564b41..ac5a0a6139f 100644 --- a/vendor/github.com/aws/smithy-go/README.md +++ b/vendor/github.com/aws/smithy-go/README.md @@ -11,8 +11,8 @@ The smithy-go runtime requires a minimum version of Go 1.24. ## :warning: Client codegen is unstable The client code generator in this repository powers the aws-sdk-go-v2. -Arbitrary client generation, while technically possible, is in an early stage -of development: +Arbitrary client generation, while possible, is in an early stage of +development: * Generated clients are missing certain features that were originally implemented SDK-side (e.g. retries) @@ -32,8 +32,6 @@ This repository implements the following Smithy build plugins: | `go-server-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go server code generation for Smithy models. | | `go-shape-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go shape code generation (types only) for Smithy models. | -**NOTE: Build plugins are not currently published to mavenCentral. You must publish to mavenLocal to make the build plugins visible to the Smithy CLI. The artifact version is currently fixed at 0.1.0.** - ## `go-codegen` ### Configuration @@ -79,7 +77,7 @@ example created from `smithy init`: ], "maven": { "dependencies": [ - "software.amazon.smithy.go:smithy-go-codegen:0.1.0" + "software.amazon.smithy.go:smithy-go-codegen:[0.1.0,2.0)" ] }, "plugins": { diff --git a/vendor/github.com/aws/smithy-go/encoding/json/value.go b/vendor/github.com/aws/smithy-go/encoding/json/value.go index b41ff1e15c2..eac49c44c2e 100644 --- a/vendor/github.com/aws/smithy-go/encoding/json/value.go +++ b/vendor/github.com/aws/smithy-go/encoding/json/value.go @@ -106,6 +106,11 @@ func (jv Value) BigInteger(v *big.Int) { // BigDecimal encodes v as JSON value func (jv Value) BigDecimal(v *big.Float) { + if v.Sign() == 0 && v.Signbit() { + // Preserve negative zero sign which Int64() would lose. + jv.w.Write([]byte("-0")) + return + } if i, accuracy := v.Int64(); accuracy == big.Exact { jv.Long(i) return diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go index 0c11541276b..68828dbfe94 100644 --- a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go @@ -27,6 +27,9 @@ func IsValidHostLabel(input string, allowSubDomains bool) bool { if !smithyhttp.ValidHostLabel(label) { return false } + if label[0] == '-' || label[len(label)-1] == '-' { + return false + } } return true diff --git a/vendor/github.com/aws/smithy-go/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go index ba81f77281f..c945a45db81 100644 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ b/vendor/github.com/aws/smithy-go/go_module_metadata.go @@ -3,4 +3,4 @@ package smithy // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.27.1" +const goModuleVersion = "1.28.1" diff --git a/vendor/github.com/aws/smithy-go/schema.go b/vendor/github.com/aws/smithy-go/schema.go index 6293d34b1e3..8e9c209a580 100644 --- a/vendor/github.com/aws/smithy-go/schema.go +++ b/vendor/github.com/aws/smithy-go/schema.go @@ -71,8 +71,9 @@ type Schema struct { directMask uint64 // bitmask: bit i set means indexed[i] was declared directly on this schema targetID ShapeID // for member schemas, the target's shape ID - listMember *Schema - mapKey, mapValue *Schema + // resolved on the fly and cached + listMember atomic.Pointer[Schema] + mapKey, mapValue atomic.Pointer[Schema] ext [numExtensionSlots]unsafe.Pointer // lazily-computed codec extensions, accessed atomically } @@ -126,9 +127,6 @@ func (s *Schema) AddMember(name string, target *Schema, ts ...Trait) *Schema { traits: cloneTraits(target.traits), directMask: 0, // inherited traits are not direct targetID: target.id, - listMember: target.listMember, - mapKey: target.mapKey, - mapValue: target.mapValue, } // member-declared traits override and are direct @@ -143,14 +141,6 @@ func (s *Schema) AddMember(name string, target *Schema, ts ...Trait) *Schema { atomic.StorePointer(&s.ext[i], nil) } - switch name { - case "member": - s.listMember = m - case "key": - s.mapKey = m - case "value": - s.mapValue = m - } return m } @@ -176,17 +166,31 @@ func cloneTraits(src map[ShapeID]Trait) map[ShapeID]Trait { // ListMember returns the "member" schema for list types. func (s *Schema) ListMember() *Schema { - return s.listMember + return s.lookup(&s.listMember, "member") } // MapKey returns the "key" schema for map types. func (s *Schema) MapKey() *Schema { - return s.mapKey + return s.lookup(&s.mapKey, "key") } // MapValue returns the "value" schema for map types. func (s *Schema) MapValue() *Schema { - return s.mapValue + return s.lookup(&s.mapValue, "value") +} + +func (s *Schema) lookup(cached *atomic.Pointer[Schema], name string) *Schema { + if v := cached.Load(); v != nil { + return v + } + + m, ok := s.members[name] + if !ok { + return nil + } + + cached.Store(m) + return m } // MemberName returns the member component of the schema's shape ID. diff --git a/vendor/github.com/aws/smithy-go/schema_ext.go b/vendor/github.com/aws/smithy-go/schema_ext.go index 7503b30b806..e98427ae345 100644 --- a/vendor/github.com/aws/smithy-go/schema_ext.go +++ b/vendor/github.com/aws/smithy-go/schema_ext.go @@ -9,13 +9,14 @@ import ( // (JSON, CBOR, etc.) uses a distinct slot to cache precomputed data. type ExtensionID int -const numExtensionSlots = 4 +const numExtensionSlots = 5 const ( - ExtJSON ExtensionID = iota // transport/http/protocol/internal/json - ExtCBOR // transport/http/protocol/internal/cbor - ExtXML // transport/http/protocol/internal/xml - ExtQuery // transport/http/protocol/internal/query + ExtJSON ExtensionID = iota // transport/http/protocol/internal/json + ExtCBOR // transport/http/protocol/internal/cbor + ExtXML // transport/http/protocol/internal/xml + ExtQuery // transport/http/protocol/internal/query + ExtHTTPBinding // transport/http/protocol/internal/httpbinding ) // SchemaExtension retrieves or lazily computes the extension for the given diff --git a/vendor/github.com/aws/smithy-go/transport/http/eventstream.go b/vendor/github.com/aws/smithy-go/transport/http/eventstream.go index 251db8ac35b..970ade30e20 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/eventstream.go +++ b/vendor/github.com/aws/smithy-go/transport/http/eventstream.go @@ -56,7 +56,10 @@ func NewEventStreamWriter(protocol ClientProtocol, schema *smithy.Schema, stream } func (w *EventStreamWriter) writeStream() { - defer w.Close() + defer func() { + w.err.SetError(w.eventStream.Close()) + }() + defer w.signalClose() for { select { @@ -100,11 +103,14 @@ func (w *EventStreamWriter) Send(ctx context.Context, variant *smithy.Schema, ev // Close signals end-of-stream and closes the underlying writer. Close is // safe for concurrent calls. func (w *EventStreamWriter) Close() error { + w.signalClose() + return w.err.Err() +} + +func (w *EventStreamWriter) signalClose() { w.closeOnce.Do(func() { close(w.done) - w.err.SetError(w.eventStream.Close()) }) - return w.err.Err() } // Err returns the first error encountered during writing. diff --git a/vendor/github.com/aws/smithy-go/transport/http/host.go b/vendor/github.com/aws/smithy-go/transport/http/host.go index db9801bea52..b504a455da2 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/host.go +++ b/vendor/github.com/aws/smithy-go/transport/http/host.go @@ -69,7 +69,7 @@ func ValidPortNumber(port string) bool { return true } -// ValidHostLabel returns whether the label is a valid RFC 3986 host label. +// ValidHostLabel returns whether the label is a valid RFC 952/1123 host label. func ValidHostLabel(label string) bool { if l := len(label); l == 0 || l > 63 { return false diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go index 914338f2e75..a7e70b1cb50 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go +++ b/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go @@ -8,9 +8,35 @@ import ( "github.com/aws/smithy-go/middleware" ) +// CloseResponseBody closes the HTTP response body. It leaves the body open only +// for a successful response whose payload is a caller-owned stream (isStreaming +// with a nil opErr); on error, or for a non-streaming response, it closes the +// body — an error response body is diagnostic, not a caller-owned stream. +func CloseResponseBody(ctx context.Context, resp *Response, isStreaming bool, opErr error) { + if resp == nil || resp.Body == nil { + return + } + if isStreaming && opErr == nil { + return + } + + // Drain to EOF before closing; a body closed while unread prevents + // connection reuse. + if _, copyErr := io.Copy(io.Discard, resp.Body); copyErr != nil { + middleware.GetLogger(ctx).Logf(logging.Warn, "failed to discard remaining HTTP response body, this may affect connection reuse") + } + + if closeErr := resp.Body.Close(); closeErr != nil { + middleware.GetLogger(ctx).Logf(logging.Warn, "failed to close HTTP response body, this may affect connection reuse") + } +} + // AddErrorCloseResponseBodyMiddleware adds the middleware to automatically // close the response body of an operation request if the request response // failed. +// +// Deprecated: generated operation deserializers now close the response body +// via CloseResponseBody, so this middleware is no longer used. func AddErrorCloseResponseBodyMiddleware(stack *middleware.Stack) error { return stack.Deserialize.Insert(&errorCloseResponseBodyMiddleware{}, "OperationDeserializer", middleware.Before) } @@ -42,6 +68,9 @@ func (m *errorCloseResponseBodyMiddleware) HandleDeserialize( // AddCloseResponseBodyMiddleware adds the middleware to automatically close // the response body of an operation request, after the response had been // deserialized. +// +// Deprecated: generated operation deserializers now close the response body +// via CloseResponseBody, so this middleware is no longer used. func AddCloseResponseBodyMiddleware(stack *middleware.Stack) error { return stack.Deserialize.Insert(&closeResponseBody{}, "OperationDeserializer", middleware.Before) } diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go index 9969389bb29..7a1c47fe367 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go +++ b/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go @@ -14,6 +14,9 @@ type ComputeContentLength struct { // AddComputeContentLengthMiddleware adds ComputeContentLength to the middleware // stack's Build step. +// +// Deprecated: Content-Length is now set when the request body is set via +// Request.SetStream, so this middleware is no longer used. func AddComputeContentLengthMiddleware(stack *middleware.Stack) error { return stack.Build.Add(&ComputeContentLength{}, middleware.After) } diff --git a/vendor/github.com/aws/smithy-go/transport/http/request.go b/vendor/github.com/aws/smithy-go/transport/http/request.go index 5cbf6f10acc..87acdfe57c1 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/request.go +++ b/vendor/github.com/aws/smithy-go/transport/http/request.go @@ -118,6 +118,9 @@ func (r *Request) IsStreamSeekable() bool { // SetStream returns a clone of the request with the stream set to the provided // reader. May return an error if the provided reader is seekable but returns // an error. +// +// ContentLength is set to the stream's length when it can be determined, and +// left unchanged otherwise. func (r *Request) SetStream(reader io.Reader) (rc *Request, err error) { rc = r.Clone() @@ -151,6 +154,12 @@ func (r *Request) SetStream(reader io.Reader) (rc *Request, err error) { rc.isStreamSeekable = isStreamSeekable rc.streamStartPos = streamStartPos + if n, ok, err := rc.StreamLength(); err != nil { + return rc, err + } else if ok { + rc.ContentLength = n + } + return rc, err } diff --git a/vendor/github.com/aws/smithy-go/waiter/logger.go b/vendor/github.com/aws/smithy-go/waiter/logger.go index 8d70a03ff2f..cb31a2e099c 100644 --- a/vendor/github.com/aws/smithy-go/waiter/logger.go +++ b/vendor/github.com/aws/smithy-go/waiter/logger.go @@ -30,7 +30,7 @@ func (m *Logger) HandleInitialize(ctx context.Context, in middleware.InitializeI return next.HandleInitialize(ctx, in) } -// AddLogger is a helper util to add waiter logger after `SetLogger` middleware in +// AddLogger is a helper util to add a waiter logger to the initialize stack. func (m Logger) AddLogger(stack *middleware.Stack) error { - return stack.Initialize.Insert(&m, "SetLogger", middleware.After) + return stack.Initialize.Add(&m, middleware.After) } diff --git a/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/vendor/github.com/felixge/httpsnoop/capture_metrics.go index bec7b71b39c..97f0a51de31 100644 --- a/vendor/github.com/felixge/httpsnoop/capture_metrics.go +++ b/vendor/github.com/felixge/httpsnoop/capture_metrics.go @@ -69,6 +69,16 @@ func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWri } }, + WriteString: func(next WriteStringFunc) WriteStringFunc { + return func(s string) (int, error) { + n, err := next(s) + + m.Written += int64(n) + headerWritten = true + return n, err + } + }, + ReadFrom: func(next ReadFromFunc) ReadFromFunc { return func(src io.Reader) (int64, error) { n, err := next(src) @@ -81,6 +91,31 @@ func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWri } ) + // defer to ensure duration is updated even if the handler panics + defer func() { + m.Duration += time.Since(start) + }() fn(Wrap(w, hooks)) - m.Duration += time.Since(start) +} + +// deadliner defines two methods introduced in go 1.20. The standard library +// seems not to provide an interface we can import, hence its definition here. +type deadliner interface { + SetReadDeadline(deadline time.Time) error + SetWriteDeadline(deadline time.Time) error +} + +// fullDuplexEnabler defines a method introduced in go 1.21. The standard +// library seems not to provide an interface we can import, hence its definition +// here. +type fullDuplexEnabler interface { + EnableFullDuplex() error +} + +// httpFlushError defines a method introduced in go 1.20. The standard +// library seems not to provide an interface we can import, hence its definition +// here. +// See https://github.com/golang/go/blob/go1.20/src/net/http/responsecontroller.go#L50 +type httpFlushError interface { + FlushError() error } diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated.go b/vendor/github.com/felixge/httpsnoop/wrap_generated.go new file mode 100644 index 00000000000..b6549ba982b --- /dev/null +++ b/vendor/github.com/felixge/httpsnoop/wrap_generated.go @@ -0,0 +1,16179 @@ +// Code generated by "httpsnoop/codegen"; DO NOT EDIT. + +package httpsnoop + +import ( + "bufio" + "io" + "net" + "net/http" + "time" +) + +// HeaderFunc is part of the http.ResponseWriter interface. +type HeaderFunc func() http.Header + +// WriteHeaderFunc is part of the http.ResponseWriter interface. +type WriteHeaderFunc func(code int) + +// WriteFunc is part of the http.ResponseWriter interface. +type WriteFunc func(b []byte) (int, error) + +// FlushFunc is part of the http.Flusher interface. +type FlushFunc func() + +// FlushErrorFunc is part of the httpFlushError interface. +type FlushErrorFunc func() error + +// CloseNotifyFunc is part of the http.CloseNotifier interface. +type CloseNotifyFunc func() <-chan bool + +// HijackFunc is part of the http.Hijacker interface. +type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) + +// ReadFromFunc is part of the io.ReaderFrom interface. +type ReadFromFunc func(src io.Reader) (int64, error) + +// SetReadDeadlineFunc is part of the deadliner interface. +type SetReadDeadlineFunc func(deadline time.Time) error + +// SetWriteDeadlineFunc is part of the deadliner interface. +type SetWriteDeadlineFunc func(deadline time.Time) error + +// EnableFullDuplexFunc is part of the fullDuplexEnabler interface. +type EnableFullDuplexFunc func() error + +// PushFunc is part of the http.Pusher interface. +type PushFunc func(target string, opts *http.PushOptions) error + +// WriteStringFunc is part of the io.StringWriter interface. +type WriteStringFunc func(s string) (int, error) + +// Hooks defines a set of method interceptors for methods included in +// http.ResponseWriter as well as some others. You can think of them as +// middleware for the function calls they target. See Wrap for more details. +// +// For each method, the exact matching hook takes precedence. For example, +// WriteString calls the WriteString hook when it is configured, even if a +// Write hook is also configured. If the exact hook is not configured, most +// methods call through to the underlying ResponseWriter directly. +// +// Two compatibility fallbacks preserve the behavior users had before Wrap +// learned about newer optional interfaces: +// - If the underlying ResponseWriter implements io.StringWriter and +// WriteString is called, but only the Write hook is configured, WriteString +// is routed through the Write hook with []byte(s). If neither hook is +// configured, WriteString calls the underlying WriteString method directly. +// - If the underlying ResponseWriter implements both http.Flusher and +// FlushError, and FlushError is called, but only the Flush hook is +// configured, FlushError is routed through the Flush hook while preserving +// the error returned by the underlying FlushError method. If neither hook is +// configured, FlushError calls the underlying FlushError method directly. +type Hooks struct { + Header func(HeaderFunc) HeaderFunc + WriteHeader func(WriteHeaderFunc) WriteHeaderFunc + Write func(WriteFunc) WriteFunc + Flush func(FlushFunc) FlushFunc + FlushError func(FlushErrorFunc) FlushErrorFunc + CloseNotify func(CloseNotifyFunc) CloseNotifyFunc + Hijack func(HijackFunc) HijackFunc + ReadFrom func(ReadFromFunc) ReadFromFunc + SetReadDeadline func(SetReadDeadlineFunc) SetReadDeadlineFunc + SetWriteDeadline func(SetWriteDeadlineFunc) SetWriteDeadlineFunc + EnableFullDuplex func(EnableFullDuplexFunc) EnableFullDuplexFunc + Push func(PushFunc) PushFunc + WriteString func(WriteStringFunc) WriteStringFunc +} + +// Wrap returns a wrapped version of w that provides the exact same interface +// as w. Specifically if w implements any combination of: +// +// - http.Flusher +// - httpFlushError +// - http.CloseNotifier +// - http.Hijacker +// - io.ReaderFrom +// - deadliner +// - fullDuplexEnabler +// - http.Pusher +// - io.StringWriter +// +// The wrapped version will implement the exact same combination. If no hooks +// are set, the wrapped version also behaves exactly as w. Hooks targeting +// methods not supported by w are ignored. Any other hooks will intercept the +// method they target and may modify the call's arguments and/or return values. +// The CaptureMetrics implementation serves as a working example for how the +// hooks can be used. +func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { + state := &rwState{w: w} + var combo uint16 + if hooks.Header != nil { + state.header = hooks.Header(w.Header) + } + if hooks.WriteHeader != nil { + state.writeHeader = hooks.WriteHeader(w.WriteHeader) + } + if hooks.Write != nil { + state.write = hooks.Write(w.Write) + } + if t0, i0 := w.(http.Flusher); i0 { + combo |= 1 << 8 + if hooks.Flush != nil { + state.flush = hooks.Flush(t0.Flush) + } + } + if t1, i1 := w.(httpFlushError); i1 { + combo |= 1 << 7 + if hooks.FlushError != nil { + state.flushError = hooks.FlushError(t1.FlushError) + } else if state.flush != nil { + state.flushError = func() (err error) { hooks.Flush(func() { err = t1.FlushError() })(); return err } + } + } + if t2, i2 := w.(http.CloseNotifier); i2 { + combo |= 1 << 6 + if hooks.CloseNotify != nil { + state.closeNotify = hooks.CloseNotify(t2.CloseNotify) + } + } + if t3, i3 := w.(http.Hijacker); i3 { + combo |= 1 << 5 + if hooks.Hijack != nil { + state.hijack = hooks.Hijack(t3.Hijack) + } + } + if t4, i4 := w.(io.ReaderFrom); i4 { + combo |= 1 << 4 + if hooks.ReadFrom != nil { + state.readFrom = hooks.ReadFrom(t4.ReadFrom) + } + } + if t5, i5 := w.(deadliner); i5 { + combo |= 1 << 3 + if hooks.SetReadDeadline != nil { + state.setReadDeadline = hooks.SetReadDeadline(t5.SetReadDeadline) + } + if hooks.SetWriteDeadline != nil { + state.setWriteDeadline = hooks.SetWriteDeadline(t5.SetWriteDeadline) + } + } + if t6, i6 := w.(fullDuplexEnabler); i6 { + combo |= 1 << 2 + if hooks.EnableFullDuplex != nil { + state.enableFullDuplex = hooks.EnableFullDuplex(t6.EnableFullDuplex) + } + } + if t7, i7 := w.(http.Pusher); i7 { + combo |= 1 << 1 + if hooks.Push != nil { + state.push = hooks.Push(t7.Push) + } + } + if t8, i8 := w.(io.StringWriter); i8 { + combo |= 1 << 0 + if hooks.WriteString != nil { + state.writeString = hooks.WriteString(t8.WriteString) + } else if state.write != nil { + state.writeString = func(s string) (int, error) { return state.write([]byte(s)) } + } + } + switch combo { + case 0: + return (*rw0)(state) + case 1: + return (*rw1)(state) + case 2: + return (*rw2)(state) + case 3: + return (*rw3)(state) + case 4: + return (*rw4)(state) + case 5: + return (*rw5)(state) + case 6: + return (*rw6)(state) + case 7: + return (*rw7)(state) + case 8: + return (*rw8)(state) + case 9: + return (*rw9)(state) + case 10: + return (*rw10)(state) + case 11: + return (*rw11)(state) + case 12: + return (*rw12)(state) + case 13: + return (*rw13)(state) + case 14: + return (*rw14)(state) + case 15: + return (*rw15)(state) + case 16: + return (*rw16)(state) + case 17: + return (*rw17)(state) + case 18: + return (*rw18)(state) + case 19: + return (*rw19)(state) + case 20: + return (*rw20)(state) + case 21: + return (*rw21)(state) + case 22: + return (*rw22)(state) + case 23: + return (*rw23)(state) + case 24: + return (*rw24)(state) + case 25: + return (*rw25)(state) + case 26: + return (*rw26)(state) + case 27: + return (*rw27)(state) + case 28: + return (*rw28)(state) + case 29: + return (*rw29)(state) + case 30: + return (*rw30)(state) + case 31: + return (*rw31)(state) + case 32: + return (*rw32)(state) + case 33: + return (*rw33)(state) + case 34: + return (*rw34)(state) + case 35: + return (*rw35)(state) + case 36: + return (*rw36)(state) + case 37: + return (*rw37)(state) + case 38: + return (*rw38)(state) + case 39: + return (*rw39)(state) + case 40: + return (*rw40)(state) + case 41: + return (*rw41)(state) + case 42: + return (*rw42)(state) + case 43: + return (*rw43)(state) + case 44: + return (*rw44)(state) + case 45: + return (*rw45)(state) + case 46: + return (*rw46)(state) + case 47: + return (*rw47)(state) + case 48: + return (*rw48)(state) + case 49: + return (*rw49)(state) + case 50: + return (*rw50)(state) + case 51: + return (*rw51)(state) + case 52: + return (*rw52)(state) + case 53: + return (*rw53)(state) + case 54: + return (*rw54)(state) + case 55: + return (*rw55)(state) + case 56: + return (*rw56)(state) + case 57: + return (*rw57)(state) + case 58: + return (*rw58)(state) + case 59: + return (*rw59)(state) + case 60: + return (*rw60)(state) + case 61: + return (*rw61)(state) + case 62: + return (*rw62)(state) + case 63: + return (*rw63)(state) + case 64: + return (*rw64)(state) + case 65: + return (*rw65)(state) + case 66: + return (*rw66)(state) + case 67: + return (*rw67)(state) + case 68: + return (*rw68)(state) + case 69: + return (*rw69)(state) + case 70: + return (*rw70)(state) + case 71: + return (*rw71)(state) + case 72: + return (*rw72)(state) + case 73: + return (*rw73)(state) + case 74: + return (*rw74)(state) + case 75: + return (*rw75)(state) + case 76: + return (*rw76)(state) + case 77: + return (*rw77)(state) + case 78: + return (*rw78)(state) + case 79: + return (*rw79)(state) + case 80: + return (*rw80)(state) + case 81: + return (*rw81)(state) + case 82: + return (*rw82)(state) + case 83: + return (*rw83)(state) + case 84: + return (*rw84)(state) + case 85: + return (*rw85)(state) + case 86: + return (*rw86)(state) + case 87: + return (*rw87)(state) + case 88: + return (*rw88)(state) + case 89: + return (*rw89)(state) + case 90: + return (*rw90)(state) + case 91: + return (*rw91)(state) + case 92: + return (*rw92)(state) + case 93: + return (*rw93)(state) + case 94: + return (*rw94)(state) + case 95: + return (*rw95)(state) + case 96: + return (*rw96)(state) + case 97: + return (*rw97)(state) + case 98: + return (*rw98)(state) + case 99: + return (*rw99)(state) + case 100: + return (*rw100)(state) + case 101: + return (*rw101)(state) + case 102: + return (*rw102)(state) + case 103: + return (*rw103)(state) + case 104: + return (*rw104)(state) + case 105: + return (*rw105)(state) + case 106: + return (*rw106)(state) + case 107: + return (*rw107)(state) + case 108: + return (*rw108)(state) + case 109: + return (*rw109)(state) + case 110: + return (*rw110)(state) + case 111: + return (*rw111)(state) + case 112: + return (*rw112)(state) + case 113: + return (*rw113)(state) + case 114: + return (*rw114)(state) + case 115: + return (*rw115)(state) + case 116: + return (*rw116)(state) + case 117: + return (*rw117)(state) + case 118: + return (*rw118)(state) + case 119: + return (*rw119)(state) + case 120: + return (*rw120)(state) + case 121: + return (*rw121)(state) + case 122: + return (*rw122)(state) + case 123: + return (*rw123)(state) + case 124: + return (*rw124)(state) + case 125: + return (*rw125)(state) + case 126: + return (*rw126)(state) + case 127: + return (*rw127)(state) + case 128: + return (*rw128)(state) + case 129: + return (*rw129)(state) + case 130: + return (*rw130)(state) + case 131: + return (*rw131)(state) + case 132: + return (*rw132)(state) + case 133: + return (*rw133)(state) + case 134: + return (*rw134)(state) + case 135: + return (*rw135)(state) + case 136: + return (*rw136)(state) + case 137: + return (*rw137)(state) + case 138: + return (*rw138)(state) + case 139: + return (*rw139)(state) + case 140: + return (*rw140)(state) + case 141: + return (*rw141)(state) + case 142: + return (*rw142)(state) + case 143: + return (*rw143)(state) + case 144: + return (*rw144)(state) + case 145: + return (*rw145)(state) + case 146: + return (*rw146)(state) + case 147: + return (*rw147)(state) + case 148: + return (*rw148)(state) + case 149: + return (*rw149)(state) + case 150: + return (*rw150)(state) + case 151: + return (*rw151)(state) + case 152: + return (*rw152)(state) + case 153: + return (*rw153)(state) + case 154: + return (*rw154)(state) + case 155: + return (*rw155)(state) + case 156: + return (*rw156)(state) + case 157: + return (*rw157)(state) + case 158: + return (*rw158)(state) + case 159: + return (*rw159)(state) + case 160: + return (*rw160)(state) + case 161: + return (*rw161)(state) + case 162: + return (*rw162)(state) + case 163: + return (*rw163)(state) + case 164: + return (*rw164)(state) + case 165: + return (*rw165)(state) + case 166: + return (*rw166)(state) + case 167: + return (*rw167)(state) + case 168: + return (*rw168)(state) + case 169: + return (*rw169)(state) + case 170: + return (*rw170)(state) + case 171: + return (*rw171)(state) + case 172: + return (*rw172)(state) + case 173: + return (*rw173)(state) + case 174: + return (*rw174)(state) + case 175: + return (*rw175)(state) + case 176: + return (*rw176)(state) + case 177: + return (*rw177)(state) + case 178: + return (*rw178)(state) + case 179: + return (*rw179)(state) + case 180: + return (*rw180)(state) + case 181: + return (*rw181)(state) + case 182: + return (*rw182)(state) + case 183: + return (*rw183)(state) + case 184: + return (*rw184)(state) + case 185: + return (*rw185)(state) + case 186: + return (*rw186)(state) + case 187: + return (*rw187)(state) + case 188: + return (*rw188)(state) + case 189: + return (*rw189)(state) + case 190: + return (*rw190)(state) + case 191: + return (*rw191)(state) + case 192: + return (*rw192)(state) + case 193: + return (*rw193)(state) + case 194: + return (*rw194)(state) + case 195: + return (*rw195)(state) + case 196: + return (*rw196)(state) + case 197: + return (*rw197)(state) + case 198: + return (*rw198)(state) + case 199: + return (*rw199)(state) + case 200: + return (*rw200)(state) + case 201: + return (*rw201)(state) + case 202: + return (*rw202)(state) + case 203: + return (*rw203)(state) + case 204: + return (*rw204)(state) + case 205: + return (*rw205)(state) + case 206: + return (*rw206)(state) + case 207: + return (*rw207)(state) + case 208: + return (*rw208)(state) + case 209: + return (*rw209)(state) + case 210: + return (*rw210)(state) + case 211: + return (*rw211)(state) + case 212: + return (*rw212)(state) + case 213: + return (*rw213)(state) + case 214: + return (*rw214)(state) + case 215: + return (*rw215)(state) + case 216: + return (*rw216)(state) + case 217: + return (*rw217)(state) + case 218: + return (*rw218)(state) + case 219: + return (*rw219)(state) + case 220: + return (*rw220)(state) + case 221: + return (*rw221)(state) + case 222: + return (*rw222)(state) + case 223: + return (*rw223)(state) + case 224: + return (*rw224)(state) + case 225: + return (*rw225)(state) + case 226: + return (*rw226)(state) + case 227: + return (*rw227)(state) + case 228: + return (*rw228)(state) + case 229: + return (*rw229)(state) + case 230: + return (*rw230)(state) + case 231: + return (*rw231)(state) + case 232: + return (*rw232)(state) + case 233: + return (*rw233)(state) + case 234: + return (*rw234)(state) + case 235: + return (*rw235)(state) + case 236: + return (*rw236)(state) + case 237: + return (*rw237)(state) + case 238: + return (*rw238)(state) + case 239: + return (*rw239)(state) + case 240: + return (*rw240)(state) + case 241: + return (*rw241)(state) + case 242: + return (*rw242)(state) + case 243: + return (*rw243)(state) + case 244: + return (*rw244)(state) + case 245: + return (*rw245)(state) + case 246: + return (*rw246)(state) + case 247: + return (*rw247)(state) + case 248: + return (*rw248)(state) + case 249: + return (*rw249)(state) + case 250: + return (*rw250)(state) + case 251: + return (*rw251)(state) + case 252: + return (*rw252)(state) + case 253: + return (*rw253)(state) + case 254: + return (*rw254)(state) + case 255: + return (*rw255)(state) + case 256: + return (*rw256)(state) + case 257: + return (*rw257)(state) + case 258: + return (*rw258)(state) + case 259: + return (*rw259)(state) + case 260: + return (*rw260)(state) + case 261: + return (*rw261)(state) + case 262: + return (*rw262)(state) + case 263: + return (*rw263)(state) + case 264: + return (*rw264)(state) + case 265: + return (*rw265)(state) + case 266: + return (*rw266)(state) + case 267: + return (*rw267)(state) + case 268: + return (*rw268)(state) + case 269: + return (*rw269)(state) + case 270: + return (*rw270)(state) + case 271: + return (*rw271)(state) + case 272: + return (*rw272)(state) + case 273: + return (*rw273)(state) + case 274: + return (*rw274)(state) + case 275: + return (*rw275)(state) + case 276: + return (*rw276)(state) + case 277: + return (*rw277)(state) + case 278: + return (*rw278)(state) + case 279: + return (*rw279)(state) + case 280: + return (*rw280)(state) + case 281: + return (*rw281)(state) + case 282: + return (*rw282)(state) + case 283: + return (*rw283)(state) + case 284: + return (*rw284)(state) + case 285: + return (*rw285)(state) + case 286: + return (*rw286)(state) + case 287: + return (*rw287)(state) + case 288: + return (*rw288)(state) + case 289: + return (*rw289)(state) + case 290: + return (*rw290)(state) + case 291: + return (*rw291)(state) + case 292: + return (*rw292)(state) + case 293: + return (*rw293)(state) + case 294: + return (*rw294)(state) + case 295: + return (*rw295)(state) + case 296: + return (*rw296)(state) + case 297: + return (*rw297)(state) + case 298: + return (*rw298)(state) + case 299: + return (*rw299)(state) + case 300: + return (*rw300)(state) + case 301: + return (*rw301)(state) + case 302: + return (*rw302)(state) + case 303: + return (*rw303)(state) + case 304: + return (*rw304)(state) + case 305: + return (*rw305)(state) + case 306: + return (*rw306)(state) + case 307: + return (*rw307)(state) + case 308: + return (*rw308)(state) + case 309: + return (*rw309)(state) + case 310: + return (*rw310)(state) + case 311: + return (*rw311)(state) + case 312: + return (*rw312)(state) + case 313: + return (*rw313)(state) + case 314: + return (*rw314)(state) + case 315: + return (*rw315)(state) + case 316: + return (*rw316)(state) + case 317: + return (*rw317)(state) + case 318: + return (*rw318)(state) + case 319: + return (*rw319)(state) + case 320: + return (*rw320)(state) + case 321: + return (*rw321)(state) + case 322: + return (*rw322)(state) + case 323: + return (*rw323)(state) + case 324: + return (*rw324)(state) + case 325: + return (*rw325)(state) + case 326: + return (*rw326)(state) + case 327: + return (*rw327)(state) + case 328: + return (*rw328)(state) + case 329: + return (*rw329)(state) + case 330: + return (*rw330)(state) + case 331: + return (*rw331)(state) + case 332: + return (*rw332)(state) + case 333: + return (*rw333)(state) + case 334: + return (*rw334)(state) + case 335: + return (*rw335)(state) + case 336: + return (*rw336)(state) + case 337: + return (*rw337)(state) + case 338: + return (*rw338)(state) + case 339: + return (*rw339)(state) + case 340: + return (*rw340)(state) + case 341: + return (*rw341)(state) + case 342: + return (*rw342)(state) + case 343: + return (*rw343)(state) + case 344: + return (*rw344)(state) + case 345: + return (*rw345)(state) + case 346: + return (*rw346)(state) + case 347: + return (*rw347)(state) + case 348: + return (*rw348)(state) + case 349: + return (*rw349)(state) + case 350: + return (*rw350)(state) + case 351: + return (*rw351)(state) + case 352: + return (*rw352)(state) + case 353: + return (*rw353)(state) + case 354: + return (*rw354)(state) + case 355: + return (*rw355)(state) + case 356: + return (*rw356)(state) + case 357: + return (*rw357)(state) + case 358: + return (*rw358)(state) + case 359: + return (*rw359)(state) + case 360: + return (*rw360)(state) + case 361: + return (*rw361)(state) + case 362: + return (*rw362)(state) + case 363: + return (*rw363)(state) + case 364: + return (*rw364)(state) + case 365: + return (*rw365)(state) + case 366: + return (*rw366)(state) + case 367: + return (*rw367)(state) + case 368: + return (*rw368)(state) + case 369: + return (*rw369)(state) + case 370: + return (*rw370)(state) + case 371: + return (*rw371)(state) + case 372: + return (*rw372)(state) + case 373: + return (*rw373)(state) + case 374: + return (*rw374)(state) + case 375: + return (*rw375)(state) + case 376: + return (*rw376)(state) + case 377: + return (*rw377)(state) + case 378: + return (*rw378)(state) + case 379: + return (*rw379)(state) + case 380: + return (*rw380)(state) + case 381: + return (*rw381)(state) + case 382: + return (*rw382)(state) + case 383: + return (*rw383)(state) + case 384: + return (*rw384)(state) + case 385: + return (*rw385)(state) + case 386: + return (*rw386)(state) + case 387: + return (*rw387)(state) + case 388: + return (*rw388)(state) + case 389: + return (*rw389)(state) + case 390: + return (*rw390)(state) + case 391: + return (*rw391)(state) + case 392: + return (*rw392)(state) + case 393: + return (*rw393)(state) + case 394: + return (*rw394)(state) + case 395: + return (*rw395)(state) + case 396: + return (*rw396)(state) + case 397: + return (*rw397)(state) + case 398: + return (*rw398)(state) + case 399: + return (*rw399)(state) + case 400: + return (*rw400)(state) + case 401: + return (*rw401)(state) + case 402: + return (*rw402)(state) + case 403: + return (*rw403)(state) + case 404: + return (*rw404)(state) + case 405: + return (*rw405)(state) + case 406: + return (*rw406)(state) + case 407: + return (*rw407)(state) + case 408: + return (*rw408)(state) + case 409: + return (*rw409)(state) + case 410: + return (*rw410)(state) + case 411: + return (*rw411)(state) + case 412: + return (*rw412)(state) + case 413: + return (*rw413)(state) + case 414: + return (*rw414)(state) + case 415: + return (*rw415)(state) + case 416: + return (*rw416)(state) + case 417: + return (*rw417)(state) + case 418: + return (*rw418)(state) + case 419: + return (*rw419)(state) + case 420: + return (*rw420)(state) + case 421: + return (*rw421)(state) + case 422: + return (*rw422)(state) + case 423: + return (*rw423)(state) + case 424: + return (*rw424)(state) + case 425: + return (*rw425)(state) + case 426: + return (*rw426)(state) + case 427: + return (*rw427)(state) + case 428: + return (*rw428)(state) + case 429: + return (*rw429)(state) + case 430: + return (*rw430)(state) + case 431: + return (*rw431)(state) + case 432: + return (*rw432)(state) + case 433: + return (*rw433)(state) + case 434: + return (*rw434)(state) + case 435: + return (*rw435)(state) + case 436: + return (*rw436)(state) + case 437: + return (*rw437)(state) + case 438: + return (*rw438)(state) + case 439: + return (*rw439)(state) + case 440: + return (*rw440)(state) + case 441: + return (*rw441)(state) + case 442: + return (*rw442)(state) + case 443: + return (*rw443)(state) + case 444: + return (*rw444)(state) + case 445: + return (*rw445)(state) + case 446: + return (*rw446)(state) + case 447: + return (*rw447)(state) + case 448: + return (*rw448)(state) + case 449: + return (*rw449)(state) + case 450: + return (*rw450)(state) + case 451: + return (*rw451)(state) + case 452: + return (*rw452)(state) + case 453: + return (*rw453)(state) + case 454: + return (*rw454)(state) + case 455: + return (*rw455)(state) + case 456: + return (*rw456)(state) + case 457: + return (*rw457)(state) + case 458: + return (*rw458)(state) + case 459: + return (*rw459)(state) + case 460: + return (*rw460)(state) + case 461: + return (*rw461)(state) + case 462: + return (*rw462)(state) + case 463: + return (*rw463)(state) + case 464: + return (*rw464)(state) + case 465: + return (*rw465)(state) + case 466: + return (*rw466)(state) + case 467: + return (*rw467)(state) + case 468: + return (*rw468)(state) + case 469: + return (*rw469)(state) + case 470: + return (*rw470)(state) + case 471: + return (*rw471)(state) + case 472: + return (*rw472)(state) + case 473: + return (*rw473)(state) + case 474: + return (*rw474)(state) + case 475: + return (*rw475)(state) + case 476: + return (*rw476)(state) + case 477: + return (*rw477)(state) + case 478: + return (*rw478)(state) + case 479: + return (*rw479)(state) + case 480: + return (*rw480)(state) + case 481: + return (*rw481)(state) + case 482: + return (*rw482)(state) + case 483: + return (*rw483)(state) + case 484: + return (*rw484)(state) + case 485: + return (*rw485)(state) + case 486: + return (*rw486)(state) + case 487: + return (*rw487)(state) + case 488: + return (*rw488)(state) + case 489: + return (*rw489)(state) + case 490: + return (*rw490)(state) + case 491: + return (*rw491)(state) + case 492: + return (*rw492)(state) + case 493: + return (*rw493)(state) + case 494: + return (*rw494)(state) + case 495: + return (*rw495)(state) + case 496: + return (*rw496)(state) + case 497: + return (*rw497)(state) + case 498: + return (*rw498)(state) + case 499: + return (*rw499)(state) + case 500: + return (*rw500)(state) + case 501: + return (*rw501)(state) + case 502: + return (*rw502)(state) + case 503: + return (*rw503)(state) + case 504: + return (*rw504)(state) + case 505: + return (*rw505)(state) + case 506: + return (*rw506)(state) + case 507: + return (*rw507)(state) + case 508: + return (*rw508)(state) + case 509: + return (*rw509)(state) + case 510: + return (*rw510)(state) + case 511: + return (*rw511)(state) + } + panic("unreachable") +} + +type rwState struct { + w http.ResponseWriter + header HeaderFunc + writeHeader WriteHeaderFunc + write WriteFunc + flush FlushFunc + flushError FlushErrorFunc + closeNotify CloseNotifyFunc + hijack HijackFunc + readFrom ReadFromFunc + setReadDeadline SetReadDeadlineFunc + setWriteDeadline SetWriteDeadlineFunc + enableFullDuplex EnableFullDuplexFunc + push PushFunc + writeString WriteStringFunc +} + +func (r *rwState) doHeader() http.Header { + if r.header != nil { + return r.header() + } + return r.w.Header() +} + +func (r *rwState) doWriteHeader(code int) { + if r.writeHeader != nil { + r.writeHeader(code) + return + } + r.w.WriteHeader(code) +} + +func (r *rwState) doWrite(b []byte) (int, error) { + if r.write != nil { + return r.write(b) + } + return r.w.Write(b) +} + +func (r *rwState) doFlush() { + if r.flush != nil { + r.flush() + return + } + r.w.(http.Flusher).Flush() +} + +func (r *rwState) doFlushError() error { + if r.flushError != nil { + return r.flushError() + } + return r.w.(httpFlushError).FlushError() +} + +func (r *rwState) doCloseNotify() <-chan bool { + if r.closeNotify != nil { + return r.closeNotify() + } + return r.w.(http.CloseNotifier).CloseNotify() +} + +func (r *rwState) doHijack() (net.Conn, *bufio.ReadWriter, error) { + if r.hijack != nil { + return r.hijack() + } + return r.w.(http.Hijacker).Hijack() +} + +func (r *rwState) doReadFrom(src io.Reader) (int64, error) { + if r.readFrom != nil { + return r.readFrom(src) + } + return r.w.(io.ReaderFrom).ReadFrom(src) +} + +func (r *rwState) doSetReadDeadline(deadline time.Time) error { + if r.setReadDeadline != nil { + return r.setReadDeadline(deadline) + } + return r.w.(deadliner).SetReadDeadline(deadline) +} + +func (r *rwState) doSetWriteDeadline(deadline time.Time) error { + if r.setWriteDeadline != nil { + return r.setWriteDeadline(deadline) + } + return r.w.(deadliner).SetWriteDeadline(deadline) +} + +func (r *rwState) doEnableFullDuplex() error { + if r.enableFullDuplex != nil { + return r.enableFullDuplex() + } + return r.w.(fullDuplexEnabler).EnableFullDuplex() +} + +func (r *rwState) doPush(target string, opts *http.PushOptions) error { + if r.push != nil { + return r.push(target, opts) + } + return r.w.(http.Pusher).Push(target, opts) +} + +func (r *rwState) doWriteString(s string) (int, error) { + if r.writeString != nil { + return r.writeString(s) + } + return r.w.(io.StringWriter).WriteString(s) +} + +// combination 1/512: http.ResponseWriter +type rw0 rwState + +func (w *rw0) Unwrap() http.ResponseWriter { return w.w } +func (w *rw0) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw0) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw0) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} + +// combination 2/512: http.ResponseWriter, io.StringWriter +type rw1 rwState + +func (w *rw1) Unwrap() http.ResponseWriter { return w.w } +func (w *rw1) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw1) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw1) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw1) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 3/512: http.ResponseWriter, http.Pusher +type rw2 rwState + +func (w *rw2) Unwrap() http.ResponseWriter { return w.w } +func (w *rw2) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw2) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw2) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw2) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 4/512: http.ResponseWriter, http.Pusher, io.StringWriter +type rw3 rwState + +func (w *rw3) Unwrap() http.ResponseWriter { return w.w } +func (w *rw3) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw3) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw3) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw3) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw3) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 5/512: http.ResponseWriter, fullDuplexEnabler +type rw4 rwState + +func (w *rw4) Unwrap() http.ResponseWriter { return w.w } +func (w *rw4) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw4) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw4) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw4) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 6/512: http.ResponseWriter, fullDuplexEnabler, io.StringWriter +type rw5 rwState + +func (w *rw5) Unwrap() http.ResponseWriter { return w.w } +func (w *rw5) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw5) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw5) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw5) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw5) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 7/512: http.ResponseWriter, fullDuplexEnabler, http.Pusher +type rw6 rwState + +func (w *rw6) Unwrap() http.ResponseWriter { return w.w } +func (w *rw6) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw6) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw6) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw6) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw6) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 8/512: http.ResponseWriter, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw7 rwState + +func (w *rw7) Unwrap() http.ResponseWriter { return w.w } +func (w *rw7) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw7) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw7) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw7) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw7) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw7) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 9/512: http.ResponseWriter, deadliner +type rw8 rwState + +func (w *rw8) Unwrap() http.ResponseWriter { return w.w } +func (w *rw8) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw8) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw8) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw8) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw8) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 10/512: http.ResponseWriter, deadliner, io.StringWriter +type rw9 rwState + +func (w *rw9) Unwrap() http.ResponseWriter { return w.w } +func (w *rw9) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw9) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw9) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw9) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw9) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw9) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 11/512: http.ResponseWriter, deadliner, http.Pusher +type rw10 rwState + +func (w *rw10) Unwrap() http.ResponseWriter { return w.w } +func (w *rw10) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw10) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw10) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw10) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw10) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw10) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 12/512: http.ResponseWriter, deadliner, http.Pusher, io.StringWriter +type rw11 rwState + +func (w *rw11) Unwrap() http.ResponseWriter { return w.w } +func (w *rw11) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw11) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw11) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw11) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw11) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw11) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw11) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 13/512: http.ResponseWriter, deadliner, fullDuplexEnabler +type rw12 rwState + +func (w *rw12) Unwrap() http.ResponseWriter { return w.w } +func (w *rw12) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw12) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw12) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw12) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw12) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw12) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 14/512: http.ResponseWriter, deadliner, fullDuplexEnabler, io.StringWriter +type rw13 rwState + +func (w *rw13) Unwrap() http.ResponseWriter { return w.w } +func (w *rw13) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw13) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw13) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw13) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw13) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw13) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw13) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 15/512: http.ResponseWriter, deadliner, fullDuplexEnabler, http.Pusher +type rw14 rwState + +func (w *rw14) Unwrap() http.ResponseWriter { return w.w } +func (w *rw14) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw14) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw14) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw14) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw14) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw14) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw14) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 16/512: http.ResponseWriter, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw15 rwState + +func (w *rw15) Unwrap() http.ResponseWriter { return w.w } +func (w *rw15) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw15) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw15) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw15) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw15) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw15) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw15) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw15) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 17/512: http.ResponseWriter, io.ReaderFrom +type rw16 rwState + +func (w *rw16) Unwrap() http.ResponseWriter { return w.w } +func (w *rw16) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw16) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw16) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw16) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 18/512: http.ResponseWriter, io.ReaderFrom, io.StringWriter +type rw17 rwState + +func (w *rw17) Unwrap() http.ResponseWriter { return w.w } +func (w *rw17) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw17) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw17) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw17) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw17) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 19/512: http.ResponseWriter, io.ReaderFrom, http.Pusher +type rw18 rwState + +func (w *rw18) Unwrap() http.ResponseWriter { return w.w } +func (w *rw18) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw18) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw18) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw18) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw18) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 20/512: http.ResponseWriter, io.ReaderFrom, http.Pusher, io.StringWriter +type rw19 rwState + +func (w *rw19) Unwrap() http.ResponseWriter { return w.w } +func (w *rw19) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw19) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw19) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw19) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw19) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw19) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 21/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler +type rw20 rwState + +func (w *rw20) Unwrap() http.ResponseWriter { return w.w } +func (w *rw20) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw20) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw20) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw20) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw20) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 22/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw21 rwState + +func (w *rw21) Unwrap() http.ResponseWriter { return w.w } +func (w *rw21) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw21) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw21) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw21) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw21) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw21) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 23/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw22 rwState + +func (w *rw22) Unwrap() http.ResponseWriter { return w.w } +func (w *rw22) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw22) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw22) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw22) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw22) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw22) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 24/512: http.ResponseWriter, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw23 rwState + +func (w *rw23) Unwrap() http.ResponseWriter { return w.w } +func (w *rw23) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw23) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw23) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw23) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw23) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw23) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw23) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 25/512: http.ResponseWriter, io.ReaderFrom, deadliner +type rw24 rwState + +func (w *rw24) Unwrap() http.ResponseWriter { return w.w } +func (w *rw24) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw24) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw24) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw24) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw24) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw24) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 26/512: http.ResponseWriter, io.ReaderFrom, deadliner, io.StringWriter +type rw25 rwState + +func (w *rw25) Unwrap() http.ResponseWriter { return w.w } +func (w *rw25) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw25) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw25) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw25) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw25) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw25) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw25) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 27/512: http.ResponseWriter, io.ReaderFrom, deadliner, http.Pusher +type rw26 rwState + +func (w *rw26) Unwrap() http.ResponseWriter { return w.w } +func (w *rw26) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw26) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw26) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw26) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw26) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw26) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw26) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 28/512: http.ResponseWriter, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw27 rwState + +func (w *rw27) Unwrap() http.ResponseWriter { return w.w } +func (w *rw27) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw27) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw27) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw27) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw27) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw27) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw27) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw27) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 29/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw28 rwState + +func (w *rw28) Unwrap() http.ResponseWriter { return w.w } +func (w *rw28) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw28) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw28) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw28) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw28) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw28) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw28) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 30/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw29 rwState + +func (w *rw29) Unwrap() http.ResponseWriter { return w.w } +func (w *rw29) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw29) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw29) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw29) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw29) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw29) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw29) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw29) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 31/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw30 rwState + +func (w *rw30) Unwrap() http.ResponseWriter { return w.w } +func (w *rw30) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw30) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw30) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw30) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw30) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw30) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw30) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw30) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 32/512: http.ResponseWriter, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw31 rwState + +func (w *rw31) Unwrap() http.ResponseWriter { return w.w } +func (w *rw31) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw31) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw31) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw31) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw31) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw31) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw31) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw31) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw31) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 33/512: http.ResponseWriter, http.Hijacker +type rw32 rwState + +func (w *rw32) Unwrap() http.ResponseWriter { return w.w } +func (w *rw32) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw32) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw32) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw32) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 34/512: http.ResponseWriter, http.Hijacker, io.StringWriter +type rw33 rwState + +func (w *rw33) Unwrap() http.ResponseWriter { return w.w } +func (w *rw33) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw33) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw33) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw33) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw33) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 35/512: http.ResponseWriter, http.Hijacker, http.Pusher +type rw34 rwState + +func (w *rw34) Unwrap() http.ResponseWriter { return w.w } +func (w *rw34) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw34) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw34) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw34) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw34) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 36/512: http.ResponseWriter, http.Hijacker, http.Pusher, io.StringWriter +type rw35 rwState + +func (w *rw35) Unwrap() http.ResponseWriter { return w.w } +func (w *rw35) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw35) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw35) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw35) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw35) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw35) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 37/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler +type rw36 rwState + +func (w *rw36) Unwrap() http.ResponseWriter { return w.w } +func (w *rw36) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw36) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw36) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw36) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw36) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 38/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw37 rwState + +func (w *rw37) Unwrap() http.ResponseWriter { return w.w } +func (w *rw37) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw37) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw37) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw37) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw37) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw37) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 39/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw38 rwState + +func (w *rw38) Unwrap() http.ResponseWriter { return w.w } +func (w *rw38) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw38) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw38) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw38) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw38) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw38) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 40/512: http.ResponseWriter, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw39 rwState + +func (w *rw39) Unwrap() http.ResponseWriter { return w.w } +func (w *rw39) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw39) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw39) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw39) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw39) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw39) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw39) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 41/512: http.ResponseWriter, http.Hijacker, deadliner +type rw40 rwState + +func (w *rw40) Unwrap() http.ResponseWriter { return w.w } +func (w *rw40) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw40) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw40) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw40) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw40) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw40) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 42/512: http.ResponseWriter, http.Hijacker, deadliner, io.StringWriter +type rw41 rwState + +func (w *rw41) Unwrap() http.ResponseWriter { return w.w } +func (w *rw41) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw41) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw41) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw41) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw41) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw41) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw41) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 43/512: http.ResponseWriter, http.Hijacker, deadliner, http.Pusher +type rw42 rwState + +func (w *rw42) Unwrap() http.ResponseWriter { return w.w } +func (w *rw42) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw42) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw42) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw42) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw42) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw42) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw42) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 44/512: http.ResponseWriter, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw43 rwState + +func (w *rw43) Unwrap() http.ResponseWriter { return w.w } +func (w *rw43) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw43) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw43) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw43) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw43) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw43) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw43) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw43) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 45/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler +type rw44 rwState + +func (w *rw44) Unwrap() http.ResponseWriter { return w.w } +func (w *rw44) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw44) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw44) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw44) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw44) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw44) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw44) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 46/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw45 rwState + +func (w *rw45) Unwrap() http.ResponseWriter { return w.w } +func (w *rw45) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw45) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw45) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw45) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw45) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw45) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw45) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw45) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 47/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw46 rwState + +func (w *rw46) Unwrap() http.ResponseWriter { return w.w } +func (w *rw46) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw46) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw46) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw46) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw46) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw46) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw46) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw46) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 48/512: http.ResponseWriter, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw47 rwState + +func (w *rw47) Unwrap() http.ResponseWriter { return w.w } +func (w *rw47) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw47) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw47) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw47) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw47) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw47) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw47) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw47) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw47) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 49/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom +type rw48 rwState + +func (w *rw48) Unwrap() http.ResponseWriter { return w.w } +func (w *rw48) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw48) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw48) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw48) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw48) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 50/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw49 rwState + +func (w *rw49) Unwrap() http.ResponseWriter { return w.w } +func (w *rw49) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw49) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw49) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw49) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw49) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw49) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 51/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, http.Pusher +type rw50 rwState + +func (w *rw50) Unwrap() http.ResponseWriter { return w.w } +func (w *rw50) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw50) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw50) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw50) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw50) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw50) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 52/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw51 rwState + +func (w *rw51) Unwrap() http.ResponseWriter { return w.w } +func (w *rw51) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw51) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw51) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw51) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw51) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw51) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw51) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 53/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw52 rwState + +func (w *rw52) Unwrap() http.ResponseWriter { return w.w } +func (w *rw52) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw52) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw52) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw52) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw52) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw52) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 54/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw53 rwState + +func (w *rw53) Unwrap() http.ResponseWriter { return w.w } +func (w *rw53) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw53) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw53) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw53) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw53) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw53) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw53) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 55/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw54 rwState + +func (w *rw54) Unwrap() http.ResponseWriter { return w.w } +func (w *rw54) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw54) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw54) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw54) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw54) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw54) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw54) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 56/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw55 rwState + +func (w *rw55) Unwrap() http.ResponseWriter { return w.w } +func (w *rw55) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw55) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw55) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw55) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw55) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw55) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw55) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw55) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 57/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner +type rw56 rwState + +func (w *rw56) Unwrap() http.ResponseWriter { return w.w } +func (w *rw56) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw56) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw56) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw56) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw56) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw56) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw56) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 58/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw57 rwState + +func (w *rw57) Unwrap() http.ResponseWriter { return w.w } +func (w *rw57) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw57) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw57) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw57) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw57) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw57) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw57) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw57) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 59/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw58 rwState + +func (w *rw58) Unwrap() http.ResponseWriter { return w.w } +func (w *rw58) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw58) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw58) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw58) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw58) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw58) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw58) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw58) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 60/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw59 rwState + +func (w *rw59) Unwrap() http.ResponseWriter { return w.w } +func (w *rw59) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw59) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw59) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw59) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw59) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw59) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw59) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw59) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw59) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 61/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw60 rwState + +func (w *rw60) Unwrap() http.ResponseWriter { return w.w } +func (w *rw60) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw60) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw60) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw60) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw60) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw60) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw60) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw60) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 62/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw61 rwState + +func (w *rw61) Unwrap() http.ResponseWriter { return w.w } +func (w *rw61) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw61) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw61) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw61) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw61) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw61) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw61) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw61) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw61) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 63/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw62 rwState + +func (w *rw62) Unwrap() http.ResponseWriter { return w.w } +func (w *rw62) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw62) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw62) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw62) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw62) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw62) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw62) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw62) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw62) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 64/512: http.ResponseWriter, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw63 rwState + +func (w *rw63) Unwrap() http.ResponseWriter { return w.w } +func (w *rw63) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw63) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw63) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw63) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw63) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw63) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw63) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw63) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw63) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw63) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 65/512: http.ResponseWriter, http.CloseNotifier +type rw64 rwState + +func (w *rw64) Unwrap() http.ResponseWriter { return w.w } +func (w *rw64) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw64) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw64) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw64) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 66/512: http.ResponseWriter, http.CloseNotifier, io.StringWriter +type rw65 rwState + +func (w *rw65) Unwrap() http.ResponseWriter { return w.w } +func (w *rw65) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw65) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw65) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw65) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw65) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 67/512: http.ResponseWriter, http.CloseNotifier, http.Pusher +type rw66 rwState + +func (w *rw66) Unwrap() http.ResponseWriter { return w.w } +func (w *rw66) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw66) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw66) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw66) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw66) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 68/512: http.ResponseWriter, http.CloseNotifier, http.Pusher, io.StringWriter +type rw67 rwState + +func (w *rw67) Unwrap() http.ResponseWriter { return w.w } +func (w *rw67) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw67) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw67) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw67) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw67) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw67) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 69/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler +type rw68 rwState + +func (w *rw68) Unwrap() http.ResponseWriter { return w.w } +func (w *rw68) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw68) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw68) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw68) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw68) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 70/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw69 rwState + +func (w *rw69) Unwrap() http.ResponseWriter { return w.w } +func (w *rw69) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw69) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw69) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw69) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw69) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw69) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 71/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw70 rwState + +func (w *rw70) Unwrap() http.ResponseWriter { return w.w } +func (w *rw70) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw70) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw70) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw70) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw70) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw70) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 72/512: http.ResponseWriter, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw71 rwState + +func (w *rw71) Unwrap() http.ResponseWriter { return w.w } +func (w *rw71) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw71) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw71) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw71) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw71) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw71) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw71) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 73/512: http.ResponseWriter, http.CloseNotifier, deadliner +type rw72 rwState + +func (w *rw72) Unwrap() http.ResponseWriter { return w.w } +func (w *rw72) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw72) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw72) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw72) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw72) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw72) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 74/512: http.ResponseWriter, http.CloseNotifier, deadliner, io.StringWriter +type rw73 rwState + +func (w *rw73) Unwrap() http.ResponseWriter { return w.w } +func (w *rw73) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw73) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw73) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw73) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw73) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw73) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw73) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 75/512: http.ResponseWriter, http.CloseNotifier, deadliner, http.Pusher +type rw74 rwState + +func (w *rw74) Unwrap() http.ResponseWriter { return w.w } +func (w *rw74) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw74) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw74) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw74) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw74) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw74) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw74) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 76/512: http.ResponseWriter, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw75 rwState + +func (w *rw75) Unwrap() http.ResponseWriter { return w.w } +func (w *rw75) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw75) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw75) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw75) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw75) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw75) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw75) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw75) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 77/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw76 rwState + +func (w *rw76) Unwrap() http.ResponseWriter { return w.w } +func (w *rw76) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw76) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw76) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw76) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw76) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw76) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw76) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 78/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw77 rwState + +func (w *rw77) Unwrap() http.ResponseWriter { return w.w } +func (w *rw77) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw77) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw77) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw77) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw77) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw77) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw77) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw77) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 79/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw78 rwState + +func (w *rw78) Unwrap() http.ResponseWriter { return w.w } +func (w *rw78) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw78) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw78) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw78) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw78) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw78) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw78) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw78) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 80/512: http.ResponseWriter, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw79 rwState + +func (w *rw79) Unwrap() http.ResponseWriter { return w.w } +func (w *rw79) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw79) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw79) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw79) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw79) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw79) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw79) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw79) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw79) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 81/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom +type rw80 rwState + +func (w *rw80) Unwrap() http.ResponseWriter { return w.w } +func (w *rw80) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw80) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw80) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw80) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw80) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 82/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw81 rwState + +func (w *rw81) Unwrap() http.ResponseWriter { return w.w } +func (w *rw81) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw81) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw81) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw81) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw81) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw81) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 83/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw82 rwState + +func (w *rw82) Unwrap() http.ResponseWriter { return w.w } +func (w *rw82) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw82) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw82) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw82) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw82) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw82) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 84/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw83 rwState + +func (w *rw83) Unwrap() http.ResponseWriter { return w.w } +func (w *rw83) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw83) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw83) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw83) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw83) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw83) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw83) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 85/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw84 rwState + +func (w *rw84) Unwrap() http.ResponseWriter { return w.w } +func (w *rw84) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw84) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw84) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw84) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw84) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw84) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 86/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw85 rwState + +func (w *rw85) Unwrap() http.ResponseWriter { return w.w } +func (w *rw85) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw85) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw85) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw85) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw85) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw85) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw85) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 87/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw86 rwState + +func (w *rw86) Unwrap() http.ResponseWriter { return w.w } +func (w *rw86) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw86) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw86) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw86) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw86) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw86) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw86) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 88/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw87 rwState + +func (w *rw87) Unwrap() http.ResponseWriter { return w.w } +func (w *rw87) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw87) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw87) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw87) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw87) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw87) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw87) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw87) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 89/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner +type rw88 rwState + +func (w *rw88) Unwrap() http.ResponseWriter { return w.w } +func (w *rw88) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw88) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw88) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw88) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw88) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw88) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw88) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 90/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw89 rwState + +func (w *rw89) Unwrap() http.ResponseWriter { return w.w } +func (w *rw89) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw89) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw89) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw89) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw89) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw89) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw89) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw89) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 91/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw90 rwState + +func (w *rw90) Unwrap() http.ResponseWriter { return w.w } +func (w *rw90) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw90) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw90) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw90) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw90) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw90) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw90) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw90) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 92/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw91 rwState + +func (w *rw91) Unwrap() http.ResponseWriter { return w.w } +func (w *rw91) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw91) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw91) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw91) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw91) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw91) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw91) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw91) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw91) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 93/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw92 rwState + +func (w *rw92) Unwrap() http.ResponseWriter { return w.w } +func (w *rw92) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw92) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw92) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw92) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw92) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw92) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw92) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw92) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 94/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw93 rwState + +func (w *rw93) Unwrap() http.ResponseWriter { return w.w } +func (w *rw93) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw93) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw93) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw93) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw93) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw93) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw93) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw93) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw93) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 95/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw94 rwState + +func (w *rw94) Unwrap() http.ResponseWriter { return w.w } +func (w *rw94) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw94) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw94) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw94) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw94) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw94) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw94) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw94) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw94) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 96/512: http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw95 rwState + +func (w *rw95) Unwrap() http.ResponseWriter { return w.w } +func (w *rw95) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw95) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw95) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw95) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw95) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw95) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw95) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw95) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw95) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw95) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 97/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker +type rw96 rwState + +func (w *rw96) Unwrap() http.ResponseWriter { return w.w } +func (w *rw96) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw96) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw96) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw96) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw96) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 98/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw97 rwState + +func (w *rw97) Unwrap() http.ResponseWriter { return w.w } +func (w *rw97) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw97) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw97) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw97) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw97) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw97) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 99/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, http.Pusher +type rw98 rwState + +func (w *rw98) Unwrap() http.ResponseWriter { return w.w } +func (w *rw98) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw98) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw98) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw98) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw98) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw98) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 100/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw99 rwState + +func (w *rw99) Unwrap() http.ResponseWriter { return w.w } +func (w *rw99) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw99) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw99) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw99) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw99) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw99) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw99) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 101/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw100 rwState + +func (w *rw100) Unwrap() http.ResponseWriter { return w.w } +func (w *rw100) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw100) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw100) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw100) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw100) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw100) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 102/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw101 rwState + +func (w *rw101) Unwrap() http.ResponseWriter { return w.w } +func (w *rw101) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw101) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw101) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw101) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw101) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw101) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw101) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 103/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw102 rwState + +func (w *rw102) Unwrap() http.ResponseWriter { return w.w } +func (w *rw102) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw102) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw102) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw102) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw102) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw102) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw102) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 104/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw103 rwState + +func (w *rw103) Unwrap() http.ResponseWriter { return w.w } +func (w *rw103) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw103) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw103) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw103) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw103) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw103) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw103) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw103) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 105/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner +type rw104 rwState + +func (w *rw104) Unwrap() http.ResponseWriter { return w.w } +func (w *rw104) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw104) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw104) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw104) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw104) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw104) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw104) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 106/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw105 rwState + +func (w *rw105) Unwrap() http.ResponseWriter { return w.w } +func (w *rw105) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw105) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw105) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw105) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw105) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw105) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw105) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw105) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 107/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw106 rwState + +func (w *rw106) Unwrap() http.ResponseWriter { return w.w } +func (w *rw106) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw106) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw106) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw106) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw106) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw106) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw106) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw106) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 108/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw107 rwState + +func (w *rw107) Unwrap() http.ResponseWriter { return w.w } +func (w *rw107) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw107) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw107) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw107) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw107) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw107) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw107) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw107) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw107) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 109/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw108 rwState + +func (w *rw108) Unwrap() http.ResponseWriter { return w.w } +func (w *rw108) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw108) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw108) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw108) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw108) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw108) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw108) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw108) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 110/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw109 rwState + +func (w *rw109) Unwrap() http.ResponseWriter { return w.w } +func (w *rw109) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw109) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw109) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw109) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw109) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw109) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw109) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw109) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw109) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 111/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw110 rwState + +func (w *rw110) Unwrap() http.ResponseWriter { return w.w } +func (w *rw110) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw110) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw110) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw110) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw110) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw110) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw110) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw110) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw110) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 112/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw111 rwState + +func (w *rw111) Unwrap() http.ResponseWriter { return w.w } +func (w *rw111) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw111) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw111) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw111) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw111) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw111) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw111) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw111) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw111) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw111) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 113/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw112 rwState + +func (w *rw112) Unwrap() http.ResponseWriter { return w.w } +func (w *rw112) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw112) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw112) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw112) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw112) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw112) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 114/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw113 rwState + +func (w *rw113) Unwrap() http.ResponseWriter { return w.w } +func (w *rw113) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw113) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw113) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw113) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw113) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw113) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw113) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 115/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw114 rwState + +func (w *rw114) Unwrap() http.ResponseWriter { return w.w } +func (w *rw114) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw114) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw114) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw114) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw114) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw114) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw114) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 116/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw115 rwState + +func (w *rw115) Unwrap() http.ResponseWriter { return w.w } +func (w *rw115) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw115) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw115) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw115) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw115) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw115) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw115) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw115) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 117/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw116 rwState + +func (w *rw116) Unwrap() http.ResponseWriter { return w.w } +func (w *rw116) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw116) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw116) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw116) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw116) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw116) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw116) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 118/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw117 rwState + +func (w *rw117) Unwrap() http.ResponseWriter { return w.w } +func (w *rw117) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw117) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw117) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw117) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw117) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw117) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw117) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw117) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 119/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw118 rwState + +func (w *rw118) Unwrap() http.ResponseWriter { return w.w } +func (w *rw118) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw118) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw118) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw118) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw118) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw118) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw118) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw118) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 120/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw119 rwState + +func (w *rw119) Unwrap() http.ResponseWriter { return w.w } +func (w *rw119) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw119) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw119) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw119) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw119) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw119) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw119) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw119) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw119) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 121/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw120 rwState + +func (w *rw120) Unwrap() http.ResponseWriter { return w.w } +func (w *rw120) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw120) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw120) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw120) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw120) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw120) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw120) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw120) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 122/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw121 rwState + +func (w *rw121) Unwrap() http.ResponseWriter { return w.w } +func (w *rw121) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw121) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw121) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw121) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw121) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw121) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw121) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw121) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw121) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 123/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw122 rwState + +func (w *rw122) Unwrap() http.ResponseWriter { return w.w } +func (w *rw122) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw122) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw122) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw122) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw122) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw122) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw122) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw122) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw122) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 124/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw123 rwState + +func (w *rw123) Unwrap() http.ResponseWriter { return w.w } +func (w *rw123) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw123) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw123) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw123) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw123) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw123) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw123) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw123) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw123) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw123) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 125/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw124 rwState + +func (w *rw124) Unwrap() http.ResponseWriter { return w.w } +func (w *rw124) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw124) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw124) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw124) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw124) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw124) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw124) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw124) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw124) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 126/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw125 rwState + +func (w *rw125) Unwrap() http.ResponseWriter { return w.w } +func (w *rw125) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw125) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw125) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw125) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw125) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw125) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw125) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw125) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw125) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw125) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 127/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw126 rwState + +func (w *rw126) Unwrap() http.ResponseWriter { return w.w } +func (w *rw126) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw126) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw126) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw126) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw126) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw126) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw126) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw126) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw126) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw126) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 128/512: http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw127 rwState + +func (w *rw127) Unwrap() http.ResponseWriter { return w.w } +func (w *rw127) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw127) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw127) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw127) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw127) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw127) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw127) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw127) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw127) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw127) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw127) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 129/512: http.ResponseWriter, httpFlushError +type rw128 rwState + +func (w *rw128) Unwrap() http.ResponseWriter { return w.w } +func (w *rw128) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw128) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw128) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw128) FlushError() error { + return (*rwState)(w).doFlushError() +} + +// combination 130/512: http.ResponseWriter, httpFlushError, io.StringWriter +type rw129 rwState + +func (w *rw129) Unwrap() http.ResponseWriter { return w.w } +func (w *rw129) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw129) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw129) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw129) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw129) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 131/512: http.ResponseWriter, httpFlushError, http.Pusher +type rw130 rwState + +func (w *rw130) Unwrap() http.ResponseWriter { return w.w } +func (w *rw130) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw130) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw130) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw130) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw130) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 132/512: http.ResponseWriter, httpFlushError, http.Pusher, io.StringWriter +type rw131 rwState + +func (w *rw131) Unwrap() http.ResponseWriter { return w.w } +func (w *rw131) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw131) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw131) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw131) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw131) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw131) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 133/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler +type rw132 rwState + +func (w *rw132) Unwrap() http.ResponseWriter { return w.w } +func (w *rw132) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw132) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw132) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw132) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw132) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 134/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler, io.StringWriter +type rw133 rwState + +func (w *rw133) Unwrap() http.ResponseWriter { return w.w } +func (w *rw133) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw133) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw133) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw133) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw133) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw133) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 135/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler, http.Pusher +type rw134 rwState + +func (w *rw134) Unwrap() http.ResponseWriter { return w.w } +func (w *rw134) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw134) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw134) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw134) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw134) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw134) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 136/512: http.ResponseWriter, httpFlushError, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw135 rwState + +func (w *rw135) Unwrap() http.ResponseWriter { return w.w } +func (w *rw135) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw135) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw135) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw135) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw135) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw135) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw135) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 137/512: http.ResponseWriter, httpFlushError, deadliner +type rw136 rwState + +func (w *rw136) Unwrap() http.ResponseWriter { return w.w } +func (w *rw136) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw136) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw136) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw136) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw136) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw136) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 138/512: http.ResponseWriter, httpFlushError, deadliner, io.StringWriter +type rw137 rwState + +func (w *rw137) Unwrap() http.ResponseWriter { return w.w } +func (w *rw137) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw137) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw137) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw137) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw137) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw137) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw137) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 139/512: http.ResponseWriter, httpFlushError, deadliner, http.Pusher +type rw138 rwState + +func (w *rw138) Unwrap() http.ResponseWriter { return w.w } +func (w *rw138) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw138) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw138) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw138) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw138) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw138) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw138) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 140/512: http.ResponseWriter, httpFlushError, deadliner, http.Pusher, io.StringWriter +type rw139 rwState + +func (w *rw139) Unwrap() http.ResponseWriter { return w.w } +func (w *rw139) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw139) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw139) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw139) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw139) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw139) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw139) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw139) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 141/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler +type rw140 rwState + +func (w *rw140) Unwrap() http.ResponseWriter { return w.w } +func (w *rw140) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw140) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw140) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw140) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw140) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw140) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw140) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 142/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler, io.StringWriter +type rw141 rwState + +func (w *rw141) Unwrap() http.ResponseWriter { return w.w } +func (w *rw141) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw141) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw141) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw141) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw141) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw141) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw141) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw141) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 143/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher +type rw142 rwState + +func (w *rw142) Unwrap() http.ResponseWriter { return w.w } +func (w *rw142) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw142) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw142) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw142) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw142) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw142) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw142) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw142) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 144/512: http.ResponseWriter, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw143 rwState + +func (w *rw143) Unwrap() http.ResponseWriter { return w.w } +func (w *rw143) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw143) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw143) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw143) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw143) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw143) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw143) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw143) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw143) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 145/512: http.ResponseWriter, httpFlushError, io.ReaderFrom +type rw144 rwState + +func (w *rw144) Unwrap() http.ResponseWriter { return w.w } +func (w *rw144) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw144) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw144) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw144) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw144) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 146/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, io.StringWriter +type rw145 rwState + +func (w *rw145) Unwrap() http.ResponseWriter { return w.w } +func (w *rw145) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw145) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw145) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw145) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw145) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw145) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 147/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, http.Pusher +type rw146 rwState + +func (w *rw146) Unwrap() http.ResponseWriter { return w.w } +func (w *rw146) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw146) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw146) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw146) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw146) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw146) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 148/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, http.Pusher, io.StringWriter +type rw147 rwState + +func (w *rw147) Unwrap() http.ResponseWriter { return w.w } +func (w *rw147) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw147) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw147) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw147) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw147) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw147) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw147) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 149/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler +type rw148 rwState + +func (w *rw148) Unwrap() http.ResponseWriter { return w.w } +func (w *rw148) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw148) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw148) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw148) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw148) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw148) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 150/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw149 rwState + +func (w *rw149) Unwrap() http.ResponseWriter { return w.w } +func (w *rw149) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw149) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw149) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw149) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw149) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw149) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw149) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 151/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw150 rwState + +func (w *rw150) Unwrap() http.ResponseWriter { return w.w } +func (w *rw150) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw150) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw150) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw150) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw150) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw150) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw150) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 152/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw151 rwState + +func (w *rw151) Unwrap() http.ResponseWriter { return w.w } +func (w *rw151) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw151) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw151) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw151) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw151) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw151) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw151) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw151) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 153/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner +type rw152 rwState + +func (w *rw152) Unwrap() http.ResponseWriter { return w.w } +func (w *rw152) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw152) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw152) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw152) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw152) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw152) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw152) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 154/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, io.StringWriter +type rw153 rwState + +func (w *rw153) Unwrap() http.ResponseWriter { return w.w } +func (w *rw153) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw153) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw153) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw153) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw153) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw153) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw153) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw153) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 155/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, http.Pusher +type rw154 rwState + +func (w *rw154) Unwrap() http.ResponseWriter { return w.w } +func (w *rw154) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw154) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw154) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw154) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw154) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw154) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw154) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw154) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 156/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw155 rwState + +func (w *rw155) Unwrap() http.ResponseWriter { return w.w } +func (w *rw155) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw155) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw155) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw155) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw155) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw155) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw155) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw155) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw155) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 157/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw156 rwState + +func (w *rw156) Unwrap() http.ResponseWriter { return w.w } +func (w *rw156) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw156) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw156) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw156) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw156) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw156) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw156) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw156) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 158/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw157 rwState + +func (w *rw157) Unwrap() http.ResponseWriter { return w.w } +func (w *rw157) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw157) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw157) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw157) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw157) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw157) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw157) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw157) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw157) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 159/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw158 rwState + +func (w *rw158) Unwrap() http.ResponseWriter { return w.w } +func (w *rw158) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw158) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw158) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw158) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw158) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw158) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw158) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw158) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw158) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 160/512: http.ResponseWriter, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw159 rwState + +func (w *rw159) Unwrap() http.ResponseWriter { return w.w } +func (w *rw159) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw159) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw159) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw159) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw159) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw159) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw159) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw159) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw159) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw159) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 161/512: http.ResponseWriter, httpFlushError, http.Hijacker +type rw160 rwState + +func (w *rw160) Unwrap() http.ResponseWriter { return w.w } +func (w *rw160) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw160) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw160) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw160) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw160) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 162/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.StringWriter +type rw161 rwState + +func (w *rw161) Unwrap() http.ResponseWriter { return w.w } +func (w *rw161) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw161) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw161) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw161) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw161) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw161) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 163/512: http.ResponseWriter, httpFlushError, http.Hijacker, http.Pusher +type rw162 rwState + +func (w *rw162) Unwrap() http.ResponseWriter { return w.w } +func (w *rw162) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw162) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw162) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw162) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw162) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw162) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 164/512: http.ResponseWriter, httpFlushError, http.Hijacker, http.Pusher, io.StringWriter +type rw163 rwState + +func (w *rw163) Unwrap() http.ResponseWriter { return w.w } +func (w *rw163) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw163) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw163) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw163) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw163) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw163) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw163) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 165/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler +type rw164 rwState + +func (w *rw164) Unwrap() http.ResponseWriter { return w.w } +func (w *rw164) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw164) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw164) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw164) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw164) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw164) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 166/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw165 rwState + +func (w *rw165) Unwrap() http.ResponseWriter { return w.w } +func (w *rw165) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw165) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw165) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw165) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw165) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw165) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw165) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 167/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw166 rwState + +func (w *rw166) Unwrap() http.ResponseWriter { return w.w } +func (w *rw166) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw166) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw166) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw166) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw166) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw166) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw166) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 168/512: http.ResponseWriter, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw167 rwState + +func (w *rw167) Unwrap() http.ResponseWriter { return w.w } +func (w *rw167) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw167) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw167) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw167) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw167) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw167) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw167) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw167) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 169/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner +type rw168 rwState + +func (w *rw168) Unwrap() http.ResponseWriter { return w.w } +func (w *rw168) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw168) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw168) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw168) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw168) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw168) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw168) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 170/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, io.StringWriter +type rw169 rwState + +func (w *rw169) Unwrap() http.ResponseWriter { return w.w } +func (w *rw169) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw169) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw169) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw169) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw169) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw169) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw169) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw169) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 171/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, http.Pusher +type rw170 rwState + +func (w *rw170) Unwrap() http.ResponseWriter { return w.w } +func (w *rw170) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw170) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw170) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw170) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw170) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw170) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw170) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw170) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 172/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw171 rwState + +func (w *rw171) Unwrap() http.ResponseWriter { return w.w } +func (w *rw171) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw171) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw171) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw171) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw171) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw171) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw171) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw171) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw171) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 173/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler +type rw172 rwState + +func (w *rw172) Unwrap() http.ResponseWriter { return w.w } +func (w *rw172) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw172) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw172) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw172) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw172) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw172) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw172) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw172) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 174/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw173 rwState + +func (w *rw173) Unwrap() http.ResponseWriter { return w.w } +func (w *rw173) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw173) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw173) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw173) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw173) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw173) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw173) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw173) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw173) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 175/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw174 rwState + +func (w *rw174) Unwrap() http.ResponseWriter { return w.w } +func (w *rw174) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw174) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw174) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw174) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw174) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw174) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw174) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw174) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw174) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 176/512: http.ResponseWriter, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw175 rwState + +func (w *rw175) Unwrap() http.ResponseWriter { return w.w } +func (w *rw175) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw175) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw175) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw175) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw175) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw175) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw175) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw175) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw175) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw175) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 177/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom +type rw176 rwState + +func (w *rw176) Unwrap() http.ResponseWriter { return w.w } +func (w *rw176) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw176) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw176) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw176) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw176) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw176) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 178/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw177 rwState + +func (w *rw177) Unwrap() http.ResponseWriter { return w.w } +func (w *rw177) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw177) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw177) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw177) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw177) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw177) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw177) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 179/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher +type rw178 rwState + +func (w *rw178) Unwrap() http.ResponseWriter { return w.w } +func (w *rw178) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw178) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw178) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw178) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw178) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw178) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw178) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 180/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw179 rwState + +func (w *rw179) Unwrap() http.ResponseWriter { return w.w } +func (w *rw179) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw179) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw179) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw179) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw179) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw179) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw179) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw179) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 181/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw180 rwState + +func (w *rw180) Unwrap() http.ResponseWriter { return w.w } +func (w *rw180) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw180) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw180) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw180) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw180) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw180) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw180) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 182/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw181 rwState + +func (w *rw181) Unwrap() http.ResponseWriter { return w.w } +func (w *rw181) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw181) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw181) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw181) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw181) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw181) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw181) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw181) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 183/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw182 rwState + +func (w *rw182) Unwrap() http.ResponseWriter { return w.w } +func (w *rw182) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw182) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw182) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw182) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw182) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw182) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw182) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw182) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 184/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw183 rwState + +func (w *rw183) Unwrap() http.ResponseWriter { return w.w } +func (w *rw183) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw183) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw183) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw183) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw183) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw183) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw183) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw183) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw183) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 185/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner +type rw184 rwState + +func (w *rw184) Unwrap() http.ResponseWriter { return w.w } +func (w *rw184) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw184) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw184) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw184) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw184) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw184) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw184) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw184) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 186/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw185 rwState + +func (w *rw185) Unwrap() http.ResponseWriter { return w.w } +func (w *rw185) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw185) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw185) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw185) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw185) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw185) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw185) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw185) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw185) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 187/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw186 rwState + +func (w *rw186) Unwrap() http.ResponseWriter { return w.w } +func (w *rw186) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw186) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw186) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw186) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw186) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw186) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw186) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw186) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw186) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 188/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw187 rwState + +func (w *rw187) Unwrap() http.ResponseWriter { return w.w } +func (w *rw187) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw187) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw187) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw187) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw187) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw187) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw187) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw187) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw187) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw187) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 189/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw188 rwState + +func (w *rw188) Unwrap() http.ResponseWriter { return w.w } +func (w *rw188) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw188) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw188) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw188) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw188) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw188) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw188) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw188) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw188) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 190/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw189 rwState + +func (w *rw189) Unwrap() http.ResponseWriter { return w.w } +func (w *rw189) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw189) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw189) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw189) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw189) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw189) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw189) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw189) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw189) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw189) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 191/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw190 rwState + +func (w *rw190) Unwrap() http.ResponseWriter { return w.w } +func (w *rw190) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw190) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw190) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw190) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw190) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw190) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw190) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw190) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw190) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw190) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 192/512: http.ResponseWriter, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw191 rwState + +func (w *rw191) Unwrap() http.ResponseWriter { return w.w } +func (w *rw191) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw191) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw191) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw191) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw191) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw191) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw191) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw191) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw191) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw191) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw191) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 193/512: http.ResponseWriter, httpFlushError, http.CloseNotifier +type rw192 rwState + +func (w *rw192) Unwrap() http.ResponseWriter { return w.w } +func (w *rw192) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw192) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw192) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw192) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw192) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 194/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.StringWriter +type rw193 rwState + +func (w *rw193) Unwrap() http.ResponseWriter { return w.w } +func (w *rw193) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw193) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw193) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw193) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw193) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw193) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 195/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Pusher +type rw194 rwState + +func (w *rw194) Unwrap() http.ResponseWriter { return w.w } +func (w *rw194) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw194) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw194) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw194) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw194) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw194) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 196/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Pusher, io.StringWriter +type rw195 rwState + +func (w *rw195) Unwrap() http.ResponseWriter { return w.w } +func (w *rw195) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw195) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw195) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw195) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw195) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw195) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw195) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 197/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler +type rw196 rwState + +func (w *rw196) Unwrap() http.ResponseWriter { return w.w } +func (w *rw196) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw196) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw196) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw196) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw196) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw196) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 198/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw197 rwState + +func (w *rw197) Unwrap() http.ResponseWriter { return w.w } +func (w *rw197) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw197) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw197) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw197) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw197) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw197) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw197) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 199/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw198 rwState + +func (w *rw198) Unwrap() http.ResponseWriter { return w.w } +func (w *rw198) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw198) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw198) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw198) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw198) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw198) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw198) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 200/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw199 rwState + +func (w *rw199) Unwrap() http.ResponseWriter { return w.w } +func (w *rw199) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw199) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw199) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw199) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw199) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw199) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw199) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw199) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 201/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner +type rw200 rwState + +func (w *rw200) Unwrap() http.ResponseWriter { return w.w } +func (w *rw200) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw200) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw200) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw200) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw200) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw200) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw200) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 202/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, io.StringWriter +type rw201 rwState + +func (w *rw201) Unwrap() http.ResponseWriter { return w.w } +func (w *rw201) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw201) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw201) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw201) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw201) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw201) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw201) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw201) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 203/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, http.Pusher +type rw202 rwState + +func (w *rw202) Unwrap() http.ResponseWriter { return w.w } +func (w *rw202) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw202) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw202) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw202) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw202) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw202) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw202) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw202) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 204/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw203 rwState + +func (w *rw203) Unwrap() http.ResponseWriter { return w.w } +func (w *rw203) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw203) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw203) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw203) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw203) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw203) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw203) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw203) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw203) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 205/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw204 rwState + +func (w *rw204) Unwrap() http.ResponseWriter { return w.w } +func (w *rw204) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw204) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw204) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw204) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw204) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw204) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw204) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw204) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 206/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw205 rwState + +func (w *rw205) Unwrap() http.ResponseWriter { return w.w } +func (w *rw205) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw205) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw205) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw205) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw205) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw205) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw205) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw205) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw205) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 207/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw206 rwState + +func (w *rw206) Unwrap() http.ResponseWriter { return w.w } +func (w *rw206) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw206) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw206) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw206) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw206) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw206) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw206) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw206) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw206) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 208/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw207 rwState + +func (w *rw207) Unwrap() http.ResponseWriter { return w.w } +func (w *rw207) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw207) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw207) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw207) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw207) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw207) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw207) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw207) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw207) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw207) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 209/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom +type rw208 rwState + +func (w *rw208) Unwrap() http.ResponseWriter { return w.w } +func (w *rw208) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw208) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw208) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw208) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw208) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw208) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 210/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw209 rwState + +func (w *rw209) Unwrap() http.ResponseWriter { return w.w } +func (w *rw209) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw209) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw209) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw209) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw209) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw209) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw209) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 211/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw210 rwState + +func (w *rw210) Unwrap() http.ResponseWriter { return w.w } +func (w *rw210) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw210) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw210) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw210) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw210) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw210) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw210) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 212/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw211 rwState + +func (w *rw211) Unwrap() http.ResponseWriter { return w.w } +func (w *rw211) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw211) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw211) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw211) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw211) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw211) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw211) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw211) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 213/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw212 rwState + +func (w *rw212) Unwrap() http.ResponseWriter { return w.w } +func (w *rw212) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw212) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw212) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw212) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw212) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw212) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw212) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 214/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw213 rwState + +func (w *rw213) Unwrap() http.ResponseWriter { return w.w } +func (w *rw213) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw213) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw213) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw213) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw213) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw213) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw213) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw213) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 215/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw214 rwState + +func (w *rw214) Unwrap() http.ResponseWriter { return w.w } +func (w *rw214) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw214) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw214) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw214) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw214) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw214) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw214) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw214) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 216/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw215 rwState + +func (w *rw215) Unwrap() http.ResponseWriter { return w.w } +func (w *rw215) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw215) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw215) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw215) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw215) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw215) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw215) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw215) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw215) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 217/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner +type rw216 rwState + +func (w *rw216) Unwrap() http.ResponseWriter { return w.w } +func (w *rw216) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw216) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw216) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw216) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw216) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw216) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw216) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw216) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 218/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw217 rwState + +func (w *rw217) Unwrap() http.ResponseWriter { return w.w } +func (w *rw217) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw217) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw217) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw217) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw217) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw217) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw217) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw217) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw217) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 219/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw218 rwState + +func (w *rw218) Unwrap() http.ResponseWriter { return w.w } +func (w *rw218) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw218) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw218) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw218) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw218) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw218) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw218) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw218) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw218) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 220/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw219 rwState + +func (w *rw219) Unwrap() http.ResponseWriter { return w.w } +func (w *rw219) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw219) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw219) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw219) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw219) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw219) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw219) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw219) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw219) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw219) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 221/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw220 rwState + +func (w *rw220) Unwrap() http.ResponseWriter { return w.w } +func (w *rw220) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw220) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw220) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw220) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw220) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw220) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw220) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw220) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw220) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 222/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw221 rwState + +func (w *rw221) Unwrap() http.ResponseWriter { return w.w } +func (w *rw221) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw221) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw221) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw221) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw221) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw221) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw221) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw221) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw221) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw221) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 223/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw222 rwState + +func (w *rw222) Unwrap() http.ResponseWriter { return w.w } +func (w *rw222) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw222) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw222) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw222) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw222) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw222) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw222) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw222) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw222) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw222) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 224/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw223 rwState + +func (w *rw223) Unwrap() http.ResponseWriter { return w.w } +func (w *rw223) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw223) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw223) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw223) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw223) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw223) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw223) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw223) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw223) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw223) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw223) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 225/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker +type rw224 rwState + +func (w *rw224) Unwrap() http.ResponseWriter { return w.w } +func (w *rw224) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw224) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw224) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw224) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw224) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw224) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 226/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw225 rwState + +func (w *rw225) Unwrap() http.ResponseWriter { return w.w } +func (w *rw225) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw225) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw225) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw225) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw225) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw225) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw225) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 227/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher +type rw226 rwState + +func (w *rw226) Unwrap() http.ResponseWriter { return w.w } +func (w *rw226) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw226) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw226) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw226) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw226) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw226) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw226) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 228/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw227 rwState + +func (w *rw227) Unwrap() http.ResponseWriter { return w.w } +func (w *rw227) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw227) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw227) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw227) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw227) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw227) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw227) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw227) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 229/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw228 rwState + +func (w *rw228) Unwrap() http.ResponseWriter { return w.w } +func (w *rw228) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw228) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw228) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw228) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw228) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw228) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw228) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 230/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw229 rwState + +func (w *rw229) Unwrap() http.ResponseWriter { return w.w } +func (w *rw229) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw229) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw229) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw229) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw229) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw229) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw229) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw229) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 231/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw230 rwState + +func (w *rw230) Unwrap() http.ResponseWriter { return w.w } +func (w *rw230) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw230) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw230) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw230) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw230) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw230) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw230) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw230) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 232/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw231 rwState + +func (w *rw231) Unwrap() http.ResponseWriter { return w.w } +func (w *rw231) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw231) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw231) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw231) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw231) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw231) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw231) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw231) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw231) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 233/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner +type rw232 rwState + +func (w *rw232) Unwrap() http.ResponseWriter { return w.w } +func (w *rw232) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw232) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw232) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw232) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw232) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw232) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw232) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw232) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 234/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw233 rwState + +func (w *rw233) Unwrap() http.ResponseWriter { return w.w } +func (w *rw233) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw233) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw233) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw233) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw233) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw233) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw233) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw233) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw233) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 235/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw234 rwState + +func (w *rw234) Unwrap() http.ResponseWriter { return w.w } +func (w *rw234) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw234) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw234) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw234) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw234) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw234) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw234) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw234) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw234) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 236/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw235 rwState + +func (w *rw235) Unwrap() http.ResponseWriter { return w.w } +func (w *rw235) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw235) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw235) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw235) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw235) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw235) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw235) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw235) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw235) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw235) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 237/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw236 rwState + +func (w *rw236) Unwrap() http.ResponseWriter { return w.w } +func (w *rw236) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw236) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw236) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw236) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw236) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw236) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw236) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw236) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw236) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 238/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw237 rwState + +func (w *rw237) Unwrap() http.ResponseWriter { return w.w } +func (w *rw237) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw237) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw237) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw237) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw237) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw237) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw237) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw237) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw237) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw237) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 239/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw238 rwState + +func (w *rw238) Unwrap() http.ResponseWriter { return w.w } +func (w *rw238) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw238) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw238) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw238) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw238) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw238) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw238) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw238) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw238) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw238) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 240/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw239 rwState + +func (w *rw239) Unwrap() http.ResponseWriter { return w.w } +func (w *rw239) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw239) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw239) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw239) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw239) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw239) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw239) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw239) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw239) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw239) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw239) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 241/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw240 rwState + +func (w *rw240) Unwrap() http.ResponseWriter { return w.w } +func (w *rw240) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw240) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw240) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw240) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw240) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw240) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw240) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 242/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw241 rwState + +func (w *rw241) Unwrap() http.ResponseWriter { return w.w } +func (w *rw241) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw241) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw241) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw241) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw241) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw241) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw241) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw241) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 243/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw242 rwState + +func (w *rw242) Unwrap() http.ResponseWriter { return w.w } +func (w *rw242) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw242) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw242) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw242) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw242) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw242) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw242) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw242) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 244/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw243 rwState + +func (w *rw243) Unwrap() http.ResponseWriter { return w.w } +func (w *rw243) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw243) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw243) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw243) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw243) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw243) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw243) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw243) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw243) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 245/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw244 rwState + +func (w *rw244) Unwrap() http.ResponseWriter { return w.w } +func (w *rw244) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw244) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw244) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw244) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw244) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw244) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw244) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw244) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 246/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw245 rwState + +func (w *rw245) Unwrap() http.ResponseWriter { return w.w } +func (w *rw245) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw245) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw245) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw245) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw245) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw245) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw245) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw245) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw245) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 247/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw246 rwState + +func (w *rw246) Unwrap() http.ResponseWriter { return w.w } +func (w *rw246) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw246) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw246) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw246) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw246) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw246) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw246) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw246) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw246) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 248/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw247 rwState + +func (w *rw247) Unwrap() http.ResponseWriter { return w.w } +func (w *rw247) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw247) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw247) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw247) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw247) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw247) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw247) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw247) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw247) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw247) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 249/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw248 rwState + +func (w *rw248) Unwrap() http.ResponseWriter { return w.w } +func (w *rw248) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw248) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw248) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw248) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw248) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw248) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw248) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw248) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw248) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 250/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw249 rwState + +func (w *rw249) Unwrap() http.ResponseWriter { return w.w } +func (w *rw249) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw249) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw249) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw249) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw249) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw249) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw249) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw249) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw249) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw249) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 251/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw250 rwState + +func (w *rw250) Unwrap() http.ResponseWriter { return w.w } +func (w *rw250) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw250) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw250) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw250) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw250) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw250) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw250) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw250) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw250) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw250) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 252/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw251 rwState + +func (w *rw251) Unwrap() http.ResponseWriter { return w.w } +func (w *rw251) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw251) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw251) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw251) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw251) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw251) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw251) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw251) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw251) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw251) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw251) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 253/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw252 rwState + +func (w *rw252) Unwrap() http.ResponseWriter { return w.w } +func (w *rw252) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw252) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw252) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw252) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw252) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw252) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw252) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw252) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw252) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw252) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 254/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw253 rwState + +func (w *rw253) Unwrap() http.ResponseWriter { return w.w } +func (w *rw253) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw253) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw253) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw253) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw253) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw253) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw253) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw253) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw253) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw253) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw253) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 255/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw254 rwState + +func (w *rw254) Unwrap() http.ResponseWriter { return w.w } +func (w *rw254) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw254) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw254) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw254) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw254) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw254) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw254) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw254) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw254) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw254) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw254) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 256/512: http.ResponseWriter, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw255 rwState + +func (w *rw255) Unwrap() http.ResponseWriter { return w.w } +func (w *rw255) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw255) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw255) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw255) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw255) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw255) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw255) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw255) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw255) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw255) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw255) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw255) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 257/512: http.ResponseWriter, http.Flusher +type rw256 rwState + +func (w *rw256) Unwrap() http.ResponseWriter { return w.w } +func (w *rw256) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw256) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw256) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw256) Flush() { + (*rwState)(w).doFlush() +} + +// combination 258/512: http.ResponseWriter, http.Flusher, io.StringWriter +type rw257 rwState + +func (w *rw257) Unwrap() http.ResponseWriter { return w.w } +func (w *rw257) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw257) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw257) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw257) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw257) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 259/512: http.ResponseWriter, http.Flusher, http.Pusher +type rw258 rwState + +func (w *rw258) Unwrap() http.ResponseWriter { return w.w } +func (w *rw258) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw258) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw258) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw258) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw258) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 260/512: http.ResponseWriter, http.Flusher, http.Pusher, io.StringWriter +type rw259 rwState + +func (w *rw259) Unwrap() http.ResponseWriter { return w.w } +func (w *rw259) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw259) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw259) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw259) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw259) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw259) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 261/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler +type rw260 rwState + +func (w *rw260) Unwrap() http.ResponseWriter { return w.w } +func (w *rw260) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw260) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw260) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw260) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw260) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 262/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler, io.StringWriter +type rw261 rwState + +func (w *rw261) Unwrap() http.ResponseWriter { return w.w } +func (w *rw261) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw261) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw261) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw261) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw261) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw261) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 263/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler, http.Pusher +type rw262 rwState + +func (w *rw262) Unwrap() http.ResponseWriter { return w.w } +func (w *rw262) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw262) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw262) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw262) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw262) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw262) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 264/512: http.ResponseWriter, http.Flusher, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw263 rwState + +func (w *rw263) Unwrap() http.ResponseWriter { return w.w } +func (w *rw263) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw263) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw263) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw263) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw263) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw263) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw263) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 265/512: http.ResponseWriter, http.Flusher, deadliner +type rw264 rwState + +func (w *rw264) Unwrap() http.ResponseWriter { return w.w } +func (w *rw264) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw264) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw264) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw264) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw264) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw264) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 266/512: http.ResponseWriter, http.Flusher, deadliner, io.StringWriter +type rw265 rwState + +func (w *rw265) Unwrap() http.ResponseWriter { return w.w } +func (w *rw265) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw265) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw265) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw265) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw265) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw265) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw265) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 267/512: http.ResponseWriter, http.Flusher, deadliner, http.Pusher +type rw266 rwState + +func (w *rw266) Unwrap() http.ResponseWriter { return w.w } +func (w *rw266) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw266) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw266) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw266) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw266) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw266) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw266) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 268/512: http.ResponseWriter, http.Flusher, deadliner, http.Pusher, io.StringWriter +type rw267 rwState + +func (w *rw267) Unwrap() http.ResponseWriter { return w.w } +func (w *rw267) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw267) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw267) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw267) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw267) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw267) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw267) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw267) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 269/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler +type rw268 rwState + +func (w *rw268) Unwrap() http.ResponseWriter { return w.w } +func (w *rw268) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw268) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw268) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw268) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw268) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw268) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw268) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 270/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler, io.StringWriter +type rw269 rwState + +func (w *rw269) Unwrap() http.ResponseWriter { return w.w } +func (w *rw269) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw269) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw269) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw269) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw269) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw269) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw269) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw269) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 271/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler, http.Pusher +type rw270 rwState + +func (w *rw270) Unwrap() http.ResponseWriter { return w.w } +func (w *rw270) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw270) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw270) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw270) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw270) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw270) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw270) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw270) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 272/512: http.ResponseWriter, http.Flusher, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw271 rwState + +func (w *rw271) Unwrap() http.ResponseWriter { return w.w } +func (w *rw271) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw271) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw271) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw271) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw271) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw271) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw271) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw271) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw271) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 273/512: http.ResponseWriter, http.Flusher, io.ReaderFrom +type rw272 rwState + +func (w *rw272) Unwrap() http.ResponseWriter { return w.w } +func (w *rw272) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw272) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw272) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw272) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw272) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 274/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, io.StringWriter +type rw273 rwState + +func (w *rw273) Unwrap() http.ResponseWriter { return w.w } +func (w *rw273) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw273) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw273) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw273) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw273) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw273) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 275/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, http.Pusher +type rw274 rwState + +func (w *rw274) Unwrap() http.ResponseWriter { return w.w } +func (w *rw274) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw274) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw274) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw274) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw274) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw274) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 276/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, http.Pusher, io.StringWriter +type rw275 rwState + +func (w *rw275) Unwrap() http.ResponseWriter { return w.w } +func (w *rw275) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw275) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw275) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw275) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw275) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw275) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw275) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 277/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler +type rw276 rwState + +func (w *rw276) Unwrap() http.ResponseWriter { return w.w } +func (w *rw276) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw276) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw276) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw276) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw276) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw276) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 278/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw277 rwState + +func (w *rw277) Unwrap() http.ResponseWriter { return w.w } +func (w *rw277) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw277) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw277) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw277) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw277) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw277) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw277) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 279/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw278 rwState + +func (w *rw278) Unwrap() http.ResponseWriter { return w.w } +func (w *rw278) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw278) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw278) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw278) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw278) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw278) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw278) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 280/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw279 rwState + +func (w *rw279) Unwrap() http.ResponseWriter { return w.w } +func (w *rw279) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw279) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw279) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw279) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw279) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw279) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw279) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw279) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 281/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner +type rw280 rwState + +func (w *rw280) Unwrap() http.ResponseWriter { return w.w } +func (w *rw280) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw280) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw280) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw280) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw280) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw280) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw280) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 282/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, io.StringWriter +type rw281 rwState + +func (w *rw281) Unwrap() http.ResponseWriter { return w.w } +func (w *rw281) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw281) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw281) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw281) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw281) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw281) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw281) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw281) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 283/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, http.Pusher +type rw282 rwState + +func (w *rw282) Unwrap() http.ResponseWriter { return w.w } +func (w *rw282) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw282) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw282) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw282) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw282) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw282) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw282) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw282) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 284/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw283 rwState + +func (w *rw283) Unwrap() http.ResponseWriter { return w.w } +func (w *rw283) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw283) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw283) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw283) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw283) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw283) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw283) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw283) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw283) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 285/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw284 rwState + +func (w *rw284) Unwrap() http.ResponseWriter { return w.w } +func (w *rw284) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw284) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw284) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw284) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw284) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw284) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw284) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw284) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 286/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw285 rwState + +func (w *rw285) Unwrap() http.ResponseWriter { return w.w } +func (w *rw285) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw285) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw285) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw285) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw285) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw285) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw285) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw285) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw285) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 287/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw286 rwState + +func (w *rw286) Unwrap() http.ResponseWriter { return w.w } +func (w *rw286) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw286) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw286) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw286) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw286) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw286) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw286) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw286) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw286) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 288/512: http.ResponseWriter, http.Flusher, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw287 rwState + +func (w *rw287) Unwrap() http.ResponseWriter { return w.w } +func (w *rw287) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw287) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw287) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw287) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw287) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw287) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw287) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw287) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw287) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw287) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 289/512: http.ResponseWriter, http.Flusher, http.Hijacker +type rw288 rwState + +func (w *rw288) Unwrap() http.ResponseWriter { return w.w } +func (w *rw288) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw288) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw288) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw288) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw288) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 290/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.StringWriter +type rw289 rwState + +func (w *rw289) Unwrap() http.ResponseWriter { return w.w } +func (w *rw289) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw289) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw289) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw289) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw289) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw289) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 291/512: http.ResponseWriter, http.Flusher, http.Hijacker, http.Pusher +type rw290 rwState + +func (w *rw290) Unwrap() http.ResponseWriter { return w.w } +func (w *rw290) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw290) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw290) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw290) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw290) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw290) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 292/512: http.ResponseWriter, http.Flusher, http.Hijacker, http.Pusher, io.StringWriter +type rw291 rwState + +func (w *rw291) Unwrap() http.ResponseWriter { return w.w } +func (w *rw291) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw291) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw291) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw291) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw291) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw291) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw291) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 293/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler +type rw292 rwState + +func (w *rw292) Unwrap() http.ResponseWriter { return w.w } +func (w *rw292) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw292) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw292) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw292) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw292) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw292) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 294/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw293 rwState + +func (w *rw293) Unwrap() http.ResponseWriter { return w.w } +func (w *rw293) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw293) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw293) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw293) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw293) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw293) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw293) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 295/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw294 rwState + +func (w *rw294) Unwrap() http.ResponseWriter { return w.w } +func (w *rw294) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw294) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw294) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw294) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw294) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw294) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw294) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 296/512: http.ResponseWriter, http.Flusher, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw295 rwState + +func (w *rw295) Unwrap() http.ResponseWriter { return w.w } +func (w *rw295) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw295) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw295) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw295) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw295) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw295) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw295) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw295) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 297/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner +type rw296 rwState + +func (w *rw296) Unwrap() http.ResponseWriter { return w.w } +func (w *rw296) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw296) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw296) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw296) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw296) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw296) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw296) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 298/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, io.StringWriter +type rw297 rwState + +func (w *rw297) Unwrap() http.ResponseWriter { return w.w } +func (w *rw297) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw297) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw297) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw297) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw297) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw297) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw297) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw297) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 299/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, http.Pusher +type rw298 rwState + +func (w *rw298) Unwrap() http.ResponseWriter { return w.w } +func (w *rw298) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw298) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw298) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw298) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw298) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw298) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw298) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw298) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 300/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw299 rwState + +func (w *rw299) Unwrap() http.ResponseWriter { return w.w } +func (w *rw299) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw299) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw299) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw299) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw299) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw299) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw299) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw299) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw299) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 301/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler +type rw300 rwState + +func (w *rw300) Unwrap() http.ResponseWriter { return w.w } +func (w *rw300) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw300) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw300) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw300) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw300) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw300) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw300) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw300) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 302/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw301 rwState + +func (w *rw301) Unwrap() http.ResponseWriter { return w.w } +func (w *rw301) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw301) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw301) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw301) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw301) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw301) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw301) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw301) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw301) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 303/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw302 rwState + +func (w *rw302) Unwrap() http.ResponseWriter { return w.w } +func (w *rw302) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw302) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw302) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw302) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw302) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw302) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw302) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw302) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw302) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 304/512: http.ResponseWriter, http.Flusher, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw303 rwState + +func (w *rw303) Unwrap() http.ResponseWriter { return w.w } +func (w *rw303) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw303) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw303) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw303) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw303) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw303) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw303) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw303) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw303) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw303) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 305/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom +type rw304 rwState + +func (w *rw304) Unwrap() http.ResponseWriter { return w.w } +func (w *rw304) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw304) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw304) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw304) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw304) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw304) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 306/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw305 rwState + +func (w *rw305) Unwrap() http.ResponseWriter { return w.w } +func (w *rw305) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw305) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw305) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw305) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw305) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw305) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw305) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 307/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, http.Pusher +type rw306 rwState + +func (w *rw306) Unwrap() http.ResponseWriter { return w.w } +func (w *rw306) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw306) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw306) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw306) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw306) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw306) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw306) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 308/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw307 rwState + +func (w *rw307) Unwrap() http.ResponseWriter { return w.w } +func (w *rw307) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw307) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw307) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw307) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw307) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw307) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw307) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw307) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 309/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw308 rwState + +func (w *rw308) Unwrap() http.ResponseWriter { return w.w } +func (w *rw308) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw308) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw308) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw308) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw308) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw308) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw308) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 310/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw309 rwState + +func (w *rw309) Unwrap() http.ResponseWriter { return w.w } +func (w *rw309) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw309) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw309) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw309) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw309) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw309) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw309) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw309) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 311/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw310 rwState + +func (w *rw310) Unwrap() http.ResponseWriter { return w.w } +func (w *rw310) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw310) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw310) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw310) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw310) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw310) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw310) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw310) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 312/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw311 rwState + +func (w *rw311) Unwrap() http.ResponseWriter { return w.w } +func (w *rw311) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw311) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw311) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw311) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw311) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw311) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw311) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw311) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw311) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 313/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner +type rw312 rwState + +func (w *rw312) Unwrap() http.ResponseWriter { return w.w } +func (w *rw312) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw312) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw312) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw312) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw312) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw312) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw312) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw312) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 314/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw313 rwState + +func (w *rw313) Unwrap() http.ResponseWriter { return w.w } +func (w *rw313) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw313) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw313) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw313) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw313) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw313) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw313) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw313) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw313) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 315/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw314 rwState + +func (w *rw314) Unwrap() http.ResponseWriter { return w.w } +func (w *rw314) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw314) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw314) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw314) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw314) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw314) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw314) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw314) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw314) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 316/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw315 rwState + +func (w *rw315) Unwrap() http.ResponseWriter { return w.w } +func (w *rw315) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw315) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw315) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw315) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw315) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw315) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw315) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw315) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw315) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw315) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 317/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw316 rwState + +func (w *rw316) Unwrap() http.ResponseWriter { return w.w } +func (w *rw316) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw316) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw316) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw316) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw316) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw316) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw316) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw316) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw316) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 318/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw317 rwState + +func (w *rw317) Unwrap() http.ResponseWriter { return w.w } +func (w *rw317) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw317) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw317) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw317) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw317) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw317) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw317) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw317) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw317) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw317) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 319/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw318 rwState + +func (w *rw318) Unwrap() http.ResponseWriter { return w.w } +func (w *rw318) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw318) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw318) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw318) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw318) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw318) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw318) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw318) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw318) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw318) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 320/512: http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw319 rwState + +func (w *rw319) Unwrap() http.ResponseWriter { return w.w } +func (w *rw319) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw319) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw319) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw319) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw319) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw319) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw319) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw319) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw319) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw319) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw319) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 321/512: http.ResponseWriter, http.Flusher, http.CloseNotifier +type rw320 rwState + +func (w *rw320) Unwrap() http.ResponseWriter { return w.w } +func (w *rw320) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw320) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw320) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw320) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw320) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 322/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.StringWriter +type rw321 rwState + +func (w *rw321) Unwrap() http.ResponseWriter { return w.w } +func (w *rw321) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw321) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw321) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw321) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw321) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw321) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 323/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Pusher +type rw322 rwState + +func (w *rw322) Unwrap() http.ResponseWriter { return w.w } +func (w *rw322) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw322) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw322) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw322) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw322) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw322) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 324/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Pusher, io.StringWriter +type rw323 rwState + +func (w *rw323) Unwrap() http.ResponseWriter { return w.w } +func (w *rw323) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw323) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw323) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw323) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw323) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw323) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw323) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 325/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler +type rw324 rwState + +func (w *rw324) Unwrap() http.ResponseWriter { return w.w } +func (w *rw324) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw324) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw324) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw324) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw324) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw324) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 326/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw325 rwState + +func (w *rw325) Unwrap() http.ResponseWriter { return w.w } +func (w *rw325) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw325) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw325) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw325) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw325) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw325) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw325) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 327/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw326 rwState + +func (w *rw326) Unwrap() http.ResponseWriter { return w.w } +func (w *rw326) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw326) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw326) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw326) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw326) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw326) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw326) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 328/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw327 rwState + +func (w *rw327) Unwrap() http.ResponseWriter { return w.w } +func (w *rw327) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw327) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw327) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw327) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw327) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw327) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw327) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw327) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 329/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner +type rw328 rwState + +func (w *rw328) Unwrap() http.ResponseWriter { return w.w } +func (w *rw328) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw328) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw328) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw328) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw328) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw328) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw328) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 330/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, io.StringWriter +type rw329 rwState + +func (w *rw329) Unwrap() http.ResponseWriter { return w.w } +func (w *rw329) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw329) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw329) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw329) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw329) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw329) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw329) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw329) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 331/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, http.Pusher +type rw330 rwState + +func (w *rw330) Unwrap() http.ResponseWriter { return w.w } +func (w *rw330) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw330) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw330) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw330) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw330) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw330) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw330) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw330) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 332/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw331 rwState + +func (w *rw331) Unwrap() http.ResponseWriter { return w.w } +func (w *rw331) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw331) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw331) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw331) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw331) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw331) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw331) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw331) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw331) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 333/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw332 rwState + +func (w *rw332) Unwrap() http.ResponseWriter { return w.w } +func (w *rw332) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw332) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw332) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw332) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw332) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw332) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw332) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw332) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 334/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw333 rwState + +func (w *rw333) Unwrap() http.ResponseWriter { return w.w } +func (w *rw333) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw333) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw333) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw333) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw333) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw333) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw333) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw333) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw333) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 335/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw334 rwState + +func (w *rw334) Unwrap() http.ResponseWriter { return w.w } +func (w *rw334) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw334) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw334) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw334) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw334) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw334) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw334) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw334) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw334) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 336/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw335 rwState + +func (w *rw335) Unwrap() http.ResponseWriter { return w.w } +func (w *rw335) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw335) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw335) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw335) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw335) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw335) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw335) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw335) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw335) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw335) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 337/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom +type rw336 rwState + +func (w *rw336) Unwrap() http.ResponseWriter { return w.w } +func (w *rw336) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw336) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw336) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw336) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw336) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw336) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 338/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw337 rwState + +func (w *rw337) Unwrap() http.ResponseWriter { return w.w } +func (w *rw337) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw337) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw337) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw337) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw337) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw337) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw337) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 339/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw338 rwState + +func (w *rw338) Unwrap() http.ResponseWriter { return w.w } +func (w *rw338) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw338) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw338) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw338) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw338) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw338) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw338) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 340/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw339 rwState + +func (w *rw339) Unwrap() http.ResponseWriter { return w.w } +func (w *rw339) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw339) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw339) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw339) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw339) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw339) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw339) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw339) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 341/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw340 rwState + +func (w *rw340) Unwrap() http.ResponseWriter { return w.w } +func (w *rw340) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw340) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw340) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw340) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw340) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw340) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw340) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 342/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw341 rwState + +func (w *rw341) Unwrap() http.ResponseWriter { return w.w } +func (w *rw341) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw341) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw341) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw341) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw341) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw341) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw341) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw341) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 343/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw342 rwState + +func (w *rw342) Unwrap() http.ResponseWriter { return w.w } +func (w *rw342) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw342) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw342) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw342) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw342) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw342) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw342) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw342) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 344/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw343 rwState + +func (w *rw343) Unwrap() http.ResponseWriter { return w.w } +func (w *rw343) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw343) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw343) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw343) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw343) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw343) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw343) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw343) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw343) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 345/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner +type rw344 rwState + +func (w *rw344) Unwrap() http.ResponseWriter { return w.w } +func (w *rw344) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw344) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw344) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw344) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw344) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw344) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw344) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw344) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 346/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw345 rwState + +func (w *rw345) Unwrap() http.ResponseWriter { return w.w } +func (w *rw345) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw345) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw345) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw345) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw345) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw345) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw345) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw345) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw345) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 347/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw346 rwState + +func (w *rw346) Unwrap() http.ResponseWriter { return w.w } +func (w *rw346) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw346) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw346) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw346) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw346) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw346) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw346) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw346) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw346) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 348/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw347 rwState + +func (w *rw347) Unwrap() http.ResponseWriter { return w.w } +func (w *rw347) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw347) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw347) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw347) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw347) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw347) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw347) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw347) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw347) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw347) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 349/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw348 rwState + +func (w *rw348) Unwrap() http.ResponseWriter { return w.w } +func (w *rw348) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw348) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw348) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw348) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw348) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw348) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw348) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw348) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw348) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 350/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw349 rwState + +func (w *rw349) Unwrap() http.ResponseWriter { return w.w } +func (w *rw349) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw349) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw349) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw349) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw349) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw349) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw349) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw349) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw349) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw349) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 351/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw350 rwState + +func (w *rw350) Unwrap() http.ResponseWriter { return w.w } +func (w *rw350) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw350) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw350) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw350) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw350) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw350) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw350) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw350) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw350) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw350) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 352/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw351 rwState + +func (w *rw351) Unwrap() http.ResponseWriter { return w.w } +func (w *rw351) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw351) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw351) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw351) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw351) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw351) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw351) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw351) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw351) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw351) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw351) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 353/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker +type rw352 rwState + +func (w *rw352) Unwrap() http.ResponseWriter { return w.w } +func (w *rw352) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw352) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw352) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw352) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw352) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw352) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 354/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw353 rwState + +func (w *rw353) Unwrap() http.ResponseWriter { return w.w } +func (w *rw353) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw353) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw353) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw353) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw353) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw353) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw353) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 355/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, http.Pusher +type rw354 rwState + +func (w *rw354) Unwrap() http.ResponseWriter { return w.w } +func (w *rw354) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw354) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw354) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw354) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw354) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw354) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw354) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 356/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw355 rwState + +func (w *rw355) Unwrap() http.ResponseWriter { return w.w } +func (w *rw355) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw355) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw355) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw355) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw355) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw355) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw355) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw355) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 357/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw356 rwState + +func (w *rw356) Unwrap() http.ResponseWriter { return w.w } +func (w *rw356) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw356) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw356) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw356) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw356) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw356) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw356) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 358/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw357 rwState + +func (w *rw357) Unwrap() http.ResponseWriter { return w.w } +func (w *rw357) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw357) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw357) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw357) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw357) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw357) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw357) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw357) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 359/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw358 rwState + +func (w *rw358) Unwrap() http.ResponseWriter { return w.w } +func (w *rw358) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw358) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw358) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw358) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw358) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw358) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw358) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw358) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 360/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw359 rwState + +func (w *rw359) Unwrap() http.ResponseWriter { return w.w } +func (w *rw359) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw359) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw359) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw359) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw359) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw359) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw359) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw359) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw359) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 361/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner +type rw360 rwState + +func (w *rw360) Unwrap() http.ResponseWriter { return w.w } +func (w *rw360) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw360) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw360) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw360) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw360) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw360) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw360) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw360) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 362/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw361 rwState + +func (w *rw361) Unwrap() http.ResponseWriter { return w.w } +func (w *rw361) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw361) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw361) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw361) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw361) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw361) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw361) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw361) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw361) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 363/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw362 rwState + +func (w *rw362) Unwrap() http.ResponseWriter { return w.w } +func (w *rw362) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw362) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw362) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw362) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw362) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw362) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw362) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw362) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw362) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 364/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw363 rwState + +func (w *rw363) Unwrap() http.ResponseWriter { return w.w } +func (w *rw363) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw363) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw363) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw363) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw363) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw363) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw363) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw363) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw363) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw363) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 365/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw364 rwState + +func (w *rw364) Unwrap() http.ResponseWriter { return w.w } +func (w *rw364) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw364) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw364) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw364) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw364) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw364) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw364) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw364) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw364) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 366/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw365 rwState + +func (w *rw365) Unwrap() http.ResponseWriter { return w.w } +func (w *rw365) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw365) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw365) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw365) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw365) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw365) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw365) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw365) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw365) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw365) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 367/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw366 rwState + +func (w *rw366) Unwrap() http.ResponseWriter { return w.w } +func (w *rw366) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw366) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw366) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw366) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw366) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw366) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw366) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw366) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw366) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw366) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 368/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw367 rwState + +func (w *rw367) Unwrap() http.ResponseWriter { return w.w } +func (w *rw367) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw367) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw367) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw367) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw367) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw367) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw367) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw367) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw367) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw367) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw367) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 369/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw368 rwState + +func (w *rw368) Unwrap() http.ResponseWriter { return w.w } +func (w *rw368) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw368) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw368) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw368) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw368) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw368) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw368) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 370/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw369 rwState + +func (w *rw369) Unwrap() http.ResponseWriter { return w.w } +func (w *rw369) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw369) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw369) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw369) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw369) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw369) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw369) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw369) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 371/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw370 rwState + +func (w *rw370) Unwrap() http.ResponseWriter { return w.w } +func (w *rw370) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw370) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw370) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw370) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw370) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw370) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw370) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw370) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 372/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw371 rwState + +func (w *rw371) Unwrap() http.ResponseWriter { return w.w } +func (w *rw371) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw371) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw371) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw371) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw371) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw371) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw371) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw371) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw371) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 373/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw372 rwState + +func (w *rw372) Unwrap() http.ResponseWriter { return w.w } +func (w *rw372) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw372) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw372) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw372) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw372) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw372) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw372) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw372) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 374/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw373 rwState + +func (w *rw373) Unwrap() http.ResponseWriter { return w.w } +func (w *rw373) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw373) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw373) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw373) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw373) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw373) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw373) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw373) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw373) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 375/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw374 rwState + +func (w *rw374) Unwrap() http.ResponseWriter { return w.w } +func (w *rw374) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw374) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw374) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw374) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw374) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw374) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw374) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw374) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw374) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 376/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw375 rwState + +func (w *rw375) Unwrap() http.ResponseWriter { return w.w } +func (w *rw375) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw375) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw375) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw375) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw375) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw375) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw375) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw375) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw375) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw375) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 377/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw376 rwState + +func (w *rw376) Unwrap() http.ResponseWriter { return w.w } +func (w *rw376) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw376) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw376) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw376) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw376) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw376) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw376) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw376) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw376) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 378/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw377 rwState + +func (w *rw377) Unwrap() http.ResponseWriter { return w.w } +func (w *rw377) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw377) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw377) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw377) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw377) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw377) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw377) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw377) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw377) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw377) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 379/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw378 rwState + +func (w *rw378) Unwrap() http.ResponseWriter { return w.w } +func (w *rw378) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw378) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw378) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw378) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw378) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw378) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw378) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw378) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw378) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw378) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 380/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw379 rwState + +func (w *rw379) Unwrap() http.ResponseWriter { return w.w } +func (w *rw379) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw379) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw379) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw379) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw379) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw379) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw379) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw379) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw379) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw379) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw379) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 381/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw380 rwState + +func (w *rw380) Unwrap() http.ResponseWriter { return w.w } +func (w *rw380) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw380) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw380) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw380) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw380) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw380) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw380) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw380) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw380) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw380) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 382/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw381 rwState + +func (w *rw381) Unwrap() http.ResponseWriter { return w.w } +func (w *rw381) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw381) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw381) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw381) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw381) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw381) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw381) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw381) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw381) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw381) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw381) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 383/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw382 rwState + +func (w *rw382) Unwrap() http.ResponseWriter { return w.w } +func (w *rw382) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw382) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw382) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw382) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw382) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw382) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw382) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw382) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw382) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw382) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw382) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 384/512: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw383 rwState + +func (w *rw383) Unwrap() http.ResponseWriter { return w.w } +func (w *rw383) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw383) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw383) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw383) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw383) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw383) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw383) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw383) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw383) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw383) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw383) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw383) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 385/512: http.ResponseWriter, http.Flusher, httpFlushError +type rw384 rwState + +func (w *rw384) Unwrap() http.ResponseWriter { return w.w } +func (w *rw384) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw384) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw384) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw384) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw384) FlushError() error { + return (*rwState)(w).doFlushError() +} + +// combination 386/512: http.ResponseWriter, http.Flusher, httpFlushError, io.StringWriter +type rw385 rwState + +func (w *rw385) Unwrap() http.ResponseWriter { return w.w } +func (w *rw385) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw385) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw385) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw385) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw385) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw385) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 387/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Pusher +type rw386 rwState + +func (w *rw386) Unwrap() http.ResponseWriter { return w.w } +func (w *rw386) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw386) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw386) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw386) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw386) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw386) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 388/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Pusher, io.StringWriter +type rw387 rwState + +func (w *rw387) Unwrap() http.ResponseWriter { return w.w } +func (w *rw387) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw387) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw387) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw387) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw387) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw387) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw387) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 389/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler +type rw388 rwState + +func (w *rw388) Unwrap() http.ResponseWriter { return w.w } +func (w *rw388) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw388) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw388) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw388) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw388) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw388) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 390/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler, io.StringWriter +type rw389 rwState + +func (w *rw389) Unwrap() http.ResponseWriter { return w.w } +func (w *rw389) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw389) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw389) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw389) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw389) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw389) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw389) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 391/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler, http.Pusher +type rw390 rwState + +func (w *rw390) Unwrap() http.ResponseWriter { return w.w } +func (w *rw390) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw390) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw390) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw390) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw390) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw390) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw390) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 392/512: http.ResponseWriter, http.Flusher, httpFlushError, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw391 rwState + +func (w *rw391) Unwrap() http.ResponseWriter { return w.w } +func (w *rw391) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw391) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw391) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw391) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw391) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw391) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw391) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw391) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 393/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner +type rw392 rwState + +func (w *rw392) Unwrap() http.ResponseWriter { return w.w } +func (w *rw392) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw392) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw392) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw392) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw392) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw392) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw392) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 394/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, io.StringWriter +type rw393 rwState + +func (w *rw393) Unwrap() http.ResponseWriter { return w.w } +func (w *rw393) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw393) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw393) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw393) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw393) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw393) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw393) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw393) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 395/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, http.Pusher +type rw394 rwState + +func (w *rw394) Unwrap() http.ResponseWriter { return w.w } +func (w *rw394) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw394) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw394) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw394) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw394) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw394) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw394) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw394) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 396/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, http.Pusher, io.StringWriter +type rw395 rwState + +func (w *rw395) Unwrap() http.ResponseWriter { return w.w } +func (w *rw395) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw395) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw395) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw395) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw395) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw395) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw395) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw395) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw395) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 397/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler +type rw396 rwState + +func (w *rw396) Unwrap() http.ResponseWriter { return w.w } +func (w *rw396) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw396) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw396) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw396) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw396) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw396) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw396) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw396) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 398/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler, io.StringWriter +type rw397 rwState + +func (w *rw397) Unwrap() http.ResponseWriter { return w.w } +func (w *rw397) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw397) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw397) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw397) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw397) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw397) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw397) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw397) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw397) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 399/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher +type rw398 rwState + +func (w *rw398) Unwrap() http.ResponseWriter { return w.w } +func (w *rw398) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw398) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw398) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw398) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw398) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw398) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw398) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw398) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw398) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 400/512: http.ResponseWriter, http.Flusher, httpFlushError, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw399 rwState + +func (w *rw399) Unwrap() http.ResponseWriter { return w.w } +func (w *rw399) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw399) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw399) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw399) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw399) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw399) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw399) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw399) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw399) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw399) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 401/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom +type rw400 rwState + +func (w *rw400) Unwrap() http.ResponseWriter { return w.w } +func (w *rw400) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw400) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw400) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw400) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw400) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw400) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 402/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, io.StringWriter +type rw401 rwState + +func (w *rw401) Unwrap() http.ResponseWriter { return w.w } +func (w *rw401) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw401) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw401) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw401) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw401) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw401) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw401) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 403/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, http.Pusher +type rw402 rwState + +func (w *rw402) Unwrap() http.ResponseWriter { return w.w } +func (w *rw402) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw402) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw402) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw402) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw402) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw402) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw402) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 404/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, http.Pusher, io.StringWriter +type rw403 rwState + +func (w *rw403) Unwrap() http.ResponseWriter { return w.w } +func (w *rw403) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw403) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw403) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw403) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw403) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw403) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw403) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw403) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 405/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler +type rw404 rwState + +func (w *rw404) Unwrap() http.ResponseWriter { return w.w } +func (w *rw404) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw404) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw404) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw404) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw404) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw404) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw404) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 406/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw405 rwState + +func (w *rw405) Unwrap() http.ResponseWriter { return w.w } +func (w *rw405) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw405) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw405) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw405) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw405) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw405) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw405) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw405) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 407/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw406 rwState + +func (w *rw406) Unwrap() http.ResponseWriter { return w.w } +func (w *rw406) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw406) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw406) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw406) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw406) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw406) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw406) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw406) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 408/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw407 rwState + +func (w *rw407) Unwrap() http.ResponseWriter { return w.w } +func (w *rw407) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw407) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw407) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw407) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw407) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw407) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw407) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw407) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw407) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 409/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner +type rw408 rwState + +func (w *rw408) Unwrap() http.ResponseWriter { return w.w } +func (w *rw408) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw408) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw408) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw408) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw408) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw408) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw408) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw408) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 410/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, io.StringWriter +type rw409 rwState + +func (w *rw409) Unwrap() http.ResponseWriter { return w.w } +func (w *rw409) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw409) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw409) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw409) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw409) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw409) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw409) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw409) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw409) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 411/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, http.Pusher +type rw410 rwState + +func (w *rw410) Unwrap() http.ResponseWriter { return w.w } +func (w *rw410) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw410) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw410) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw410) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw410) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw410) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw410) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw410) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw410) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 412/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw411 rwState + +func (w *rw411) Unwrap() http.ResponseWriter { return w.w } +func (w *rw411) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw411) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw411) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw411) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw411) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw411) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw411) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw411) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw411) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw411) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 413/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw412 rwState + +func (w *rw412) Unwrap() http.ResponseWriter { return w.w } +func (w *rw412) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw412) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw412) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw412) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw412) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw412) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw412) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw412) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw412) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 414/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw413 rwState + +func (w *rw413) Unwrap() http.ResponseWriter { return w.w } +func (w *rw413) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw413) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw413) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw413) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw413) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw413) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw413) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw413) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw413) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw413) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 415/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw414 rwState + +func (w *rw414) Unwrap() http.ResponseWriter { return w.w } +func (w *rw414) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw414) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw414) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw414) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw414) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw414) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw414) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw414) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw414) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw414) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 416/512: http.ResponseWriter, http.Flusher, httpFlushError, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw415 rwState + +func (w *rw415) Unwrap() http.ResponseWriter { return w.w } +func (w *rw415) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw415) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw415) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw415) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw415) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw415) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw415) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw415) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw415) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw415) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw415) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 417/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker +type rw416 rwState + +func (w *rw416) Unwrap() http.ResponseWriter { return w.w } +func (w *rw416) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw416) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw416) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw416) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw416) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw416) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 418/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.StringWriter +type rw417 rwState + +func (w *rw417) Unwrap() http.ResponseWriter { return w.w } +func (w *rw417) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw417) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw417) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw417) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw417) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw417) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw417) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 419/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, http.Pusher +type rw418 rwState + +func (w *rw418) Unwrap() http.ResponseWriter { return w.w } +func (w *rw418) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw418) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw418) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw418) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw418) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw418) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw418) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 420/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, http.Pusher, io.StringWriter +type rw419 rwState + +func (w *rw419) Unwrap() http.ResponseWriter { return w.w } +func (w *rw419) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw419) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw419) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw419) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw419) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw419) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw419) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw419) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 421/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler +type rw420 rwState + +func (w *rw420) Unwrap() http.ResponseWriter { return w.w } +func (w *rw420) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw420) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw420) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw420) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw420) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw420) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw420) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 422/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw421 rwState + +func (w *rw421) Unwrap() http.ResponseWriter { return w.w } +func (w *rw421) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw421) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw421) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw421) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw421) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw421) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw421) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw421) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 423/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw422 rwState + +func (w *rw422) Unwrap() http.ResponseWriter { return w.w } +func (w *rw422) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw422) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw422) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw422) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw422) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw422) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw422) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw422) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 424/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw423 rwState + +func (w *rw423) Unwrap() http.ResponseWriter { return w.w } +func (w *rw423) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw423) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw423) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw423) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw423) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw423) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw423) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw423) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw423) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 425/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner +type rw424 rwState + +func (w *rw424) Unwrap() http.ResponseWriter { return w.w } +func (w *rw424) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw424) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw424) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw424) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw424) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw424) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw424) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw424) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 426/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, io.StringWriter +type rw425 rwState + +func (w *rw425) Unwrap() http.ResponseWriter { return w.w } +func (w *rw425) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw425) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw425) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw425) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw425) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw425) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw425) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw425) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw425) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 427/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, http.Pusher +type rw426 rwState + +func (w *rw426) Unwrap() http.ResponseWriter { return w.w } +func (w *rw426) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw426) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw426) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw426) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw426) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw426) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw426) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw426) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw426) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 428/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw427 rwState + +func (w *rw427) Unwrap() http.ResponseWriter { return w.w } +func (w *rw427) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw427) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw427) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw427) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw427) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw427) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw427) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw427) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw427) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw427) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 429/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler +type rw428 rwState + +func (w *rw428) Unwrap() http.ResponseWriter { return w.w } +func (w *rw428) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw428) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw428) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw428) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw428) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw428) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw428) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw428) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw428) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 430/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw429 rwState + +func (w *rw429) Unwrap() http.ResponseWriter { return w.w } +func (w *rw429) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw429) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw429) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw429) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw429) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw429) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw429) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw429) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw429) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw429) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 431/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw430 rwState + +func (w *rw430) Unwrap() http.ResponseWriter { return w.w } +func (w *rw430) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw430) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw430) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw430) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw430) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw430) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw430) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw430) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw430) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw430) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 432/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw431 rwState + +func (w *rw431) Unwrap() http.ResponseWriter { return w.w } +func (w *rw431) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw431) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw431) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw431) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw431) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw431) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw431) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw431) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw431) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw431) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw431) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 433/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom +type rw432 rwState + +func (w *rw432) Unwrap() http.ResponseWriter { return w.w } +func (w *rw432) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw432) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw432) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw432) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw432) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw432) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw432) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 434/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw433 rwState + +func (w *rw433) Unwrap() http.ResponseWriter { return w.w } +func (w *rw433) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw433) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw433) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw433) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw433) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw433) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw433) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw433) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 435/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher +type rw434 rwState + +func (w *rw434) Unwrap() http.ResponseWriter { return w.w } +func (w *rw434) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw434) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw434) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw434) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw434) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw434) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw434) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw434) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 436/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw435 rwState + +func (w *rw435) Unwrap() http.ResponseWriter { return w.w } +func (w *rw435) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw435) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw435) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw435) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw435) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw435) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw435) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw435) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw435) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 437/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw436 rwState + +func (w *rw436) Unwrap() http.ResponseWriter { return w.w } +func (w *rw436) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw436) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw436) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw436) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw436) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw436) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw436) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw436) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 438/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw437 rwState + +func (w *rw437) Unwrap() http.ResponseWriter { return w.w } +func (w *rw437) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw437) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw437) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw437) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw437) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw437) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw437) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw437) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw437) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 439/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw438 rwState + +func (w *rw438) Unwrap() http.ResponseWriter { return w.w } +func (w *rw438) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw438) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw438) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw438) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw438) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw438) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw438) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw438) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw438) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 440/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw439 rwState + +func (w *rw439) Unwrap() http.ResponseWriter { return w.w } +func (w *rw439) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw439) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw439) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw439) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw439) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw439) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw439) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw439) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw439) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw439) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 441/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner +type rw440 rwState + +func (w *rw440) Unwrap() http.ResponseWriter { return w.w } +func (w *rw440) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw440) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw440) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw440) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw440) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw440) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw440) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw440) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw440) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 442/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw441 rwState + +func (w *rw441) Unwrap() http.ResponseWriter { return w.w } +func (w *rw441) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw441) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw441) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw441) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw441) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw441) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw441) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw441) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw441) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw441) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 443/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw442 rwState + +func (w *rw442) Unwrap() http.ResponseWriter { return w.w } +func (w *rw442) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw442) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw442) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw442) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw442) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw442) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw442) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw442) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw442) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw442) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 444/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw443 rwState + +func (w *rw443) Unwrap() http.ResponseWriter { return w.w } +func (w *rw443) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw443) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw443) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw443) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw443) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw443) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw443) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw443) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw443) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw443) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw443) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 445/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw444 rwState + +func (w *rw444) Unwrap() http.ResponseWriter { return w.w } +func (w *rw444) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw444) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw444) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw444) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw444) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw444) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw444) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw444) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw444) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw444) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 446/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw445 rwState + +func (w *rw445) Unwrap() http.ResponseWriter { return w.w } +func (w *rw445) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw445) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw445) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw445) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw445) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw445) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw445) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw445) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw445) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw445) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw445) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 447/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw446 rwState + +func (w *rw446) Unwrap() http.ResponseWriter { return w.w } +func (w *rw446) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw446) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw446) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw446) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw446) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw446) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw446) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw446) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw446) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw446) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw446) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 448/512: http.ResponseWriter, http.Flusher, httpFlushError, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw447 rwState + +func (w *rw447) Unwrap() http.ResponseWriter { return w.w } +func (w *rw447) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw447) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw447) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw447) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw447) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw447) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw447) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw447) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw447) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw447) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw447) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw447) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 449/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier +type rw448 rwState + +func (w *rw448) Unwrap() http.ResponseWriter { return w.w } +func (w *rw448) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw448) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw448) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw448) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw448) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw448) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} + +// combination 450/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.StringWriter +type rw449 rwState + +func (w *rw449) Unwrap() http.ResponseWriter { return w.w } +func (w *rw449) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw449) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw449) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw449) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw449) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw449) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw449) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 451/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Pusher +type rw450 rwState + +func (w *rw450) Unwrap() http.ResponseWriter { return w.w } +func (w *rw450) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw450) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw450) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw450) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw450) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw450) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw450) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 452/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Pusher, io.StringWriter +type rw451 rwState + +func (w *rw451) Unwrap() http.ResponseWriter { return w.w } +func (w *rw451) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw451) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw451) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw451) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw451) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw451) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw451) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw451) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 453/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler +type rw452 rwState + +func (w *rw452) Unwrap() http.ResponseWriter { return w.w } +func (w *rw452) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw452) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw452) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw452) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw452) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw452) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw452) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 454/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler, io.StringWriter +type rw453 rwState + +func (w *rw453) Unwrap() http.ResponseWriter { return w.w } +func (w *rw453) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw453) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw453) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw453) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw453) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw453) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw453) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw453) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 455/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher +type rw454 rwState + +func (w *rw454) Unwrap() http.ResponseWriter { return w.w } +func (w *rw454) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw454) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw454) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw454) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw454) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw454) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw454) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw454) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 456/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw455 rwState + +func (w *rw455) Unwrap() http.ResponseWriter { return w.w } +func (w *rw455) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw455) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw455) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw455) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw455) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw455) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw455) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw455) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw455) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 457/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner +type rw456 rwState + +func (w *rw456) Unwrap() http.ResponseWriter { return w.w } +func (w *rw456) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw456) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw456) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw456) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw456) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw456) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw456) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw456) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 458/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, io.StringWriter +type rw457 rwState + +func (w *rw457) Unwrap() http.ResponseWriter { return w.w } +func (w *rw457) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw457) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw457) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw457) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw457) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw457) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw457) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw457) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw457) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 459/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, http.Pusher +type rw458 rwState + +func (w *rw458) Unwrap() http.ResponseWriter { return w.w } +func (w *rw458) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw458) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw458) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw458) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw458) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw458) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw458) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw458) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw458) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 460/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, http.Pusher, io.StringWriter +type rw459 rwState + +func (w *rw459) Unwrap() http.ResponseWriter { return w.w } +func (w *rw459) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw459) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw459) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw459) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw459) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw459) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw459) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw459) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw459) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw459) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 461/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler +type rw460 rwState + +func (w *rw460) Unwrap() http.ResponseWriter { return w.w } +func (w *rw460) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw460) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw460) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw460) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw460) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw460) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw460) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw460) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw460) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 462/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, io.StringWriter +type rw461 rwState + +func (w *rw461) Unwrap() http.ResponseWriter { return w.w } +func (w *rw461) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw461) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw461) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw461) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw461) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw461) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw461) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw461) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw461) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw461) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 463/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher +type rw462 rwState + +func (w *rw462) Unwrap() http.ResponseWriter { return w.w } +func (w *rw462) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw462) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw462) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw462) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw462) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw462) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw462) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw462) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw462) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw462) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 464/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw463 rwState + +func (w *rw463) Unwrap() http.ResponseWriter { return w.w } +func (w *rw463) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw463) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw463) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw463) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw463) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw463) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw463) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw463) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw463) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw463) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw463) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 465/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom +type rw464 rwState + +func (w *rw464) Unwrap() http.ResponseWriter { return w.w } +func (w *rw464) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw464) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw464) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw464) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw464) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw464) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw464) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 466/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, io.StringWriter +type rw465 rwState + +func (w *rw465) Unwrap() http.ResponseWriter { return w.w } +func (w *rw465) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw465) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw465) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw465) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw465) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw465) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw465) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw465) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 467/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher +type rw466 rwState + +func (w *rw466) Unwrap() http.ResponseWriter { return w.w } +func (w *rw466) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw466) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw466) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw466) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw466) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw466) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw466) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw466) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 468/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, http.Pusher, io.StringWriter +type rw467 rwState + +func (w *rw467) Unwrap() http.ResponseWriter { return w.w } +func (w *rw467) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw467) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw467) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw467) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw467) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw467) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw467) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw467) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw467) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 469/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler +type rw468 rwState + +func (w *rw468) Unwrap() http.ResponseWriter { return w.w } +func (w *rw468) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw468) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw468) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw468) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw468) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw468) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw468) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw468) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 470/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw469 rwState + +func (w *rw469) Unwrap() http.ResponseWriter { return w.w } +func (w *rw469) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw469) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw469) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw469) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw469) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw469) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw469) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw469) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw469) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 471/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw470 rwState + +func (w *rw470) Unwrap() http.ResponseWriter { return w.w } +func (w *rw470) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw470) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw470) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw470) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw470) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw470) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw470) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw470) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw470) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 472/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw471 rwState + +func (w *rw471) Unwrap() http.ResponseWriter { return w.w } +func (w *rw471) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw471) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw471) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw471) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw471) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw471) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw471) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw471) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw471) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw471) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 473/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner +type rw472 rwState + +func (w *rw472) Unwrap() http.ResponseWriter { return w.w } +func (w *rw472) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw472) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw472) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw472) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw472) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw472) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw472) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw472) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw472) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 474/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, io.StringWriter +type rw473 rwState + +func (w *rw473) Unwrap() http.ResponseWriter { return w.w } +func (w *rw473) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw473) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw473) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw473) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw473) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw473) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw473) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw473) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw473) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw473) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 475/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher +type rw474 rwState + +func (w *rw474) Unwrap() http.ResponseWriter { return w.w } +func (w *rw474) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw474) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw474) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw474) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw474) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw474) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw474) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw474) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw474) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw474) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 476/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw475 rwState + +func (w *rw475) Unwrap() http.ResponseWriter { return w.w } +func (w *rw475) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw475) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw475) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw475) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw475) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw475) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw475) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw475) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw475) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw475) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw475) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 477/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw476 rwState + +func (w *rw476) Unwrap() http.ResponseWriter { return w.w } +func (w *rw476) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw476) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw476) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw476) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw476) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw476) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw476) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw476) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw476) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw476) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 478/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw477 rwState + +func (w *rw477) Unwrap() http.ResponseWriter { return w.w } +func (w *rw477) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw477) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw477) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw477) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw477) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw477) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw477) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw477) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw477) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw477) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw477) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 479/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw478 rwState + +func (w *rw478) Unwrap() http.ResponseWriter { return w.w } +func (w *rw478) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw478) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw478) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw478) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw478) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw478) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw478) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw478) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw478) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw478) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw478) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 480/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw479 rwState + +func (w *rw479) Unwrap() http.ResponseWriter { return w.w } +func (w *rw479) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw479) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw479) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw479) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw479) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw479) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw479) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw479) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw479) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw479) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw479) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw479) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 481/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker +type rw480 rwState + +func (w *rw480) Unwrap() http.ResponseWriter { return w.w } +func (w *rw480) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw480) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw480) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw480) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw480) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw480) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw480) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} + +// combination 482/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.StringWriter +type rw481 rwState + +func (w *rw481) Unwrap() http.ResponseWriter { return w.w } +func (w *rw481) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw481) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw481) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw481) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw481) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw481) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw481) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw481) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 483/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher +type rw482 rwState + +func (w *rw482) Unwrap() http.ResponseWriter { return w.w } +func (w *rw482) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw482) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw482) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw482) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw482) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw482) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw482) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw482) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 484/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, http.Pusher, io.StringWriter +type rw483 rwState + +func (w *rw483) Unwrap() http.ResponseWriter { return w.w } +func (w *rw483) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw483) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw483) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw483) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw483) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw483) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw483) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw483) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw483) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 485/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler +type rw484 rwState + +func (w *rw484) Unwrap() http.ResponseWriter { return w.w } +func (w *rw484) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw484) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw484) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw484) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw484) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw484) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw484) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw484) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 486/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, io.StringWriter +type rw485 rwState + +func (w *rw485) Unwrap() http.ResponseWriter { return w.w } +func (w *rw485) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw485) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw485) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw485) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw485) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw485) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw485) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw485) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw485) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 487/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher +type rw486 rwState + +func (w *rw486) Unwrap() http.ResponseWriter { return w.w } +func (w *rw486) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw486) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw486) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw486) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw486) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw486) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw486) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw486) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw486) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 488/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw487 rwState + +func (w *rw487) Unwrap() http.ResponseWriter { return w.w } +func (w *rw487) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw487) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw487) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw487) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw487) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw487) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw487) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw487) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw487) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw487) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 489/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner +type rw488 rwState + +func (w *rw488) Unwrap() http.ResponseWriter { return w.w } +func (w *rw488) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw488) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw488) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw488) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw488) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw488) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw488) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw488) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw488) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 490/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, io.StringWriter +type rw489 rwState + +func (w *rw489) Unwrap() http.ResponseWriter { return w.w } +func (w *rw489) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw489) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw489) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw489) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw489) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw489) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw489) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw489) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw489) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw489) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 491/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher +type rw490 rwState + +func (w *rw490) Unwrap() http.ResponseWriter { return w.w } +func (w *rw490) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw490) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw490) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw490) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw490) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw490) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw490) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw490) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw490) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw490) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 492/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, http.Pusher, io.StringWriter +type rw491 rwState + +func (w *rw491) Unwrap() http.ResponseWriter { return w.w } +func (w *rw491) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw491) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw491) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw491) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw491) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw491) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw491) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw491) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw491) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw491) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw491) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 493/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler +type rw492 rwState + +func (w *rw492) Unwrap() http.ResponseWriter { return w.w } +func (w *rw492) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw492) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw492) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw492) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw492) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw492) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw492) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw492) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw492) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw492) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 494/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, io.StringWriter +type rw493 rwState + +func (w *rw493) Unwrap() http.ResponseWriter { return w.w } +func (w *rw493) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw493) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw493) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw493) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw493) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw493) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw493) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw493) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw493) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw493) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw493) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 495/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher +type rw494 rwState + +func (w *rw494) Unwrap() http.ResponseWriter { return w.w } +func (w *rw494) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw494) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw494) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw494) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw494) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw494) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw494) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw494) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw494) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw494) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw494) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 496/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw495 rwState + +func (w *rw495) Unwrap() http.ResponseWriter { return w.w } +func (w *rw495) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw495) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw495) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw495) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw495) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw495) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw495) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw495) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw495) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw495) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw495) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw495) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 497/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom +type rw496 rwState + +func (w *rw496) Unwrap() http.ResponseWriter { return w.w } +func (w *rw496) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw496) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw496) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw496) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw496) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw496) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw496) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw496) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} + +// combination 498/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, io.StringWriter +type rw497 rwState + +func (w *rw497) Unwrap() http.ResponseWriter { return w.w } +func (w *rw497) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw497) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw497) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw497) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw497) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw497) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw497) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw497) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw497) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 499/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher +type rw498 rwState + +func (w *rw498) Unwrap() http.ResponseWriter { return w.w } +func (w *rw498) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw498) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw498) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw498) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw498) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw498) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw498) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw498) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw498) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 500/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher, io.StringWriter +type rw499 rwState + +func (w *rw499) Unwrap() http.ResponseWriter { return w.w } +func (w *rw499) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw499) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw499) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw499) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw499) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw499) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw499) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw499) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw499) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw499) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 501/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler +type rw500 rwState + +func (w *rw500) Unwrap() http.ResponseWriter { return w.w } +func (w *rw500) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw500) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw500) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw500) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw500) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw500) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw500) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw500) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw500) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 502/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, io.StringWriter +type rw501 rwState + +func (w *rw501) Unwrap() http.ResponseWriter { return w.w } +func (w *rw501) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw501) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw501) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw501) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw501) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw501) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw501) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw501) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw501) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw501) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 503/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher +type rw502 rwState + +func (w *rw502) Unwrap() http.ResponseWriter { return w.w } +func (w *rw502) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw502) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw502) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw502) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw502) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw502) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw502) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw502) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw502) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw502) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 504/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw503 rwState + +func (w *rw503) Unwrap() http.ResponseWriter { return w.w } +func (w *rw503) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw503) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw503) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw503) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw503) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw503) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw503) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw503) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw503) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw503) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw503) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 505/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner +type rw504 rwState + +func (w *rw504) Unwrap() http.ResponseWriter { return w.w } +func (w *rw504) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw504) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw504) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw504) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw504) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw504) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw504) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw504) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw504) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw504) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} + +// combination 506/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, io.StringWriter +type rw505 rwState + +func (w *rw505) Unwrap() http.ResponseWriter { return w.w } +func (w *rw505) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw505) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw505) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw505) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw505) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw505) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw505) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw505) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw505) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw505) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw505) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 507/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher +type rw506 rwState + +func (w *rw506) Unwrap() http.ResponseWriter { return w.w } +func (w *rw506) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw506) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw506) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw506) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw506) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw506) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw506) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw506) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw506) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw506) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw506) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 508/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, http.Pusher, io.StringWriter +type rw507 rwState + +func (w *rw507) Unwrap() http.ResponseWriter { return w.w } +func (w *rw507) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw507) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw507) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw507) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw507) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw507) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw507) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw507) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw507) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw507) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw507) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw507) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 509/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler +type rw508 rwState + +func (w *rw508) Unwrap() http.ResponseWriter { return w.w } +func (w *rw508) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw508) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw508) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw508) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw508) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw508) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw508) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw508) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw508) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw508) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw508) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} + +// combination 510/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, io.StringWriter +type rw509 rwState + +func (w *rw509) Unwrap() http.ResponseWriter { return w.w } +func (w *rw509) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw509) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw509) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw509) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw509) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw509) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw509) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw509) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw509) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw509) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw509) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw509) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +// combination 511/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher +type rw510 rwState + +func (w *rw510) Unwrap() http.ResponseWriter { return w.w } +func (w *rw510) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw510) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw510) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw510) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw510) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw510) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw510) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw510) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw510) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw510) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw510) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw510) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} + +// combination 512/512: http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter +type rw511 rwState + +func (w *rw511) Unwrap() http.ResponseWriter { return w.w } +func (w *rw511) Header() http.Header { + return (*rwState)(w).doHeader() +} +func (w *rw511) WriteHeader(code int) { + (*rwState)(w).doWriteHeader(code) +} +func (w *rw511) Write(b []byte) (int, error) { + return (*rwState)(w).doWrite(b) +} +func (w *rw511) Flush() { + (*rwState)(w).doFlush() +} +func (w *rw511) FlushError() error { + return (*rwState)(w).doFlushError() +} +func (w *rw511) CloseNotify() <-chan bool { + return (*rwState)(w).doCloseNotify() +} +func (w *rw511) Hijack() (net.Conn, *bufio.ReadWriter, error) { + return (*rwState)(w).doHijack() +} +func (w *rw511) ReadFrom(src io.Reader) (int64, error) { + return (*rwState)(w).doReadFrom(src) +} +func (w *rw511) SetReadDeadline(deadline time.Time) error { + return (*rwState)(w).doSetReadDeadline(deadline) +} +func (w *rw511) SetWriteDeadline(deadline time.Time) error { + return (*rwState)(w).doSetWriteDeadline(deadline) +} +func (w *rw511) EnableFullDuplex() error { + return (*rwState)(w).doEnableFullDuplex() +} +func (w *rw511) Push(target string, opts *http.PushOptions) error { + return (*rwState)(w).doPush(target, opts) +} +func (w *rw511) WriteString(s string) (int, error) { + return (*rwState)(w).doWriteString(s) +} + +type Unwrapper interface { + Unwrap() http.ResponseWriter +} + +// Unwrap returns the underlying http.ResponseWriter from within zero or more +// layers of httpsnoop wrappers. +func Unwrap(w http.ResponseWriter) http.ResponseWriter { + if rw, ok := w.(Unwrapper); ok { + // recurse until rw.Unwrap() returns a non-Unwrapper + return Unwrap(rw.Unwrap()) + } + return w +} diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go deleted file mode 100644 index 101cedde674..00000000000 --- a/vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go +++ /dev/null @@ -1,436 +0,0 @@ -// +build go1.8 -// Code generated by "httpsnoop/codegen"; DO NOT EDIT. - -package httpsnoop - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// HeaderFunc is part of the http.ResponseWriter interface. -type HeaderFunc func() http.Header - -// WriteHeaderFunc is part of the http.ResponseWriter interface. -type WriteHeaderFunc func(code int) - -// WriteFunc is part of the http.ResponseWriter interface. -type WriteFunc func(b []byte) (int, error) - -// FlushFunc is part of the http.Flusher interface. -type FlushFunc func() - -// CloseNotifyFunc is part of the http.CloseNotifier interface. -type CloseNotifyFunc func() <-chan bool - -// HijackFunc is part of the http.Hijacker interface. -type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) - -// ReadFromFunc is part of the io.ReaderFrom interface. -type ReadFromFunc func(src io.Reader) (int64, error) - -// PushFunc is part of the http.Pusher interface. -type PushFunc func(target string, opts *http.PushOptions) error - -// Hooks defines a set of method interceptors for methods included in -// http.ResponseWriter as well as some others. You can think of them as -// middleware for the function calls they target. See Wrap for more details. -type Hooks struct { - Header func(HeaderFunc) HeaderFunc - WriteHeader func(WriteHeaderFunc) WriteHeaderFunc - Write func(WriteFunc) WriteFunc - Flush func(FlushFunc) FlushFunc - CloseNotify func(CloseNotifyFunc) CloseNotifyFunc - Hijack func(HijackFunc) HijackFunc - ReadFrom func(ReadFromFunc) ReadFromFunc - Push func(PushFunc) PushFunc -} - -// Wrap returns a wrapped version of w that provides the exact same interface -// as w. Specifically if w implements any combination of: -// -// - http.Flusher -// - http.CloseNotifier -// - http.Hijacker -// - io.ReaderFrom -// - http.Pusher -// -// The wrapped version will implement the exact same combination. If no hooks -// are set, the wrapped version also behaves exactly as w. Hooks targeting -// methods not supported by w are ignored. Any other hooks will intercept the -// method they target and may modify the call's arguments and/or return values. -// The CaptureMetrics implementation serves as a working example for how the -// hooks can be used. -func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { - rw := &rw{w: w, h: hooks} - _, i0 := w.(http.Flusher) - _, i1 := w.(http.CloseNotifier) - _, i2 := w.(http.Hijacker) - _, i3 := w.(io.ReaderFrom) - _, i4 := w.(http.Pusher) - switch { - // combination 1/32 - case !i0 && !i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - }{rw, rw} - // combination 2/32 - case !i0 && !i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Pusher - }{rw, rw, rw} - // combination 3/32 - case !i0 && !i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - }{rw, rw, rw} - // combination 4/32 - case !i0 && !i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw} - // combination 5/32 - case !i0 && !i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - }{rw, rw, rw} - // combination 6/32 - case !i0 && !i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - http.Pusher - }{rw, rw, rw, rw} - // combination 7/32 - case !i0 && !i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 8/32 - case !i0 && !i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 9/32 - case !i0 && i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - }{rw, rw, rw} - // combination 10/32 - case !i0 && i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Pusher - }{rw, rw, rw, rw} - // combination 11/32 - case !i0 && i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 12/32 - case !i0 && i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 13/32 - case !i0 && i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw} - // combination 14/32 - case !i0 && i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 15/32 - case !i0 && i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 16/32 - case !i0 && i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 17/32 - case i0 && !i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - }{rw, rw, rw} - // combination 18/32 - case i0 && !i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Pusher - }{rw, rw, rw, rw} - // combination 19/32 - case i0 && !i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 20/32 - case i0 && !i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 21/32 - case i0 && !i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - }{rw, rw, rw, rw} - // combination 22/32 - case i0 && !i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 23/32 - case i0 && !i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 24/32 - case i0 && !i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 25/32 - case i0 && i1 && !i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - }{rw, rw, rw, rw} - // combination 26/32 - case i0 && i1 && !i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Pusher - }{rw, rw, rw, rw, rw} - // combination 27/32 - case i0 && i1 && !i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 28/32 - case i0 && i1 && !i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 29/32 - case i0 && i1 && i2 && !i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw, rw} - // combination 30/32 - case i0 && i1 && i2 && !i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - http.Pusher - }{rw, rw, rw, rw, rw, rw} - // combination 31/32 - case i0 && i1 && i2 && i3 && !i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw, rw} - // combination 32/32 - case i0 && i1 && i2 && i3 && i4: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - http.Pusher - }{rw, rw, rw, rw, rw, rw, rw} - } - panic("unreachable") -} - -type rw struct { - w http.ResponseWriter - h Hooks -} - -func (w *rw) Unwrap() http.ResponseWriter { - return w.w -} - -func (w *rw) Header() http.Header { - f := w.w.(http.ResponseWriter).Header - if w.h.Header != nil { - f = w.h.Header(f) - } - return f() -} - -func (w *rw) WriteHeader(code int) { - f := w.w.(http.ResponseWriter).WriteHeader - if w.h.WriteHeader != nil { - f = w.h.WriteHeader(f) - } - f(code) -} - -func (w *rw) Write(b []byte) (int, error) { - f := w.w.(http.ResponseWriter).Write - if w.h.Write != nil { - f = w.h.Write(f) - } - return f(b) -} - -func (w *rw) Flush() { - f := w.w.(http.Flusher).Flush - if w.h.Flush != nil { - f = w.h.Flush(f) - } - f() -} - -func (w *rw) CloseNotify() <-chan bool { - f := w.w.(http.CloseNotifier).CloseNotify - if w.h.CloseNotify != nil { - f = w.h.CloseNotify(f) - } - return f() -} - -func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { - f := w.w.(http.Hijacker).Hijack - if w.h.Hijack != nil { - f = w.h.Hijack(f) - } - return f() -} - -func (w *rw) ReadFrom(src io.Reader) (int64, error) { - f := w.w.(io.ReaderFrom).ReadFrom - if w.h.ReadFrom != nil { - f = w.h.ReadFrom(f) - } - return f(src) -} - -func (w *rw) Push(target string, opts *http.PushOptions) error { - f := w.w.(http.Pusher).Push - if w.h.Push != nil { - f = w.h.Push(f) - } - return f(target, opts) -} - -type Unwrapper interface { - Unwrap() http.ResponseWriter -} - -// Unwrap returns the underlying http.ResponseWriter from within zero or more -// layers of httpsnoop wrappers. -func Unwrap(w http.ResponseWriter) http.ResponseWriter { - if rw, ok := w.(Unwrapper); ok { - // recurse until rw.Unwrap() returns a non-Unwrapper - return Unwrap(rw.Unwrap()) - } else { - return w - } -} diff --git a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go b/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go deleted file mode 100644 index e0951df1527..00000000000 --- a/vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go +++ /dev/null @@ -1,278 +0,0 @@ -// +build !go1.8 -// Code generated by "httpsnoop/codegen"; DO NOT EDIT. - -package httpsnoop - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// HeaderFunc is part of the http.ResponseWriter interface. -type HeaderFunc func() http.Header - -// WriteHeaderFunc is part of the http.ResponseWriter interface. -type WriteHeaderFunc func(code int) - -// WriteFunc is part of the http.ResponseWriter interface. -type WriteFunc func(b []byte) (int, error) - -// FlushFunc is part of the http.Flusher interface. -type FlushFunc func() - -// CloseNotifyFunc is part of the http.CloseNotifier interface. -type CloseNotifyFunc func() <-chan bool - -// HijackFunc is part of the http.Hijacker interface. -type HijackFunc func() (net.Conn, *bufio.ReadWriter, error) - -// ReadFromFunc is part of the io.ReaderFrom interface. -type ReadFromFunc func(src io.Reader) (int64, error) - -// Hooks defines a set of method interceptors for methods included in -// http.ResponseWriter as well as some others. You can think of them as -// middleware for the function calls they target. See Wrap for more details. -type Hooks struct { - Header func(HeaderFunc) HeaderFunc - WriteHeader func(WriteHeaderFunc) WriteHeaderFunc - Write func(WriteFunc) WriteFunc - Flush func(FlushFunc) FlushFunc - CloseNotify func(CloseNotifyFunc) CloseNotifyFunc - Hijack func(HijackFunc) HijackFunc - ReadFrom func(ReadFromFunc) ReadFromFunc -} - -// Wrap returns a wrapped version of w that provides the exact same interface -// as w. Specifically if w implements any combination of: -// -// - http.Flusher -// - http.CloseNotifier -// - http.Hijacker -// - io.ReaderFrom -// -// The wrapped version will implement the exact same combination. If no hooks -// are set, the wrapped version also behaves exactly as w. Hooks targeting -// methods not supported by w are ignored. Any other hooks will intercept the -// method they target and may modify the call's arguments and/or return values. -// The CaptureMetrics implementation serves as a working example for how the -// hooks can be used. -func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter { - rw := &rw{w: w, h: hooks} - _, i0 := w.(http.Flusher) - _, i1 := w.(http.CloseNotifier) - _, i2 := w.(http.Hijacker) - _, i3 := w.(io.ReaderFrom) - switch { - // combination 1/16 - case !i0 && !i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - }{rw, rw} - // combination 2/16 - case !i0 && !i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - io.ReaderFrom - }{rw, rw, rw} - // combination 3/16 - case !i0 && !i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - }{rw, rw, rw} - // combination 4/16 - case !i0 && !i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 5/16 - case !i0 && i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - }{rw, rw, rw} - // combination 6/16 - case !i0 && i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 7/16 - case !i0 && i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw} - // combination 8/16 - case !i0 && i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 9/16 - case i0 && !i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - }{rw, rw, rw} - // combination 10/16 - case i0 && !i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - io.ReaderFrom - }{rw, rw, rw, rw} - // combination 11/16 - case i0 && !i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - }{rw, rw, rw, rw} - // combination 12/16 - case i0 && !i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 13/16 - case i0 && i1 && !i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - }{rw, rw, rw, rw} - // combination 14/16 - case i0 && i1 && !i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - io.ReaderFrom - }{rw, rw, rw, rw, rw} - // combination 15/16 - case i0 && i1 && i2 && !i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - }{rw, rw, rw, rw, rw} - // combination 16/16 - case i0 && i1 && i2 && i3: - return struct { - Unwrapper - http.ResponseWriter - http.Flusher - http.CloseNotifier - http.Hijacker - io.ReaderFrom - }{rw, rw, rw, rw, rw, rw} - } - panic("unreachable") -} - -type rw struct { - w http.ResponseWriter - h Hooks -} - -func (w *rw) Unwrap() http.ResponseWriter { - return w.w -} - -func (w *rw) Header() http.Header { - f := w.w.(http.ResponseWriter).Header - if w.h.Header != nil { - f = w.h.Header(f) - } - return f() -} - -func (w *rw) WriteHeader(code int) { - f := w.w.(http.ResponseWriter).WriteHeader - if w.h.WriteHeader != nil { - f = w.h.WriteHeader(f) - } - f(code) -} - -func (w *rw) Write(b []byte) (int, error) { - f := w.w.(http.ResponseWriter).Write - if w.h.Write != nil { - f = w.h.Write(f) - } - return f(b) -} - -func (w *rw) Flush() { - f := w.w.(http.Flusher).Flush - if w.h.Flush != nil { - f = w.h.Flush(f) - } - f() -} - -func (w *rw) CloseNotify() <-chan bool { - f := w.w.(http.CloseNotifier).CloseNotify - if w.h.CloseNotify != nil { - f = w.h.CloseNotify(f) - } - return f() -} - -func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) { - f := w.w.(http.Hijacker).Hijack - if w.h.Hijack != nil { - f = w.h.Hijack(f) - } - return f() -} - -func (w *rw) ReadFrom(src io.Reader) (int64, error) { - f := w.w.(io.ReaderFrom).ReadFrom - if w.h.ReadFrom != nil { - f = w.h.ReadFrom(f) - } - return f(src) -} - -type Unwrapper interface { - Unwrap() http.ResponseWriter -} - -// Unwrap returns the underlying http.ResponseWriter from within zero or more -// layers of httpsnoop wrappers. -func Unwrap(w http.ResponseWriter) http.ResponseWriter { - if rw, ok := w.(Unwrapper); ok { - // recurse until rw.Unwrap() returns a non-Unwrapper - return Unwrap(rw.Unwrap()) - } else { - return w - } -} diff --git a/vendor/github.com/go-openapi/analysis/.gitignore b/vendor/github.com/go-openapi/analysis/.gitignore index d8f4186fe59..20c4e0fa048 100644 --- a/vendor/github.com/go-openapi/analysis/.gitignore +++ b/vendor/github.com/go-openapi/analysis/.gitignore @@ -3,3 +3,5 @@ .idea .env .mcp.json +go.work.sum +.worktrees diff --git a/vendor/github.com/go-openapi/analysis/.golangci.yml b/vendor/github.com/go-openapi/analysis/.golangci.yml index b97d68077f8..0d7baa1d7fb 100644 --- a/vendor/github.com/go-openapi/analysis/.golangci.yml +++ b/vendor/github.com/go-openapi/analysis/.golangci.yml @@ -4,8 +4,11 @@ linters: disable: - depguard - funlen + - goconst - godox - gomoddirectives + - gomodguard + - gomodguard_v2 - exhaustruct - nlreturn - nonamedreturns diff --git a/vendor/github.com/go-openapi/analysis/CONTRIBUTORS.md b/vendor/github.com/go-openapi/analysis/CONTRIBUTORS.md index 2f85f1c0504..a89274cdbc3 100644 --- a/vendor/github.com/go-openapi/analysis/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/analysis/CONTRIBUTORS.md @@ -4,24 +4,31 @@ | Total Contributors | Total Contributions | | --- | --- | -| 15 | 207 | +| 22 | 273 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | -| @fredbi | 104 | | -| @casualjim | 70 | | +| @fredbi | 133 | | +| @casualjim | 91 | | | @keramix | 9 | | | @youyuanwu | 8 | | -| @msample | 3 | | +| @wjase | 7 | | | @kul-amr | 3 | | +| @schafle | 3 | | +| @msample | 3 | | | @mbohlool | 2 | | -| @Copilot | 1 | | -| @danielfbm | 1 | | -| @gregmarr | 1 | | -| @guillemj | 1 | | -| @knweiss | 1 | | -| @tklauser | 1 | | -| @cuishuang | 1 | | +| @zmay2030 | 2 | | | @ujjwalsh | 1 | | +| @itengfei | 1 | | +| @nrnrk | 1 | | +| @cuishuang | 1 | | +| @tklauser | 1 | | +| @Shimizu1111 | 1 | | +| @thaJeztah | 1 | | +| @knweiss | 1 | | +| @guillemj | 1 | | +| @gregmarr | 1 | | +| @danielfbm | 1 | | +| @Copilot | 1 | | _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/analysis/README.md b/vendor/github.com/go-openapi/analysis/README.md index 82c782fcdd4..2a90462974e 100644 --- a/vendor/github.com/go-openapi/analysis/README.md +++ b/vendor/github.com/go-openapi/analysis/README.md @@ -12,18 +12,15 @@ --- -A foundational library to analyze an OAI specification document for easier reasoning about the content. +A foundational library to analyze, diff, flatten, merge, and fix OAI specification documents for easier reasoning about the content. ## Announcements * **2025-12-19** : new community chat on discord * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] - ## Status API is stable. @@ -38,6 +35,7 @@ go get github.com/go-openapi/analysis * An analyzer providing methods to walk the functional content of a specification * A spec flattener producing a self-contained document bundle, while preserving `$ref`s +* A spec differ ("diff") to compare two specs and report structural and compatibility changes * A spec merger ("mixin") to merge several spec documents into a primary spec * A spec "fixer" ensuring that response descriptions are non empty @@ -78,9 +76,9 @@ on top of which it has been built. ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -111,9 +109,6 @@ Maintainers can cut a new release by either: [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/analysis [godoc-url]: http://pkg.go.dev/github.com/go-openapi/analysis -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue [discord-url]: https://discord.gg/FfnFYaC3k5 @@ -125,3 +120,7 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/analysis/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/analysis [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/analysis/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/analysis/analyzer.go b/vendor/github.com/go-openapi/analysis/analyzer.go index 1c91b8c5507..c24811aaeb5 100644 --- a/vendor/github.com/go-openapi/analysis/analyzer.go +++ b/vendor/github.com/go-openapi/analysis/analyzer.go @@ -145,19 +145,27 @@ type Spec struct { enums enumAnalysis allSchemas map[string]SchemaRef allOfs map[string]SchemaRef + mangler mangling.NameMangler } // New takes a swagger spec object and returns an analyzed spec document. // The analyzed document contains a number of indices that make it easier to // reason about semantics of a swagger specification for use in code generation // or validation etc. -func New(doc *spec.Swagger) *Spec { +func New(doc *spec.Swagger, opts ...Option) *Spec { + o := &analyzerOptions{} + for _, opt := range opts { + opt(o) + } + a := &Spec{ spec: doc, references: referenceAnalysis{}, patterns: patternAnalysis{}, enums: enumAnalysis{}, + mangler: mangling.NewNameMangler(o.manglerOpts...), } + a.reset() a.initialize() @@ -288,20 +296,6 @@ func (s *Spec) ProducesFor(operation *spec.Operation) []string { return s.structMapKeys(prod) } -func mapKeyFromParam(param *spec.Parameter) string { - return fmt.Sprintf("%s#%s", param.In, fieldNameFromParam(param)) -} - -func fieldNameFromParam(param *spec.Parameter) string { - // TODO: this should be x-go-name - if nm, ok := param.Extensions.GetString("go-name"); ok { - return nm - } - mangler := mangling.NewNameMangler() - - return mangler.ToGoName(param.Name) -} - // ErrorOnParamFunc is a callback function to be invoked // whenever an error is encountered while resolving references // on parameters. @@ -651,6 +645,19 @@ func (s *Spec) AllEnums() map[string][]any { return cloneEnumMap(s.enums.allEnums) } +func (s *Spec) mapKeyFromParam(param *spec.Parameter) string { + return fmt.Sprintf("%s#%s", param.In, s.fieldNameFromParam(param)) +} + +func (s *Spec) fieldNameFromParam(param *spec.Parameter) string { + // TODO: this should be x-go-name + if nm, ok := param.Extensions.GetString("go-name"); ok { + return nm + } + + return s.mangler.ToGoName(param.Name) +} + func (s *Spec) structMapKeys(mp map[string]struct{}) []string { if len(mp) == 0 { return nil @@ -668,7 +675,7 @@ func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Para for _, param := range parameters { pr := param if pr.Ref.String() == "" { - res[mapKeyFromParam(&pr)] = pr + res[s.mapKeyFromParam(&pr)] = pr continue } @@ -699,7 +706,7 @@ func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Para } pr = objAsParam - res[mapKeyFromParam(&pr)] = pr + res[s.mapKeyFromParam(&pr)] = pr } } diff --git a/vendor/github.com/go-openapi/analysis/flatten.go b/vendor/github.com/go-openapi/analysis/flatten.go index d7ee0064b6f..c90456f6a05 100644 --- a/vendor/github.com/go-openapi/analysis/flatten.go +++ b/vendor/github.com/go-openapi/analysis/flatten.go @@ -243,7 +243,7 @@ func nameInlinedSchemas(opts *FlattenOpts) error { continue } - asch, err := Schema(SchemaOpts{Schema: sch.Schema, Root: opts.Swagger(), BasePath: opts.BasePath}) + asch, err := Schema(SchemaOpts{Schema: sch.Schema, Root: opts.Swagger(), BasePath: opts.BasePath, PathLoaderWithOptions: opts.PathLoaderWithOptions}) if err != nil { return ErrAtKey(key, err) } @@ -554,6 +554,7 @@ func updateRefParents(allRefs map[string]spec.Ref, r *newRef) { } } +//nolint:gocognit,gocyclo,cyclop // legacy from a lot of design choices that led to concentrate the complexity just here. func stripOAIGenForRef(opts *FlattenOpts, k string, r *newRef) (bool, error) { replacedWithComplex := false @@ -574,7 +575,7 @@ func stripOAIGenForRef(opts *FlattenOpts, k string, r *newRef) (bool, error) { } // rewrite other parents to point to first parent - if len(pr) > 1 { + if len(pr) > 1 { //nolint:nestif // should be refactored at a later time for _, p := range pr[1:] { replacingRef := spec.MustCreateRef(pr[0]) @@ -656,7 +657,7 @@ func stripOAIGenForRef(opts *FlattenOpts, k string, r *newRef) (bool, error) { // determine if the previous substitution did inline a complex schema if r.schema != nil && r.schema.Ref.String() == "" { // inline schema - asch, err := Schema(SchemaOpts{Schema: r.schema, Root: opts.Swagger(), BasePath: opts.BasePath}) + asch, err := Schema(SchemaOpts{Schema: r.schema, Root: opts.Swagger(), BasePath: opts.BasePath, PathLoaderWithOptions: opts.PathLoaderWithOptions}) if err != nil { return false, err } @@ -760,7 +761,7 @@ func flattenAnonPointer(key string, v SchemaRef, refsToReplace map[string]Schema debugLog("namePointers at %s for %s", key, v.Ref.String()) // qualify the expanded schema - asch, ers := Schema(SchemaOpts{Schema: v.Schema, Root: opts.Swagger(), BasePath: opts.BasePath}) + asch, ers := Schema(SchemaOpts{Schema: v.Schema, Root: opts.Swagger(), BasePath: opts.BasePath, PathLoaderWithOptions: opts.PathLoaderWithOptions}) if ers != nil { return ErrAtKey(key, ers) } diff --git a/vendor/github.com/go-openapi/analysis/flatten_name.go b/vendor/github.com/go-openapi/analysis/flatten_name.go index 922cae55c5e..9d732171840 100644 --- a/vendor/github.com/go-openapi/analysis/flatten_name.go +++ b/vendor/github.com/go-openapi/analysis/flatten_name.go @@ -273,9 +273,9 @@ func mangler(o *FlattenOpts) func(string) string { if o.KeepNames { return func(in string) string { return in } } - mangler := mangling.NewNameMangler() + m := mangling.NewNameMangler(o.ManglerOpts...) - return mangler.ToJSONName + return m.ToJSONName } func nameFromRef(ref spec.Ref, o *FlattenOpts) string { diff --git a/vendor/github.com/go-openapi/analysis/flatten_options.go b/vendor/github.com/go-openapi/analysis/flatten_options.go index 23a57ea1aca..1e182ad4355 100644 --- a/vendor/github.com/go-openapi/analysis/flatten_options.go +++ b/vendor/github.com/go-openapi/analysis/flatten_options.go @@ -4,9 +4,12 @@ package analysis import ( + "encoding/json" "log" "github.com/go-openapi/spec" + "github.com/go-openapi/swag/loading" + "github.com/go-openapi/swag/mangling" ) // FlattenOpts configuration for flattening a swagger specification. @@ -24,12 +27,23 @@ type FlattenOpts struct { BasePath string // The location of the root document for this spec to resolve relative $ref // Flattening options - Expand bool // When true, skip flattening the spec and expand it instead (if Minimal is false) - Minimal bool // When true, do not decompose complex structures such as allOf - Verbose bool // enable some reporting on possible name conflicts detected - RemoveUnused bool // When true, remove unused parameters, responses and definitions after expansion/flattening - ContinueOnError bool // Continue when spec expansion issues are found - KeepNames bool // Do not attempt to jsonify names from references when flattening + Expand bool // When true, skip flattening the spec and expand it instead (if Minimal is false) + Minimal bool // When true, do not decompose complex structures such as allOf + Verbose bool // enable some reporting on possible name conflicts detected + RemoveUnused bool // When true, remove unused parameters, responses and definitions after expansion/flattening + ContinueOnError bool // Continue when spec expansion issues are found + KeepNames bool // Do not attempt to jsonify names from references when flattening + ManglerOpts []mangling.Option `json:"-"` // Options for the name mangler used to jsonify names + + // PathLoaderWithOptions injects the document loader used to resolve remote and relative $ref + // while flattening or expanding the specification. It matches the option-aware loader signature + // of github.com/go-openapi/swag/loading (and go-openapi/loads). + // + // Security: when flattening a specification obtained from an untrusted source, set this to a + // confined loader — for example one built with loading.WithRoot (to confine local reads) and + // loading.WithHTTPClient (to restrict remote fetches), or a restricted loader from + // go-openapi/loads. Left nil, the spec package default (unsandboxed) loader is used. + PathLoaderWithOptions func(string, ...loading.Option) (json.RawMessage, error) `json:"-"` /* Extra keys */ _ struct{} // require keys @@ -38,9 +52,10 @@ type FlattenOpts struct { // ExpandOpts creates a spec.[spec.ExpandOptions] to configure expanding a specification document. func (f *FlattenOpts) ExpandOpts(skipSchemas bool) *spec.ExpandOptions { return &spec.ExpandOptions{ - RelativeBase: f.BasePath, - SkipSchemas: skipSchemas, - ContinueOnError: f.ContinueOnError, + RelativeBase: f.BasePath, + SkipSchemas: skipSchemas, + ContinueOnError: f.ContinueOnError, + PathLoaderWithOptions: f.PathLoaderWithOptions, } } diff --git a/vendor/github.com/go-openapi/analysis/go.work.sum b/vendor/github.com/go-openapi/analysis/go.work.sum deleted file mode 100644 index 899a68976e7..00000000000 --- a/vendor/github.com/go-openapi/analysis/go.work.sum +++ /dev/null @@ -1,47 +0,0 @@ -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss= -go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= -golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= diff --git a/vendor/github.com/go-openapi/analysis/mixin.go b/vendor/github.com/go-openapi/analysis/mixin.go index a7a9306cb37..635b1b0ad4a 100644 --- a/vendor/github.com/go-openapi/analysis/mixin.go +++ b/vendor/github.com/go-openapi/analysis/mixin.go @@ -11,37 +11,66 @@ import ( "github.com/go-openapi/spec" ) -// Mixin modifies the primary swagger spec by adding the paths and -// definitions from the mixin specs. Top level parameters and -// responses from the mixins are also carried over. Operation id -// collisions are avoided by appending "Mixin" but only if -// needed. +// Mixin merges one or more Swagger 2.0 documents into a primary document. // -// The following parts of primary are subject to merge, filling empty details +// # Argument order and precedence // -// - Info +// The first argument is the primary spec, which Mixin modifies in place. +// Subsequent arguments are mixins, listed in decreasing order of priority. +// On any collision, the primary always wins; among mixins, the earliest one +// wins. +// +// Example: given a primary spec with host "a.example.com" and a mixin with +// host "b.example.com", the merged result keeps "a.example.com" (primary +// wins, the mixin value is dropped). Given a primary without a host and a +// mixin with host "b.example.com", the merged result uses "b.example.com" +// (the mixin fills in the empty field on the primary). +// +// # What gets merged +// +// Top-level scalar fields on the primary are filled from the first mixin +// that provides them, but only if the primary's value is the zero value: +// +// - Info (including the nested Contact and License) // - BasePath // - Host // - ExternalDocs // -// Consider calling [FixEmptyResponseDescriptions]() on the modified primary -// if you read them from storage and they are valid to start with. +// Map and slice fields are merged entry by entry. This covers: +// +// - paths, definitions, parameters, responses +// - securityDefinitions, security, tags +// - top-level and Info extensions +// +// Duplicate keys (or equal security requirements, or equal tag names) are +// skipped with a warning; warnings are returned as a slice and intended to +// be inspected by the caller (e.g. compared to an expected collision count +// in build scripts). +// +// Schemes, consumes and produces are merged as the union of distinct +// values. Duplicates there are silently dropped, no warning is emitted. +// +// Operation id collisions are auto-resolved by appending "Mixin" to the +// mixin operation id (N is the mixin index), so the merged spec keeps +// unique operation ids. +// +// # Notes and limitations // -// Entries in "paths", "definitions", "parameters" and "responses" are -// added to the primary in the order of the given mixins. If the entry -// already exists in primary it is skipped with a warning message. +// Consider calling [FixEmptyResponseDescriptions] on the modified primary +// if you read responses from storage and they are valid to start with. // -// The count of skipped entries (from collisions) is returned so any -// deviation from the number expected can flag a warning in your build -// scripts. Carefully review the collisions before accepting them; -// consider renaming things if possible. +// No key normalization takes place. Ensure paths, type names, etc. are +// canonical if your downstream tools rely on normalized forms. // -// No key normalization takes place (paths, type defs, -// etc). Ensure they are canonical if your downstream tools do -// key normalization of any form. +// YAML anchors (& / *) are resolved by the YAML parser before Mixin sees +// the document, so they are not preserved in the merged output, and they +// cannot be shared across input files. Use $ref for cross-file reuse. See +// https://goswagger.io/go-swagger/faq/faq_swagger/#does-swagger-mixin-preserve-yaml-anchors // -// Merging schemes ([http], https), and consumers/producers do not account for -// collisions. +// The order of paths and definitions in the merged output is alphabetical: +// the underlying spec model stores them as Go maps, which serialize with +// sorted keys. Source-file order is not preserved. See +// https://goswagger.io/go-swagger/faq/faq_swagger/#can-i-control-the-path-or-operation-order-in-swagger-mixin-output func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string { skipped := make([]string, 0, len(mixins)) opIDs := getOpIDs(primary) @@ -101,6 +130,7 @@ func pathItemOps(p spec.PathItem) []*spec.Operation { rv = appendOp(rv, p.Post) rv = appendOp(rv, p.Delete) rv = appendOp(rv, p.Head) + rv = appendOp(rv, p.Options) rv = appendOp(rv, p.Patch) return rv @@ -184,9 +214,9 @@ func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIDs map[string]bool, m // Swagger requires that operationIds be // unique within a spec. If we find a // collision we append "Mixin0" to the - // operatoinId we are adding, where 0 is mixin + // operationId we are adding, where 0 is mixin // index. We assume that operationIds with - // all the proivded specs are already unique. + // all the provided specs are already unique. piops := pathItemOps(v) for _, piop := range piops { if opIDs[piop.ID] { @@ -329,7 +359,7 @@ func mergeSwaggerProps(primary *spec.Swagger, m *spec.Swagger) []string { if primary.ExternalDocs == nil { primary.ExternalDocs = m.ExternalDocs - } else if m != nil { + } else if m.ExternalDocs != nil { skippedDocs = mergeExternalDocs(primary.ExternalDocs, m.ExternalDocs) skipped = append(skipped, skippedDocs...) } diff --git a/vendor/github.com/go-openapi/analysis/options.go b/vendor/github.com/go-openapi/analysis/options.go new file mode 100644 index 00000000000..b46cd2ca693 --- /dev/null +++ b/vendor/github.com/go-openapi/analysis/options.go @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package analysis + +import "github.com/go-openapi/swag/mangling" + +// Option configures the behavior of a new [Spec] analyzer. +type Option func(*analyzerOptions) + +type analyzerOptions struct { + manglerOpts []mangling.Option +} + +// WithManglerOptions sets the name mangler options used when building +// Go identifiers from specification names (e.g. parameter names). +func WithManglerOptions(opts ...mangling.Option) Option { + return func(o *analyzerOptions) { + o.manglerOpts = append(o.manglerOpts, opts...) + } +} diff --git a/vendor/github.com/go-openapi/analysis/schema.go b/vendor/github.com/go-openapi/analysis/schema.go index bedea652acf..2c250461eb0 100644 --- a/vendor/github.com/go-openapi/analysis/schema.go +++ b/vendor/github.com/go-openapi/analysis/schema.go @@ -4,8 +4,11 @@ package analysis import ( + "encoding/json" + "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag/loading" ) // SchemaOpts configures the schema analyzer. @@ -13,7 +16,17 @@ type SchemaOpts struct { Schema *spec.Schema Root any BasePath string - _ struct{} + + // PathLoaderWithOptions injects the document loader (with loading options) used to resolve + // remote and relative $ref while analyzing a schema. + // + // Security: set this to a confined loader — for example one built with loading.WithRoot and + // loading.WithHTTPClient, or a restricted loader from go-openapi/loads — when the schema may + // derive from an untrusted source. Left nil, the spec package default (unsandboxed) loader is + // used. + PathLoaderWithOptions func(string, ...loading.Option) (json.RawMessage, error) + + _ struct{} } // Schema analysis, will classify the schema according to known @@ -24,9 +37,10 @@ func Schema(opts SchemaOpts) (*AnalyzedSchema, error) { } a := &AnalyzedSchema{ - schema: opts.Schema, - root: opts.Root, - basePath: opts.BasePath, + schema: opts.Schema, + root: opts.Root, + basePath: opts.BasePath, + pathLoaderWithOptions: opts.PathLoaderWithOptions, } a.initializeFlags() @@ -54,9 +68,10 @@ func Schema(opts SchemaOpts) (*AnalyzedSchema, error) { // AnalyzedSchema indicates what the schema represents. type AnalyzedSchema struct { - schema *spec.Schema - root any - basePath string + schema *spec.Schema + root any + basePath string + pathLoaderWithOptions func(string, ...loading.Option) (json.RawMessage, error) hasProps bool hasAllOf bool @@ -103,19 +118,32 @@ func (a *AnalyzedSchema) inherits(other *AnalyzedSchema) { a.IsEnum = other.IsEnum } +// subSchemaOpts builds SchemaOpts for a nested schema, propagating the root, base path and the +// injected document loader so that confinement applies throughout the recursive analysis. +func (a *AnalyzedSchema) subSchemaOpts(sch *spec.Schema) SchemaOpts { + return SchemaOpts{ + Schema: sch, + Root: a.root, + BasePath: a.basePath, + PathLoaderWithOptions: a.pathLoaderWithOptions, + } +} + +// expandOpts builds the spec expand options for this analysis, carrying the injected loader so +// remote/relative $ref are resolved through it (rather than the unsandboxed package default). +func (a *AnalyzedSchema) expandOpts() *spec.ExpandOptions { + return &spec.ExpandOptions{PathLoaderWithOptions: a.pathLoaderWithOptions} +} + func (a *AnalyzedSchema) inferFromRef() error { if a.hasRef { sch := new(spec.Schema) sch.Ref = a.schema.Ref - err := spec.ExpandSchema(sch, a.root, nil) + err := spec.ExpandSchemaWithOptions(sch, a.root, nil, a.expandOpts()) if err != nil { return err } - rsch, err := Schema(SchemaOpts{ - Schema: sch, - Root: a.root, - BasePath: a.basePath, - }) + rsch, err := Schema(a.subSchemaOpts(sch)) if err != nil { // NOTE(fredbi): currently the only cause for errors is // unresolved ref. Since spec.ExpandSchema() expands the @@ -159,11 +187,7 @@ func (a *AnalyzedSchema) inferMap() error { // maps if a.schema.AdditionalProperties.Schema != nil { - msch, err := Schema(SchemaOpts{ - Schema: a.schema.AdditionalProperties.Schema, - Root: a.root, - BasePath: a.basePath, - }) + msch, err := Schema(a.subSchemaOpts(a.schema.AdditionalProperties.Schema)) if err != nil { return err } @@ -186,11 +210,7 @@ func (a *AnalyzedSchema) inferArray() error { a.IsArray = a.isArrayType() && (a.schema.Items == nil || a.schema.Items.Schemas == nil) if a.IsArray && a.hasItems { if a.schema.Items.Schema != nil { - itsch, err := Schema(SchemaOpts{ - Schema: a.schema.Items.Schema, - Root: a.root, - BasePath: a.basePath, - }) + itsch, err := Schema(a.subSchemaOpts(a.schema.Items.Schema)) if err != nil { return err } diff --git a/vendor/github.com/go-openapi/jsonpointer/.cliff.toml b/vendor/github.com/go-openapi/jsonpointer/.cliff.toml deleted file mode 100644 index 702629f5dc3..00000000000 --- a/vendor/github.com/go-openapi/jsonpointer/.cliff.toml +++ /dev/null @@ -1,181 +0,0 @@ -# git-cliff ~ configuration file -# https://git-cliff.org/docs/configuration - -[changelog] -header = """ -""" - -footer = """ - ------ - -**[{{ remote.github.repo }}]({{ self::remote_url() }}) license terms** - -[![License][license-badge]][license-url] - -[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg -[license-url]: {{ self::remote_url() }}/?tab=Apache-2.0-1-ov-file#readme - -{%- macro remote_url() -%} - https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} -{%- endmacro -%} -""" - -body = """ -{%- if version %} -## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/tree/{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }} -{%- else %} -## [unreleased] -{%- endif %} -{%- if message %} - {%- raw %}\n{% endraw %} -{{ message }} - {%- raw %}\n{% endraw %} -{%- endif %} -{%- if version %} - {%- if previous.version %} - -**Full Changelog**: <{{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}> - {%- endif %} -{%- else %} - {%- raw %}\n{% endraw %} -{%- endif %} - -{%- if statistics %}{% if statistics.commit_count %} - {%- raw %}\n{% endraw %} -{{ statistics.commit_count }} commits in this release. - {%- raw %}\n{% endraw %} -{%- endif %}{% endif %} ------ - -{%- for group, commits in commits | group_by(attribute="group") %} - {%- raw %}\n{% endraw %} -### {{ group | upper_first }} - {%- raw %}\n{% endraw %} - {%- for commit in commits %} - {%- if commit.remote.pr_title %} - {%- set commit_message = commit.remote.pr_title %} - {%- else %} - {%- set commit_message = commit.message %} - {%- endif %} -* {{ commit_message | split(pat="\n") | first | trim }} - {%- if commit.remote.username %} -{%- raw %} {% endraw %}by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }}) - {%- endif %} - {%- if commit.remote.pr_number %} -{%- raw %} {% endraw %}in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) - {%- endif %} -{%- raw %} {% endraw %}[...]({{ self::remote_url() }}/commit/{{ commit.id }}) - {%- endfor %} -{%- endfor %} - -{%- if github %} -{%- raw %}\n{% endraw -%} - {%- set all_contributors = github.contributors | length %} - {%- if github.contributors | filter(attribute="username", value="dependabot[bot]") | length < all_contributors %} ------ - -### People who contributed to this release - {% endif %} - {%- for contributor in github.contributors | filter(attribute="username") | sort(attribute="username") %} - {%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %} -* [@{{ contributor.username }}](https://github.com/{{ contributor.username }}) - {%- endif %} - {%- endfor %} - - {% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} ------ - {%- raw %}\n{% endraw %} - -### New Contributors - {%- endif %} - - {%- for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} - {%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %} -* @{{ contributor.username }} made their first contribution - {%- if contributor.pr_number %} - in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ - {%- endif %} - {%- endif %} - {%- endfor %} -{%- endif %} - -{%- raw %}\n{% endraw %} - -{%- macro remote_url() -%} - https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} -{%- endmacro -%} -""" -# Remove leading and trailing whitespaces from the changelog's body. -trim = true -# Render body even when there are no releases to process. -render_always = true -# An array of regex based postprocessors to modify the changelog. -postprocessors = [ - # Replace the placeholder with a URL. - #{ pattern = '', replace = "https://github.com/orhun/git-cliff" }, -] -# output file path -# output = "test.md" - -[git] -# Parse commits according to the conventional commits specification. -# See https://www.conventionalcommits.org -conventional_commits = false -# Exclude commits that do not match the conventional commits specification. -filter_unconventional = false -# Require all commits to be conventional. -# Takes precedence over filter_unconventional. -require_conventional = false -# Split commits on newlines, treating each line as an individual commit. -split_commits = false -# An array of regex based parsers to modify commit messages prior to further processing. -commit_preprocessors = [ - # Replace issue numbers with link templates to be updated in `changelog.postprocessors`. - #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, - # Check spelling of the commit message using https://github.com/crate-ci/typos. - # If the spelling is incorrect, it will be fixed automatically. - #{ pattern = '.*', replace_command = 'typos --write-changes -' } -] -# Prevent commits that are breaking from being excluded by commit parsers. -protect_breaking_commits = false -# An array of regex based parsers for extracting data from the commit message. -# Assigns commits to groups. -# Optionally sets the commit's scope and can decide to exclude commits from further processing. -commit_parsers = [ - { message = "^[Cc]hore\\([Rr]elease\\): prepare for", skip = true }, - { message = "(^[Mm]erge)|([Mm]erge conflict)", skip = true }, - { field = "author.name", pattern = "dependabot*", group = "Updates" }, - { message = "([Ss]ecurity)|([Vv]uln)", group = "Security" }, - { body = "(.*[Ss]ecurity)|([Vv]uln)", group = "Security" }, - { message = "([Cc]hore\\(lint\\))|(style)|(lint)|(codeql)|(golangci)", group = "Code quality" }, - { message = "(^[Dd]oc)|((?i)readme)|(badge)|(typo)|(documentation)", group = "Documentation" }, - { message = "(^[Ff]eat)|(^[Ee]nhancement)", group = "Implemented enhancements" }, - { message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(license)|(example)", group = "Miscellaneous tasks" }, - { message = "^test", group = "Testing" }, - { message = "(^fix)|(panic)", group = "Fixed bugs" }, - { message = "(^refact)|(rework)", group = "Refactor" }, - { message = "(^[Pp]erf)|(performance)", group = "Performance" }, - { message = "(^[Cc]hore)", group = "Miscellaneous tasks" }, - { message = "^[Rr]evert", group = "Reverted changes" }, - { message = "(upgrade.*?go)|(go\\s+version)", group = "Updates" }, - { message = ".*", group = "Other" }, -] -# Exclude commits that are not matched by any commit parser. -filter_commits = false -# An array of link parsers for extracting external references, and turning them into URLs, using regex. -link_parsers = [] -# Include only the tags that belong to the current branch. -use_branch_tags = false -# Order releases topologically instead of chronologically. -topo_order = false -# Order releases topologically instead of chronologically. -topo_order_commits = true -# Order of commits in each group/release within the changelog. -# Allowed values: newest, oldest -sort_commits = "newest" -# Process submodules commits -recurse_submodules = false - -#[remote.github] -#owner = "go-openapi" diff --git a/vendor/github.com/go-openapi/jsonpointer/.gitignore b/vendor/github.com/go-openapi/jsonpointer/.gitignore index 885dc27ab0b..d8f4186fe59 100644 --- a/vendor/github.com/go-openapi/jsonpointer/.gitignore +++ b/vendor/github.com/go-openapi/jsonpointer/.gitignore @@ -3,4 +3,3 @@ .idea .env .mcp.json -.claude/ diff --git a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml index dc7c96053de..9d2733176ea 100644 --- a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml +++ b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml @@ -4,7 +4,10 @@ linters: disable: - depguard - funlen + - goconst - godox + - gomodguard + - gomodguard_v2 - exhaustruct - nlreturn - nonamedreturns diff --git a/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md b/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md index 2ebebedc150..de0bf5c04ba 100644 --- a/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/jsonpointer/CONTRIBUTORS.md @@ -4,14 +4,15 @@ | Total Contributors | Total Contributions | | --- | --- | -| 12 | 101 | +| 13 | 132 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | -| @fredbi | 54 | | +| @fredbi | 83 | | | @casualjim | 33 | | | @magodo | 3 | | | @youyuanwu | 3 | | +| @alexandear | 2 | | | @gaiaz-iusipov | 1 | | | @gbjk | 1 | | | @gordallott | 1 | | @@ -21,4 +22,4 @@ | @olivierlemasle | 1 | | | @testwill | 1 | | - _this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_ + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/jsonpointer/NOTICE b/vendor/github.com/go-openapi/jsonpointer/NOTICE index f3b51939a95..201908d2f08 100644 --- a/vendor/github.com/go-openapi/jsonpointer/NOTICE +++ b/vendor/github.com/go-openapi/jsonpointer/NOTICE @@ -18,7 +18,7 @@ It ships with copies of other software which license terms are recalled below. The original software was authored on 25-02-2013 by sigu-399 (https://github.com/sigu-399, sigu.399@gmail.com). -github.com/sigh-399/jsonpointer +github.com/sigu-399/jsonpointer =========================== // SPDX-FileCopyrightText: Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) diff --git a/vendor/github.com/go-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md index c52803e2e8f..6e7929c64b3 100644 --- a/vendor/github.com/go-openapi/jsonpointer/README.md +++ b/vendor/github.com/go-openapi/jsonpointer/README.md @@ -16,17 +16,34 @@ An implementation of JSON Pointer for golang, which supports go `struct`. ## Announcements -* **2025-12-19** : new community chat on discord - * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** - -You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] - -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] +* **2026-07-07** : landing v1.0.0 + * stable API pledge + +* **2026-06-29** : reinsourced external dependency to swag (v0.24.0) + * module `github.com/go-openapi/swag/jsonname` is source directly here, so we no longer have any external dependency + * `jsonname` was never really used by any other package, so it makes sense to deprecate it away from the `swag` family + and retrofit its functionality here. `jsonpointer` no longer get external dependencies, besides test dependencies. + +* **2026-04-15** : added support for trailing "-" for arrays (v0.23.0) + * this brings full support of [RFC6901][RFC6901] + * this is supported for types relying on the reflection-based implemented + * API semantics remain essentially unaltered. Exception: `Pointer.Set(document any,value any) (document any, err error)` + can only perform a best-effort to mutate the input document in place. In the case of adding elements to an array with a + trailing "-", either pass a mutable array (`*[]T`) as the input document, or use the returned updated document instead. + * types that implement the `JSONSetable` interface may not implement the mutation implied by the trailing "-" + +* **2026-04-15** : added support for optional alternate JSON name providers + * for struct support the defaults might not suit all situations: there are known limitations + when it comes to handle untagged fields or embedded types. + * the default name provider in use is not fully aligned with go JSON stdlib + * exposed an option (or global setting) to change the provider that resolves a struct into json keys + * the default behavior is not altered ## Status -API is stable. +API is stable and feature-complete. + +The project continues to receive regular updates, bug fixes and hygiene maintenance (CI, linting, etc). ## Import this library in your project @@ -88,7 +105,7 @@ See -also known as [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) +also known as [RFC6901][RFC6901]. ## Licensing @@ -99,19 +116,19 @@ on top of which it has been built. ## Limitations -The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, -the reference token MUST contain either...' is not implemented. - -That is because our implementation of the JSON pointer only supports explicit references to array elements: -the provision in the spec to resolve non-existent members as "the last element in the array", -using the special trailing character "-" is not implemented. +* [RFC6901][RFC6901] is now fully supported, including trailing "-" semantics for arrays (for `Set` operations). +* Default behavior: JSON name detection in go `struct`s + - Unlike go standard marshaling, untagged fields do not default to the go field name and are ignored. + - anonymous fields are not traversed if untagged + - the above limitations may be overcome by calling `UseGoNameProvider()` at initialization time. + - alternatively, users may inject the desired custom behavior for naming fields as an option. ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -142,11 +159,8 @@ Maintainers can cut a new release by either: [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer [godoc-url]: http://pkg.go.dev/github.com/go-openapi/jsonpointer -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue -[discord-url]: https://discord.gg/twZ9BwT3 +[discord-url]: https://discord.gg/FfnFYaC3k5 [license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg @@ -156,3 +170,8 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/jsonpointer/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/jsonpointer [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/jsonpointer/latest +[RFC6901]: https://www.rfc-editor.org/rfc/rfc6901 + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/jsonpointer/errors.go b/vendor/github.com/go-openapi/jsonpointer/errors.go index 8c50dde8bcf..2ae6e3cfb3e 100644 --- a/vendor/github.com/go-openapi/jsonpointer/errors.go +++ b/vendor/github.com/go-openapi/jsonpointer/errors.go @@ -16,12 +16,25 @@ const ( ErrPointer pointerError = "JSON pointer error" // ErrInvalidStart states that a JSON pointer must start with a separator ("/"). - ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator + ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator + `"` // ErrUnsupportedValueType indicates that a value of the wrong type is being set. ErrUnsupportedValueType pointerError = "only structs, pointers, maps and slices are supported for setting values" + + // ErrDashToken indicates use of the RFC 6901 "-" reference token in a context where it cannot be + // resolved. + // + // Per RFC 6901 §4 the "-" token refers to the (nonexistent) element after the last array element. + // It may only be used as the terminal token of a [Pointer.Set] against a slice, where it means + // "append". + // + // Any other use (get, offset, intermediate traversal, non-slice target) is an error condition that + // wraps this sentinel. + ErrDashToken pointerError = `the "-" array token cannot be resolved here` //nolint:gosec // G101 false positive: this is a JSON Pointer reference token, not a credential. ) +const dashToken = "-" + func errNoKey(key string) error { return fmt.Errorf("object has no key %q: %w", key, ErrPointer) } @@ -33,3 +46,15 @@ func errOutOfBounds(length, idx int) error { func errInvalidReference(token string) error { return fmt.Errorf("invalid token reference %q: %w", token, ErrPointer) } + +func errDashOnGet() error { + return fmt.Errorf("cannot resolve %q token on get: %w: %w", dashToken, ErrDashToken, ErrPointer) +} + +func errDashIntermediate() error { + return fmt.Errorf("the %q token may only appear as the terminal token of a pointer: %w: %w", dashToken, ErrDashToken, ErrPointer) +} + +func errDashOnOffset() error { + return fmt.Errorf("cannot compute offset for %q token (nonexistent element): %w: %w", dashToken, ErrDashToken, ErrPointer) +} diff --git a/vendor/github.com/go-openapi/jsonpointer/ifaces.go b/vendor/github.com/go-openapi/jsonpointer/ifaces.go new file mode 100644 index 00000000000..31359c48fad --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/ifaces.go @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonpointer + +import "reflect" + +// JSONPointable is an interface for structs to implement, when they need to customize the json +// pointer process or want to avoid the use of reflection. +type JSONPointable interface { + // JSONLookup returns a value pointed at this (unescaped) key. + JSONLookup(key string) (any, error) +} + +// JSONSetable is an interface for structs to implement, when they need to customize the json +// pointer process or want to avoid the use of reflection. +// +// # Handling of the RFC 6901 "-" token +// +// When a type implementing JSONSetable is the terminal parent of a [Pointer.Set] call, the library +// passes the raw reference token to JSONSet without interpretation. +// +// In particular, the RFC 6901 "-" token (which conventionally means "append" for arrays, per RFC +// 6902) is forwarded verbatim as the key argument. +// +// Implementations that model an array-like container are expected to give "-" the append semantics; +// implementations that do not should return an error wrapping [ErrDashToken] (or [ErrPointer]) for +// clarity. +// +// Implementations are responsible for any in-place mutation: the library does not attempt to rebind +// the result of JSONSet into a parent container. +type JSONSetable interface { + // JSONSet sets the value pointed at the (unescaped) key. + // + // The key may be the RFC 6901 "-" token when the pointer targets a slice-like member; see the + // interface documentation for details. + JSONSet(key string, value any) error +} + +// NameProvider knows how to resolve go struct fields into json names. +// +// The default provider is brought by +// [github.com/go-openapi/jsonpointer/jsonname.DefaultJSONNameProvider]. +type NameProvider interface { + // GetGoName gets the go name for a json property name + GetGoName(subject any, name string) (string, bool) + + // GetGoNameForType gets the go name for a given type for a json property name + GetGoNameForType(tpe reflect.Type, name string) (string, bool) +} diff --git a/vendor/github.com/go-openapi/swag/jsonname/doc.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/doc.go similarity index 100% rename from vendor/github.com/go-openapi/swag/jsonname/doc.go rename to vendor/github.com/go-openapi/jsonpointer/jsonname/doc.go diff --git a/vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go similarity index 88% rename from vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go rename to vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go index adc4426873c..5eec18fbfd0 100644 --- a/vendor/github.com/go-openapi/swag/jsonname/go_name_provider.go +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/go_name_provider.go @@ -11,11 +11,11 @@ import ( var _ providerIface = (*GoNameProvider)(nil) -// GoNameProvider resolves json property names to go struct field names following -// the same rules as the standard library's [encoding/json] package. +// GoNameProvider resolves json property names to go struct field names following the same rules as +// the standard library's [encoding/json] package. // -// Contrary to [NameProvider], it considers exported fields without a json tag, -// and promotes fields from anonymous embedded struct types. +// Contrary to [NameProvider], it considers exported fields without a json tag, and promotes fields +// from anonymous embedded struct types. // // Rules (aligned with encoding/json): // @@ -104,9 +104,9 @@ func (n *GoNameProvider) nameIndexFor(tpe reflect.Type) nameIndex { return names } -// fieldEntry captures a candidate field discovered while walking a struct -// along with the indirection path from the root type (used to resolve conflicts -// by depth in the same way encoding/json does). +// fieldEntry captures a candidate field discovered while walking a struct along with the +// indirection path from the root type (used to resolve conflicts by depth in the same way +// encoding/json does). type fieldEntry struct { goName string jsonName string @@ -129,6 +129,8 @@ func buildGoNameIndex(tpe reflect.Type) nameIndex { // collectGoFields walks tpe breadth-first along anonymous struct fields, // reproducing the field selection performed by encoding/json.typeFields. +// +//nolint:gocognit // everything is inlined to help the compiler determine what escapes and what doesn't func collectGoFields(tpe reflect.Type) []fieldEntry { if tpe.Kind() != reflect.Struct { return nil @@ -157,12 +159,12 @@ func collectGoFields(tpe reflect.Type) []fieldEntry { } for _, q := range current { - for i := 0; i < q.typ.NumField(); i++ { + for i := range q.typ.NumField() { sf := q.typ.Field(i) if sf.Anonymous { ft := sf.Type - if ft.Kind() == reflect.Ptr { + if ft.Kind() == reflect.Pointer { ft = ft.Elem() } if !sf.IsExported() && ft.Kind() != reflect.Struct { @@ -180,7 +182,7 @@ func collectGoFields(tpe reflect.Type) []fieldEntry { tagged := jsonName != "" ft := sf.Type - if ft.Kind() == reflect.Ptr { + if ft.Kind() == reflect.Pointer { ft = ft.Elem() } @@ -221,9 +223,9 @@ func collectGoFields(tpe reflect.Type) []fieldEntry { return dominantFields(candidates) } -// dominantFields applies the Go encoding/json conflict resolution rules: -// at each JSON name, the shallowest field wins; at equal depth, a uniquely -// tagged candidate wins; otherwise all candidates for that name are dropped. +// dominantFields applies the Go encoding/json conflict resolution rules: at each JSON name, the +// shallowest field wins; at equal depth, a uniquely tagged candidate wins; otherwise all candidates +// for that name are dropped. func dominantFields(candidates []fieldEntry) []fieldEntry { byName := make(map[string][]fieldEntry, len(candidates)) for _, c := range candidates { @@ -272,14 +274,14 @@ func dominantFields(candidates []fieldEntry) []fieldEntry { return out } -// parseJSONTag returns the name component of a json struct tag and whether -// it carried any non-name option (kept for future-proofing, e.g. "omitempty"). +// parseJSONTag returns the name component of a json struct tag and whether it carried any non-name +// option (kept for future-proofing, e.g. "omitempty"). func parseJSONTag(tag string) (string, string) { if tag == "" { return "", "" } - if idx := strings.IndexByte(tag, ','); idx >= 0 { - return tag[:idx], tag[idx+1:] + if before, after, ok := strings.Cut(tag, ","); ok { + return before, after } return tag, "" diff --git a/vendor/github.com/go-openapi/swag/jsonname/ifaces.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go similarity index 77% rename from vendor/github.com/go-openapi/swag/jsonname/ifaces.go rename to vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go index 812ace5639f..64871f0d276 100644 --- a/vendor/github.com/go-openapi/swag/jsonname/ifaces.go +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/ifaces.go @@ -5,9 +5,11 @@ package jsonname import "reflect" -// providerIface is an unexported compile-time contract that every name provider -// in this package is expected to satisfy. -// It mirrors the interface declared by the main consumer of this module: [github.com/go-openapi/jsonpointer.NameProvider]. +// providerIface is an unexported compile-time contract that every name provider in this package is +// expected to satisfy. +// +// It mirrors the interface declared by the main consumer of this module: +// [github.com/go-openapi/jsonpointer.NameProvider]. type providerIface interface { GetGoName(subject any, name string) (string, bool) GetGoNameForType(tpe reflect.Type, name string) (string, bool) diff --git a/vendor/github.com/go-openapi/swag/jsonname/name_provider.go b/vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go similarity index 83% rename from vendor/github.com/go-openapi/swag/jsonname/name_provider.go rename to vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go index 9f5da7a0165..1bec2406b52 100644 --- a/vendor/github.com/go-openapi/swag/jsonname/name_provider.go +++ b/vendor/github.com/go-openapi/jsonpointer/jsonname/name_provider.go @@ -10,12 +10,12 @@ import ( ) // DefaultJSONNameProvider is the default cache for types. -var DefaultJSONNameProvider = NewNameProvider() +var DefaultJSONNameProvider = NewNameProvider() //nolint:gochecknoglobals // default settings, for backward compatible package-level settings var _ providerIface = (*NameProvider)(nil) -// NameProvider represents an object capable of translating from go property names -// to json property names. +// NameProvider represents an object capable of translating from go property names to json property +// names. // // This type is thread-safe. // @@ -30,7 +30,7 @@ type nameIndex struct { goNames map[string]string } -// NewNameProvider creates a new name provider +// NewNameProvider creates a new name provider. func NewNameProvider() *NameProvider { return &NameProvider{ lock: &sync.Mutex{}, @@ -39,7 +39,7 @@ func NewNameProvider() *NameProvider { } func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) { - for i := 0; i < tpe.NumField(); i++ { + for i := range tpe.NumField() { targetDes := tpe.Field(i) if targetDes.PkgPath != "" { // unexported @@ -73,14 +73,14 @@ func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) { } func newNameIndex(tpe reflect.Type) nameIndex { - var idx = make(map[string]string, tpe.NumField()) - var reverseIdx = make(map[string]string, tpe.NumField()) + idx := make(map[string]string, tpe.NumField()) + reverseIdx := make(map[string]string, tpe.NumField()) buildnameIndex(tpe, idx, reverseIdx) return nameIndex{jsonNames: idx, goNames: reverseIdx} } -// GetJSONNames gets all the json property names for a type +// GetJSONNames gets all the json property names for a type. func (n *NameProvider) GetJSONNames(subject any) []string { n.lock.Lock() defer n.lock.Unlock() @@ -97,13 +97,13 @@ func (n *NameProvider) GetJSONNames(subject any) []string { return res } -// GetJSONName gets the json name for a go property name +// GetJSONName gets the json name for a go property name. func (n *NameProvider) GetJSONName(subject any, name string) (string, bool) { tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() return n.GetJSONNameForType(tpe, name) } -// GetJSONNameForType gets the json name for a go property name on a given type +// GetJSONNameForType gets the json name for a go property name on a given type. func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { n.lock.Lock() defer n.lock.Unlock() @@ -115,13 +115,13 @@ func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string return nme, ok } -// GetGoName gets the go name for a json property name +// GetGoName gets the go name for a json property name. func (n *NameProvider) GetGoName(subject any, name string) (string, bool) { tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() return n.GetGoNameForType(tpe, name) } -// GetGoNameForType gets the go name for a given type for a json property name +// GetGoNameForType gets the go name for a given type for a json property name. func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { n.lock.Lock() defer n.lock.Unlock() diff --git a/vendor/github.com/go-openapi/jsonpointer/options.go b/vendor/github.com/go-openapi/jsonpointer/options.go new file mode 100644 index 00000000000..223c1e5ff0e --- /dev/null +++ b/vendor/github.com/go-openapi/jsonpointer/options.go @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package jsonpointer + +import ( + "sync" + + "github.com/go-openapi/jsonpointer/jsonname" +) + +// Option to tune the behavior of a JSON [Pointer]. +type Option func(*options) + +var ( + //nolint:gochecknoglobals // package level defaults are provided as a convenient, backward-compatible way to adopt options. + defaultOptions = options{ + provider: jsonname.DefaultJSONNameProvider, + } + //nolint:gochecknoglobals // guards defaultOptions against concurrent SetDefaultNameProvider / read races (testing) + defaultOptionsMu sync.RWMutex +) + +// SetDefaultNameProvider sets the [NameProvider] as a package-level default. +// +// By default, the default provider is [jsonname.DefaultJSONNameProvider]. +// +// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], [GetForToken] and +// [SetForToken]. +// The typical usage is to call it once at initialization time. +// +// A nil provider is ignored. +func SetDefaultNameProvider(provider NameProvider) { + if provider == nil { + return + } + + defaultOptionsMu.Lock() + defer defaultOptionsMu.Unlock() + + defaultOptions.provider = provider +} + +// UseGoNameProvider sets the [NameProvider] as a package-level default to the alternative provider +// [jsonname.GoNameProvider], that covers a few areas not supported by the default name provider. +// +// This implementation supports untagged exported fields and embedded types in go struct. +// It follows strictly the behavior of the JSON standard library regarding field naming conventions. +// +// It is safe to call concurrently with [Pointer.Get], [Pointer.Set], [GetForToken] and +// [SetForToken]. +// The typical usage is to call it once at initialization time. +func UseGoNameProvider() { + SetDefaultNameProvider(jsonname.NewGoNameProvider()) +} + +// DefaultNameProvider returns the current package-level [NameProvider]. +func DefaultNameProvider() NameProvider { //nolint:ireturn // returning the interface is the point — callers pick their own implementation. + defaultOptionsMu.RLock() + defer defaultOptionsMu.RUnlock() + + return defaultOptions.provider +} + +// WithNameProvider injects a custom [NameProvider] to resolve json names from go struct types. +func WithNameProvider(provider NameProvider) Option { + return func(o *options) { + o.provider = provider + } +} + +type options struct { + provider NameProvider +} + +func optionsWithDefaults(opts []Option) options { + var o options + o.provider = DefaultNameProvider() + + for _, apply := range opts { + apply(&o) + } + + return o +} diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go index 7df49af3b96..05fc863ee60 100644 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go @@ -11,8 +11,6 @@ import ( "reflect" "strconv" "strings" - - "github.com/go-openapi/swag/jsonname" ) const ( @@ -20,20 +18,6 @@ const ( pointerSeparator = `/` ) -// JSONPointable is an interface for structs to implement, -// when they need to customize the json pointer process or want to avoid the use of reflection. -type JSONPointable interface { - // JSONLookup returns a value pointed at this (unescaped) key. - JSONLookup(key string) (any, error) -} - -// JSONSetable is an interface for structs to implement, -// when they need to customize the json pointer process or want to avoid the use of reflection. -type JSONSetable interface { - // JSONSet sets the value pointed at the (unescaped) key. - JSONSet(key string, value any) error -} - // Pointer is a representation of a json pointer. // // Use [Pointer.Get] to retrieve a value or [Pointer.Set] to set a value. @@ -41,7 +25,7 @@ type JSONSetable interface { // It works with any go type interpreted as a JSON document, which means: // // - if a type implements [JSONPointable], its [JSONPointable.JSONLookup] method is used to resolve [Pointer.Get] -// - if a type implements [JSONSetable], its [JSONPointable.JSONSet] method is used to resolve [Pointer.Set] +// - if a type implements [JSONSetable], its [JSONSetable.JSONSet] method is used to resolve [Pointer.Set] // - a go map[K]V is interpreted as an object, with type K assignable to a string // - a go slice []T is interpreted as an array // - a go struct is interpreted as an object, with exported fields interpreted as keys @@ -50,7 +34,8 @@ type JSONSetable interface { // // For struct s resolved by reflection, key mappings honor the conventional struct tag `json`. // -// Fields that do not specify a `json` tag, or specify an empty one, or are tagged as `json:"-"` are ignored. +// Fields that do not specify a `json` tag, or specify an empty one, or are tagged as `json:"-"` are +// ignored. // // # Limitations // @@ -71,16 +56,36 @@ func New(jsonPointerString string) (Pointer, error) { // Get uses the pointer to retrieve a value from a JSON document. // // It returns the value with its type as a [reflect.Kind] or an error. -func (p *Pointer) Get(document any) (any, reflect.Kind, error) { - return p.get(document, jsonname.DefaultJSONNameProvider) +func (p *Pointer) Get(document any, opts ...Option) (any, reflect.Kind, error) { + o := optionsWithDefaults(opts) + + return p.get(document, o.provider) } -// Set uses the pointer to set a value from a data type -// that represent a JSON document. +// Set uses the pointer to set a value from a data type that represent a JSON document. +// +// # Mutation contract // -// It returns the updated document. -func (p *Pointer) Set(document any, value any) (any, error) { - return document, p.set(document, value, jsonname.DefaultJSONNameProvider) +// Set mutates the provided document in place whenever Go's type system allows it: when document is +// a map, a pointer, or when the targeted value is reached through an addressable ancestor (e.g. a +// struct field traversed via a pointer, a slice element). +// +// Callers that rely on this in-place behavior may continue to ignore the returned document. +// +// The returned document is only load-bearing when Set cannot mutate in place. +// +// This happens in one specific case: appending to a top-level slice passed by value (e.g. document +// of type []T rather than *[]T) via the RFC 6901 "-" terminal token. reflect.Append produces a new +// slice header that the library cannot rebind into the caller's variable; the updated document is +// returned instead. +// +// Pass *[]T if you want in-place rebind for that case as well. +// +// See [ErrDashToken] for the semantics of the "-" token. +func (p *Pointer) Set(document any, value any, opts ...Option) (any, error) { + o := optionsWithDefaults(opts) + + return p.set(document, value, o.provider) } // DecodedTokens returns the decoded (unescaped) tokens of this JSON pointer. @@ -109,6 +114,46 @@ func (p *Pointer) String() string { return pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator) } +// Offset returns the byte offset, in the raw JSON text of document, of the location referenced by +// this pointer's terminal token. +// +// Unlike [Pointer.Get] and [Pointer.Set], which operate on a decoded Go value, Offset operates +// directly on the textual JSON source. +// +// It drives an [encoding/json.Decoder] over the string and stops at the terminal token, returning +// the position at which the decoder was about to read that token. +// +// It is primarily intended for tooling that needs to map a pointer back to a region of the original +// source: reporting line/column for validation or parse diagnostics, extracting a sub-document by +// slicing the raw bytes, or highlighting the referenced span in an editor. +// +// # Offset semantics +// +// The meaning of the returned offset depends on whether the terminal token addresses an object +// property or an array element: +// +// - Object property: the offset points to the first byte of the key (its +// opening quote character), not to the associated value. For example, +// pointer "/foo/bar" against {"foo": {"bar": 21}} returns 9, the index of +// the opening quote of "bar". +// - Array element: the offset points to the first byte of the value at that +// index. For example, pointer "/0/1" against [[1,2], [3,4]] returns 4, +// the index of the digit 2. +// +// # Errors +// +// Offset returns an error in any of these cases: +// +// - document is not syntactically valid JSON; +// - the structure of document does not match the pointer (e.g. traversing +// into a scalar, or a token that is neither a valid key nor a valid +// numeric index); +// - a referenced key or index does not exist in document; +// - the pointer's terminal token is the RFC 6901 "-" array token, which +// designates a nonexistent element and therefore has no offset in the +// source. The returned error wraps [ErrDashToken]. +// +// All errors wrap [ErrPointer]. func (p *Pointer) Offset(document string) (int64, error) { dec := json.NewDecoder(strings.NewReader(document)) var offset int64 @@ -137,7 +182,34 @@ func (p *Pointer) Offset(document string) (int64, error) { return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) } } - return offset, nil + return skipJSONSeparator(document, offset), nil +} + +// skipJSONSeparator advances offset past trailing JSON whitespace and at most one value separator +// (comma) in document, so the result points at the first byte of the next JSON token. +// +// The streaming decoder's InputOffset sits right after the most recently consumed token, which +// between values is the comma (or whitespace) — not the following token. +// +// Normalizing here keeps Offset's contract uniform: for both object keys and array elements, and +// regardless of position within the parent container, the returned offset always points at the +// first byte of the addressed token. +func skipJSONSeparator(document string, offset int64) int64 { + n := int64(len(document)) + for offset < n && isJSONWhitespace(document[offset]) { + offset++ + } + if offset < n && document[offset] == ',' { + offset++ + } + for offset < n && isJSONWhitespace(document[offset]) { + offset++ + } + return offset +} + +func isJSONWhitespace(c byte) bool { + return c == ' ' || c == '\t' || c == '\n' || c == '\r' } // "Constructor", parses the given string JSON pointer. @@ -157,9 +229,9 @@ func (p *Pointer) parse(jsonPointerString string) error { return nil } -func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) { +func (p *Pointer) get(node any, nameProvider NameProvider) (any, reflect.Kind, error) { if nameProvider == nil { - nameProvider = jsonname.DefaultJSONNameProvider + nameProvider = defaultOptions.provider } kind := reflect.Invalid @@ -185,50 +257,128 @@ func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, refle return node, kind, nil } -func (p *Pointer) set(node, data any, nameProvider *jsonname.NameProvider) error { +func (p *Pointer) set(node, data any, nameProvider NameProvider) (any, error) { knd := reflect.ValueOf(node).Kind() if knd != reflect.Pointer && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { - return errors.Join( + return node, errors.Join( fmt.Errorf("unexpected type: %T", node), //nolint:err113 // err wrapping is carried out by errors.Join, not fmt.Errorf. ErrUnsupportedValueType, ErrPointer, ) } - l := len(p.referenceTokens) - // full document when empty - if l == 0 { - return nil + if len(p.referenceTokens) == 0 { + return node, nil } if nameProvider == nil { - nameProvider = jsonname.DefaultJSONNameProvider + nameProvider = defaultOptions.provider } - var decodedToken string - lastIndex := l - 1 + return p.setAt(node, p.referenceTokens, data, nameProvider) +} - if lastIndex > 0 { // skip if we only have one token in pointer - for _, token := range p.referenceTokens[:lastIndex] { - decodedToken = Unescape(token) - next, err := p.resolveNodeForToken(node, decodedToken, nameProvider) - if err != nil { - return err - } +// setAt recursively walks the token list, setting the data at the terminal token and rebinding any +// new child reference (e.g. a slice header returned by an "-" append) into its parent on the way +// back up. +// +// Returning the (possibly new) node at each level is what makes append work at any depth without +// requiring the caller to pass a pointer to the containing slice: the new slice header propagates +// up and each parent rebinds it via the appropriate kind-specific setter. +func (p *Pointer) setAt(node any, tokens []string, data any, nameProvider NameProvider) (any, error) { + decodedToken := Unescape(tokens[0]) + + if len(tokens) == 1 { + return setSingleImpl(node, data, decodedToken, nameProvider) + } - node = next - } + child, err := p.resolveNodeForToken(node, decodedToken, nameProvider) + if err != nil { + return node, err } - // last token - decodedToken = Unescape(p.referenceTokens[lastIndex]) + newChild, err := p.setAt(child, tokens[1:], data, nameProvider) + if err != nil { + return node, err + } - return setSingleImpl(node, data, decodedToken, nameProvider) + return rebindChild(node, decodedToken, newChild, nameProvider) } -func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvider *jsonname.NameProvider) (next any, err error) { +// rebindChild writes newChild back into node at decodedToken. +// +// For cases where the child was already mutated in place (pointer aliasing, addressable slice +// elements) the rebind is a safe no-op. +// +// For cases where the child was returned by value (map entries holding a slice, slices reached +// through a non-addressable ancestor), the rebind propagates the new value into the parent. +// +// Parents implementing [JSONPointable] are left alone: they took ownership of the child via +// JSONLookup and did not opt into a JSONSet-based rebind on intermediate tokens. +func rebindChild(node any, decodedToken string, newChild any, nameProvider NameProvider) (any, error) { + if _, ok := node.(JSONPointable); ok { + return node, nil + } + + rValue := reflect.Indirect(reflect.ValueOf(node)) + + switch rValue.Kind() { + case reflect.Struct: + nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) + if !ok { + return node, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + } + fld := rValue.FieldByName(nm) + if !fld.CanSet() { + return node, nil + } + assignReflectValue(fld, newChild) + return node, nil + + case reflect.Map: + rValue.SetMapIndex(reflect.ValueOf(decodedToken), reflect.ValueOf(newChild)) + return node, nil + + case reflect.Slice: + if decodedToken == dashToken { + return node, errDashIntermediate() + } + idx, err := strconv.Atoi(decodedToken) + if err != nil { + return node, errors.Join(err, ErrPointer) + } + elem := rValue.Index(idx) + if !elem.CanSet() { + return node, nil + } + assignReflectValue(elem, newChild) + return node, nil + + default: + return node, errInvalidReference(decodedToken) + } +} + +// assignReflectValue assigns src into dst, unwrapping a pointer when dst expects the pointee type. +// +// This tolerates the pointer-wrapping performed by [typeFromValue] for addressable fields. +func assignReflectValue(dst reflect.Value, src any) { + nv := reflect.ValueOf(src) + if !nv.IsValid() { + return + } + if nv.Type().AssignableTo(dst.Type()) { + dst.Set(nv) + return + } + if nv.Kind() == reflect.Pointer && nv.Elem().Type().AssignableTo(dst.Type()) { + dst.Set(nv.Elem()) + } +} + +func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvider NameProvider) (next any, err error) { // check for nil during traversal if isNil(node) { return nil, fmt.Errorf("cannot traverse through nil value at %q: %w", decodedToken, ErrPointer) @@ -272,6 +422,9 @@ func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvide return typeFromValue(mv), nil case reflect.Slice: + if decodedToken == dashToken { + return nil, errDashIntermediate() + } tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { return nil, errors.Join(err, ErrPointer) @@ -312,16 +465,23 @@ func typeFromValue(v reflect.Value) any { } // GetForToken gets a value for a json pointer token 1 level deep. -func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) { - return getSingleImpl(document, decodedToken, jsonname.DefaultJSONNameProvider) +func GetForToken(document any, decodedToken string, opts ...Option) (any, reflect.Kind, error) { + o := optionsWithDefaults(opts) + + return getSingleImpl(document, decodedToken, o.provider) } // SetForToken sets a value for a json pointer token 1 level deep. -func SetForToken(document any, decodedToken string, value any) (any, error) { - return document, setSingleImpl(document, value, decodedToken, jsonname.DefaultJSONNameProvider) +// +// See [Pointer.Set] for the mutation contract, in particular the handling of the RFC 6901 "-" token +// on slices. +func SetForToken(document any, decodedToken string, value any, opts ...Option) (any, error) { + o := optionsWithDefaults(opts) + + return setSingleImpl(document, value, decodedToken, o.provider) } -func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) { +func getSingleImpl(node any, decodedToken string, nameProvider NameProvider) (any, reflect.Kind, error) { rValue := reflect.Indirect(reflect.ValueOf(node)) kind := rValue.Kind() if isNil(node) { @@ -361,6 +521,9 @@ func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NamePro return nil, kind, errNoKey(decodedToken) case reflect.Slice: + if decodedToken == dashToken { + return nil, kind, errDashOnGet() + } tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { return nil, kind, errors.Join(err, ErrPointer) @@ -378,14 +541,14 @@ func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NamePro } } -func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.NameProvider) error { +func setSingleImpl(node, data any, decodedToken string, nameProvider NameProvider) (any, error) { // check for nil to prevent panic when calling rValue.Type() if isNil(node) { - return fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer) + return node, fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer) } if ns, ok := node.(JSONSetable); ok { - return ns.JSONSet(decodedToken, data) + return node, ns.JSONSet(decodedToken, data) } rValue := reflect.Indirect(reflect.ValueOf(node)) @@ -394,12 +557,12 @@ func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.N case reflect.Struct: nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) if !ok { - return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) + return node, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer) } fld := rValue.FieldByName(nm) if !fld.CanSet() { - return fmt.Errorf("can't set struct field %s to %v: %w", nm, data, ErrPointer) + return node, fmt.Errorf("can't set struct field %s to %v: %w", nm, data, ErrPointer) } value := reflect.ValueOf(data) @@ -407,33 +570,51 @@ func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.N assignedType := fld.Type() if !valueType.AssignableTo(assignedType) { - return fmt.Errorf("can't set value with type %T to field %s with type %v: %w", data, nm, assignedType, ErrPointer) + return node, fmt.Errorf("can't set value with type %T to field %s with type %v: %w", data, nm, assignedType, ErrPointer) } fld.Set(value) - return nil + return node, nil case reflect.Map: kv := reflect.ValueOf(decodedToken) rValue.SetMapIndex(kv, reflect.ValueOf(data)) - return nil + return node, nil case reflect.Slice: + if decodedToken == dashToken { + // RFC 6901 §4 / RFC 6902 append semantics: terminal "-" appends the value to the slice. + // + // We rebind in place when the slice is reachable via an addressable ancestor; otherwise we + // return the new slice header for the parent (or the public Set) to rebind. + value := reflect.ValueOf(data) + elemType := rValue.Type().Elem() + if !value.Type().AssignableTo(elemType) { + return node, fmt.Errorf("can't append value of type %T to slice of %v: %w", data, elemType, ErrPointer) + } + newSlice := reflect.Append(rValue, value) + if rValue.CanSet() { + rValue.Set(newSlice) + return node, nil + } + return newSlice.Interface(), nil + } + tokenIndex, err := strconv.Atoi(decodedToken) if err != nil { - return errors.Join(err, ErrPointer) + return node, errors.Join(err, ErrPointer) } sLength := rValue.Len() if tokenIndex < 0 || tokenIndex >= sLength { - return errOutOfBounds(sLength, tokenIndex) + return node, errOutOfBounds(sLength, tokenIndex) } elem := rValue.Index(tokenIndex) if !elem.CanSet() { - return fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer) + return node, fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer) } value := reflect.ValueOf(data) @@ -441,15 +622,15 @@ func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.N assignedType := elem.Type() if !valueType.AssignableTo(assignedType) { - return fmt.Errorf("can't set value with type %T to slice element %d with type %v: %w", data, tokenIndex, assignedType, ErrPointer) + return node, fmt.Errorf("can't set value with type %T to slice element %d with type %v: %w", data, tokenIndex, assignedType, ErrPointer) } elem.Set(value) - return nil + return node, nil default: - return errInvalidReference(decodedToken) + return node, errInvalidReference(decodedToken) } } @@ -460,24 +641,27 @@ func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { if err != nil { return 0, err } - switch tk := tk.(type) { - case json.Delim: - switch tk { - case '{': - if err = drainSingle(dec); err != nil { - return 0, err - } - case '[': + key, ok := tk.(string) + if !ok { + return 0, fmt.Errorf("invalid key token %#v: %w", tk, ErrPointer) + } + if key == decodedToken { + return offset, nil + } + + // Consume the associated value. + // Scalars are fully read by a single Token() call; composite values must be drained. + tk, err = dec.Token() + if err != nil { + return 0, err + } + if delim, isDelim := tk.(json.Delim); isDelim { + switch delim { + case '{', '[': if err = drainSingle(dec); err != nil { return 0, err } } - case string: - if tk == decodedToken { - return offset, nil - } - default: - return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer) } } @@ -485,6 +669,9 @@ func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) { } func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) { + if decodedToken == dashToken { + return 0, errDashOnOffset() + } idx, err := strconv.Atoi(decodedToken) if err != nil { return 0, fmt.Errorf("token reference %q is not a number: %w: %w", decodedToken, err, ErrPointer) @@ -548,10 +735,7 @@ func drainSingle(dec *json.Decoder) error { return nil } -// JSON pointer encoding: -// ~0 => ~ -// ~1 => / -// ... and vice versa +// JSON pointer encoding: ~0 => ~ ~1 => / ... and vice versa. const ( encRefTok0 = `~0` diff --git a/vendor/github.com/go-openapi/jsonreference/.gitignore b/vendor/github.com/go-openapi/jsonreference/.gitignore index 885dc27ab0b..d8f4186fe59 100644 --- a/vendor/github.com/go-openapi/jsonreference/.gitignore +++ b/vendor/github.com/go-openapi/jsonreference/.gitignore @@ -3,4 +3,3 @@ .idea .env .mcp.json -.claude/ diff --git a/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md b/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md index 7faeb83a77d..d20737c946d 100644 --- a/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/jsonreference/CONTRIBUTORS.md @@ -4,18 +4,18 @@ | Total Contributors | Total Contributions | | --- | --- | -| 9 | 73 | +| 9 | 83 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | -| @fredbi | 36 | https://github.com/go-openapi/jsonreference/commits?author=fredbi | -| @casualjim | 25 | https://github.com/go-openapi/jsonreference/commits?author=casualjim | -| @youyuanwu | 5 | https://github.com/go-openapi/jsonreference/commits?author=youyuanwu | -| @olivierlemasle | 2 | https://github.com/go-openapi/jsonreference/commits?author=olivierlemasle | -| @apelisse | 1 | https://github.com/go-openapi/jsonreference/commits?author=apelisse | -| @gbjk | 1 | https://github.com/go-openapi/jsonreference/commits?author=gbjk | -| @honza | 1 | https://github.com/go-openapi/jsonreference/commits?author=honza | -| @Neo2308 | 1 | https://github.com/go-openapi/jsonreference/commits?author=Neo2308 | -| @erraggy | 1 | https://github.com/go-openapi/jsonreference/commits?author=erraggy | +| @fredbi | 46 | | +| @casualjim | 25 | | +| @youyuanwu | 5 | | +| @olivierlemasle | 2 | | +| @apelisse | 1 | | +| @gbjk | 1 | | +| @honza | 1 | | +| @Neo2308 | 1 | | +| @erraggy | 1 | | - _this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_ + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/jsonreference/README.md b/vendor/github.com/go-openapi/jsonreference/README.md index adea1606197..fbd16cf8924 100644 --- a/vendor/github.com/go-openapi/jsonreference/README.md +++ b/vendor/github.com/go-openapi/jsonreference/README.md @@ -16,13 +16,8 @@ An implementation of JSON Reference for golang. ## Announcements -* **2025-12-19** : new community chat on discord - * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** - -You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] - -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] +* **2026-07-07** : landing v1.0.0 + * stable API pledge ## Status @@ -74,9 +69,9 @@ on top of which it has been built. ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -111,11 +106,8 @@ Maintainers can cut a new release by either: [doc-url]: https://goswagger.io/go-openapi [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/jsonreference [godoc-url]: http://pkg.go.dev/github.com/go-openapi/jsonreference -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue -[discord-url]: https://discord.gg/twZ9BwT3 +[discord-url]: https://discord.gg/FfnFYaC3k5 [license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg @@ -125,3 +117,7 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/jsonreference/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/jsonreference [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/jsonreference/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/loads/.gitignore b/vendor/github.com/go-openapi/loads/.gitignore index d8f4186fe59..fbb78de2c34 100644 --- a/vendor/github.com/go-openapi/loads/.gitignore +++ b/vendor/github.com/go-openapi/loads/.gitignore @@ -3,3 +3,4 @@ .idea .env .mcp.json +.worktrees diff --git a/vendor/github.com/go-openapi/loads/.golangci.yml b/vendor/github.com/go-openapi/loads/.golangci.yml index 83968f3faeb..272b14e545d 100644 --- a/vendor/github.com/go-openapi/loads/.golangci.yml +++ b/vendor/github.com/go-openapi/loads/.golangci.yml @@ -7,6 +7,8 @@ linters: - gochecknoglobals # on this repo, it is hard to refactor without globals/inits and no breaking change - gochecknoinits - godox + - gomodguard + - gomodguard_v2 - exhaustruct - nlreturn - nonamedreturns diff --git a/vendor/github.com/go-openapi/loads/CONTRIBUTORS.md b/vendor/github.com/go-openapi/loads/CONTRIBUTORS.md index 36b836a3d5a..ff3fd35081f 100644 --- a/vendor/github.com/go-openapi/loads/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/loads/CONTRIBUTORS.md @@ -4,12 +4,12 @@ | Total Contributors | Total Contributions | | --- | --- | -| 14 | 123 | +| 14 | 136 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | +| @fredbi | 58 | | | @casualjim | 48 | | -| @fredbi | 45 | | | @youyuanwu | 6 | | | @vburenin | 4 | | | @keramix | 4 | | @@ -23,4 +23,4 @@ | @kreativka | 1 | | | @petrkotas | 1 | | - _this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_ + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/loads/README.md b/vendor/github.com/go-openapi/loads/README.md index d92e62a040d..293f79bb6a0 100644 --- a/vendor/github.com/go-openapi/loads/README.md +++ b/vendor/github.com/go-openapi/loads/README.md @@ -20,12 +20,9 @@ Supports JSON and YAML documents. * **2025-12-19** : new community chat on discord * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] - ## Status API is stable. @@ -58,6 +55,41 @@ go get github.com/go-openapi/loads See also the provided [examples](https://pkg.go.dev/github.com/go-openapi/loads#pkg-examples). +## Security + +This library does not enforce a security policy of its own: it reads whatever the configured +loader is allowed to read. + +This is deliberate — like `go-openapi/swag/loading`, it is a base utility, +and sanitizing or containing untrusted input is the caller's responsibility, +just as sanitizing a file name before passing it to `os.ReadFile` is not that function's job. + +When a spec — its path or its `$ref` contents — may come from an untrusted source, confine +loading explicitly (e.g. `loading.WithRoot` for local files and a restricted +`loading.WithHTTPClient` for remote URLs, passed via `loads.WithLoadingOptions`). + +For the common case, the pre-baked `loads.SpecRestricted` / `loads.JSONSpecRestricted` loaders +bundle a trusted root with a network-restricted client (`loads.RestrictedHTTPClient`) and apply +the confinement to `$ref` resolution as well: + +```go +doc, err := loads.SpecRestricted(path, trustedRoot) +``` + +To harden the package-level default in one call — so even callers that rely on the global +loader (including cross-package `$ref` resolution via `spec.PathLoader`) are confined, with no +unconfined fallback left — use `loads.SetRestrictedLoaders` at startup: + +```go +loads.SetRestrictedLoaders(trustedRoot) +``` + +Note that `loads.AddLoader` only *prepends* to the default chain, leaving the unconfined loader +reachable; use `loads.SetLoaders` / `loads.SetRestrictedLoaders` to replace it. + +See the [Security section of the package documentation][security-doc] for the threat model and +runnable examples. For the project's vulnerability reporting policy, see [SECURITY.md](./SECURITY.md). + ## Change log See @@ -69,9 +101,9 @@ This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE). ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -102,11 +134,8 @@ Maintainers can cut a new release by either: [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/loads [godoc-url]: http://pkg.go.dev/github.com/go-openapi/loads -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue -[discord-url]: https://discord.gg/twZ9BwT3 +[discord-url]: https://discord.gg/FfnFYaC3k5 [license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg @@ -116,3 +145,9 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/loads/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/loads [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/loads/latest + +[security-doc]: https://pkg.go.dev/github.com/go-openapi/loads#hdr-Security + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/loads/doc.go b/vendor/github.com/go-openapi/loads/doc.go index 67a5e2f8d95..0fafe4f4683 100644 --- a/vendor/github.com/go-openapi/loads/doc.go +++ b/vendor/github.com/go-openapi/loads/doc.go @@ -6,4 +6,72 @@ // It is used by other go-openapi packages to load and run analysis on local or remote spec documents. // // Loaders support JSON and YAML documents. +// +// # Security +// +// This package does not enforce a security policy of its own: like the underlying +// [github.com/go-openapi/swag/loading] utilities, it reads whatever the configured loader is +// allowed to read. +// +// When a spec — its path or its contents — may derive from untrusted input, the caller must confine loading explicitly. +// +// This is a deliberate design choice. +// Both this package and the [github.com/go-openapi/swag/loading] utilities are base building blocks: +// deciding which sources are legitimate, and containing access to them, +// requires application context that a general-purpose loader does not have. +// +// Just as sanitizing a file name before handing it to [os.ReadFile] is the caller's +// responsibility and not that function's, sanitizing and containing the path and references +// resolved here is the responsibility of the code that may feed them untrusted input. +// +// There are two distinct attack surfaces: +// +// - The path passed to [Spec], [JSONSpec], or [Embedded]. By default a local path is read +// with no confinement, so a caller-controlled path (including an absolute path or a +// "file:///etc/passwd" URI) may read any file the process can access. A remote path is +// fetched with [net/http.DefaultClient], which follows redirects and performs no +// destination filtering, so a caller-controlled URL may reach internal services or cloud +// metadata endpoints (server-side request forgery). +// +// - The contents of the spec, when references are resolved. [Document.Expanded] follows the +// "$ref" pointers found inside the document by calling the same loader recursively. A spec +// obtained even from a trusted path can therefore drive arbitrary local reads +// ("$ref": "file:///etc/passwd") or SSRF ("$ref": "http://169.254.169.254/...") through +// its own contents. This amplification is specific to reference resolution and does not +// exist in the raw loading utilities. +// +// Mitigation. Pass [github.com/go-openapi/swag/loading] options through [WithLoadingOptions]; +// they are attached to the document's loader and so apply both to the initial load and to +// every "$ref" resolved during expansion: +// +// - [github.com/go-openapi/swag/loading.WithRoot] confines local reads to a trusted +// directory, rejecting absolute paths, ".." traversal, and symlinks that escape it. Prefer +// it over a [github.com/go-openapi/swag/loading.WithFS] built from [os.DirFS], which does +// not block symlink escapes. +// +// - [github.com/go-openapi/swag/loading.WithHTTPClient] allows to supply a restricted HTTP client. +// Enforce the network policy at dial time (a [net.Dialer] Control hook), so it also covers +// redirects and DNS rebinding, which a URL-string allowlist cannot. See the example on +// [Spec]. +// +// Pre-baked loaders. When the opinionated defaults fit, [SpecRestricted], [JSONSpecRestricted] +// and [JSONDocRestricted] bundle a trusted root with a network-restricted client +// ([RestrictedHTTPClient]), and apply the confinement to "$ref" resolution as well — so the +// common case needs no manual wiring. To harden the global default in one call (so even callers +// that rely on the package-level loader are confined), use [SetRestrictedLoaders]. Reach for the +// options above when you need a custom policy; [IsForbiddenAddress] exposes the default network +// policy so you can reuse it as the base of your own HTTP client. +// +// Caveats: +// +// - The package-level default loader (also installed as [github.com/go-openapi/spec.PathLoader]) +// carries no loading options and is therefore unconfined. It is used as a fallback when +// expansion runs without a document loader, and by other go-openapi packages that resolve +// references on their own. [AddLoader] does not fix this — it only prepends, leaving the +// unconfined fallback reachable. Either build a confined loader per call, or replace the +// global default outright with [SetLoaders] / [SetRestrictedLoaders]. +// +// - A custom loader installed via [WithDocLoader] or [AddLoader] only honors these +// protections if its loading function actually applies the [github.com/go-openapi/swag/loading] +// options it is given. package loads diff --git a/vendor/github.com/go-openapi/loads/errors.go b/vendor/github.com/go-openapi/loads/errors.go index 14a8186b6ca..e94f038f947 100644 --- a/vendor/github.com/go-openapi/loads/errors.go +++ b/vendor/github.com/go-openapi/loads/errors.go @@ -15,4 +15,8 @@ const ( // ErrNoLoader indicates that no configured loader matched the input. ErrNoLoader loaderError = "no loader matched" + + // ErrForbiddenAddress is returned by [RestrictedHTTPClient] when a connection is attempted + // to a non-public address (loopback, private, link-local, or unspecified). + ErrForbiddenAddress loaderError = "blocked dial to a non-public address" ) diff --git a/vendor/github.com/go-openapi/loads/loaders.go b/vendor/github.com/go-openapi/loads/loaders.go index ac8adfe8b20..ba5c48b65f8 100644 --- a/vendor/github.com/go-openapi/loads/loaders.go +++ b/vendor/github.com/go-openapi/loads/loaders.go @@ -21,6 +21,15 @@ import ( var loaders *loader func init() { + loaders = defaultLoaders() + + // sets the global default loader for go-openapi/spec + spec.PathLoader = loaders.Load +} + +// defaultLoaders builds the built-in loader chain: a YAML matcher first, with a JSON loader as +// the catch-all fallback. +func defaultLoaders() *loader { jsonLoader := &loader{ DocLoaderWithMatch: DocLoaderWithMatch{ Match: func(_ string) bool { @@ -30,20 +39,85 @@ func init() { }, } - loaders = jsonLoader.WithHead(&loader{ + return jsonLoader.WithHead(&loader{ DocLoaderWithMatch: DocLoaderWithMatch{ Match: loading.YAMLMatcher, Fn: loading.YAMLDoc, }, }) +} - // sets the global default loader for go-openapi/spec - spec.PathLoader = loaders.Load +// LoaderChain links a list of [DocLoaderWithMatch] into a single [DocLoader], preserving order. +// Entries with a nil Fn are skipped. Loading options passed at call time are forwarded to the +// matched loader. +// +// Combined with [LoaderWithOptions], it composes a self-contained loader (for example a +// format-dispatching YAML/JSON chain, each entry carrying its own options) that a caller can inject +// through [WithDocLoader] instead of relying on the package-level global loaders. +// +// The returned DocLoader is never nil: when no usable loader is provided, it yields [ErrNoLoader] +// on every call. This fails closed rather than returning nil (which every caller would have to +// guard against, at the risk of a nil-func panic) or silently falling back to an unconfined +// loader. +func LoaderChain(ldrs ...DocLoaderWithMatch) DocLoader { + loader := buildLoaderChain(ldrs...) + + return func(pth string, opts ...loading.Option) (json.RawMessage, error) { + l := loader.clone() + if l != nil { + l.loadingOptions = opts + } + + return l.Load(pth) // nil-safe: yields ErrNoLoader when the chain is empty + } +} + +// buildLoaderChain links a list of [DocLoaderWithMatch] into a loader chain, preserving order. +// Entries with a nil Fn are skipped. Returns nil when no usable loader is provided. +func buildLoaderChain(ldrs ...DocLoaderWithMatch) *loader { + var final, prev *loader + for _, ldr := range ldrs { + if ldr.Fn == nil { + continue + } + + node := &loader{DocLoaderWithMatch: ldr} + if prev == nil { + final = node + prev = node + + continue + } + + prev = prev.WithNext(node) + } + + return final } // DocLoader represents a doc loader type. type DocLoader func(string, ...loading.Option) (json.RawMessage, error) +// LoaderWithOptions returns a [DocLoader] that always applies opts. +// +// Use it to bind a set of [loading.Option] to a loader so they apply to every load — for example a +// custom HTTP client or timeout, authentication or custom headers, an embedded or rooted file +// system, or a remote-address restriction. This is the building block for a document loader that +// carries its own options, avoiding reliance on the package-level global loaders. +// +// opts are appended after any options passed at call time, so they take precedence (loading +// options are last-wins). This also makes confinement options (e.g. [loading.WithRoot]) win over +// any caller-supplied options. +func LoaderWithOptions(fn DocLoader, opts ...loading.Option) DocLoader { + return func(path string, callOpts ...loading.Option) (json.RawMessage, error) { + all := make([]loading.Option, 0, len(callOpts)+len(opts)) + all = append(all, callOpts...) + all = append(all, opts...) + + return fn(path, all...) + } +} + // DocMatcher represents a predicate to check if a loader matches. type DocMatcher func(string) bool @@ -141,6 +215,17 @@ func JSONDoc(path string, opts ...loading.Option) (json.RawMessage, error) { // // This function updates the default loader used by [github.com/go-openapi/spec]. // Since this sets package level globals, you shouldn't call this concurrently. +// +// # Security +// +// AddLoader only *prepends* to the default chain: the previous loaders — including the +// unconfined JSON fallback — remain reachable, both here and via cross-package "$ref" +// resolution. It is therefore the wrong tool for hardening the global default. To replace the +// chain entirely (leaving no unconfined fallback) use [SetLoaders], or [SetRestrictedLoaders] +// for a one-call confined setup. For a single load, prefer a confined per-call loader via +// [WithLoadingOptions] or [WithDocLoaderMatches]. A custom loader registered here only honors +// the protections if its loading function applies the [github.com/go-openapi/swag/loading] +// options it is given. See the package documentation on Security. func AddLoader(predicate DocMatcher, load DocLoader) { loaders = loaders.WithHead(&loader{ DocLoaderWithMatch: DocLoaderWithMatch{ @@ -152,3 +237,36 @@ func AddLoader(predicate DocMatcher, load DocLoader) { // sets the global default loader for go-openapi/spec spec.PathLoader = loaders.Load } + +// SetLoaders replaces the package-level default loader chain with the given loaders, tried in +// order, and re-points [github.com/go-openapi/spec.PathLoader] at it. +// +// Unlike [AddLoader], nothing of the previous default survives — so when the replacement is +// confined, no unconfined fallback remains for any caller relying on the global default +// (including cross-package "$ref" resolution). An entry with a nil Match is a catch-all; you +// are responsible for providing a suitable fallback. Calling SetLoaders with no usable loader +// restores the built-in default (a YAML matcher with a JSON fallback). +// +// # Concurrency +// +// This sets package-level globals and the [github.com/go-openapi/spec] global loader. It is +// not safe to call concurrently with other loads or with [AddLoader]; configure it once at +// startup, before serving. +// +// # Security +// +// This is the way to harden the global default in one place. For a ready-made confined setup, +// see [SetRestrictedLoaders]. As with [AddLoader], a custom loader only honors the protections +// if its loading function applies the [github.com/go-openapi/swag/loading] options it is given. +// See the package documentation on Security. +func SetLoaders(ldrs ...DocLoaderWithMatch) { + chain := buildLoaderChain(ldrs...) + if chain == nil { + chain = defaultLoaders() + } + + loaders = chain + + // sets the global default loader for go-openapi/spec + spec.PathLoader = loaders.Load +} diff --git a/vendor/github.com/go-openapi/loads/options.go b/vendor/github.com/go-openapi/loads/options.go index 045ece5e095..6a4bc6983bc 100644 --- a/vendor/github.com/go-openapi/loads/options.go +++ b/vendor/github.com/go-openapi/loads/options.go @@ -51,25 +51,17 @@ func WithDocLoader(l DocLoader) LoaderOption { // Loaders are executed in the order of provided [DocLoaderWithMatch] 'es. func WithDocLoaderMatches(l ...DocLoaderWithMatch) LoaderOption { return func(opt *options) { - var final, prev *loader - for _, ldr := range l { - if ldr.Fn == nil { - continue - } - - if prev == nil { - final = &loader{DocLoaderWithMatch: ldr} - prev = final - continue - } - - prev = prev.WithNext(&loader{DocLoaderWithMatch: ldr}) - } - opt.loader = final + opt.loader = buildLoaderChain(l...) } } // WithLoadingOptions adds some [loading.Option] to be added when calling a registered loader. +// +// The options are attached to the document's loader, so they apply both to the initial load +// and to every "$ref" resolved during [Document.Expanded]. +// +// This is the recommended place to confine loading of untrusted input, for example with [loading.WithRoot] (local) and +// [loading.WithHTTPClient] (remote). See the package documentation on Security. func WithLoadingOptions(loadingOptions ...loading.Option) LoaderOption { return func(opt *options) { opt.loadingOptions = loadingOptions diff --git a/vendor/github.com/go-openapi/loads/restricted.go b/vendor/github.com/go-openapi/loads/restricted.go new file mode 100644 index 00000000000..022a9a8572a --- /dev/null +++ b/vendor/github.com/go-openapi/loads/restricted.go @@ -0,0 +1,185 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package loads + +import ( + "encoding/json" + "net" + "net/http" + "net/netip" + "syscall" + "time" + + "github.com/go-openapi/swag/loading" +) + +const ( + // numConfinementOptions is the count of loading options appended to enforce confinement + // (WithRoot + WithHTTPClient), used to size the bundled option slice. + numConfinementOptions = 2 + + defaultTLSHandshakeTimeout = 10 * time.Second +) + +// RestrictedHTTPClient returns an [http.Client] that refuses, at dial time, to connect to +// loopback, private, link-local (including cloud-metadata endpoints such as 169.254.169.254), +// or unspecified addresses. A blocked connection fails with an error wrapping +// [ErrForbiddenAddress]. +// +// The check runs in the dialer Control hook, after DNS resolution and before connect, so it +// also covers HTTP redirects and DNS rebinding — which a URL-string allowlist cannot. The +// client does not honor proxy environment variables, so the guard always inspects the real +// destination rather than a proxy address. +// +// This is the network half of the restricted loaders ([JSONDocRestricted], +// [JSONSpecRestricted], [SpecRestricted]). It may also be used directly with +// [github.com/go-openapi/swag/loading.WithHTTPClient]. +// +// The policy is opinionated and deliberately simple. For a different one (a custom allow/deny +// list, an explicit proxy, mutual TLS, ...), build your own client and pass it with +// [github.com/go-openapi/swag/loading.WithHTTPClient]. To keep the default address policy as a +// base, reuse [IsForbiddenAddress] in your own dialer Control hook — see the package examples +// for the pattern. +func RestrictedHTTPClient() *http.Client { + control := func(_, address string, _ syscall.RawConn) error { + host, _, err := net.SplitHostPort(address) + if err != nil { + return err + } + addr, err := netip.ParseAddr(host) + if err != nil { + return err + } + if IsForbiddenAddress(addr) { + return ErrForbiddenAddress + } + + return nil + } + + return &http.Client{ + Transport: &http.Transport{ + Proxy: nil, // dial the real destination so the guard inspects it + DialContext: (&net.Dialer{Control: control}).DialContext, + ForceAttemptHTTP2: true, + TLSHandshakeTimeout: defaultTLSHandshakeTimeout, + }, + } +} + +// IsForbiddenAddress reports whether addr is one that [RestrictedHTTPClient] refuses to dial: +// a loopback, private, link-local (including cloud-metadata endpoints such as 169.254.169.254), +// or unspecified address. IPv4-mapped IPv6 addresses are unmapped before the check. +// +// It is exported so callers can reuse or extend the default policy when building their own +// dialer Control hook, for example to also reject a CGNAT range or to carve out a single +// trusted internal host: +// +// control := func(_, address string, _ syscall.RawConn) error { +// host, _, err := net.SplitHostPort(address) +// if err != nil { +// return err +// } +// addr, err := netip.ParseAddr(host) +// if err != nil { +// return err +// } +// if loads.IsForbiddenAddress(addr) && host != allowedInternalHost { +// return loads.ErrForbiddenAddress +// } +// return nil +// } +func IsForbiddenAddress(addr netip.Addr) bool { + a := addr.Unmap() + + return a.IsLoopback() || a.IsPrivate() || a.IsLinkLocalUnicast() || a.IsUnspecified() +} + +// restrictedLoadingOptions bundles caller-supplied options with the confinement options, +// appended last so that local rooting and the restricted client always take precedence +// (the loading options are last-wins). +func restrictedLoadingOptions(root string, extra []loading.Option) []loading.Option { + out := make([]loading.Option, 0, len(extra)+numConfinementOptions) + out = append(out, extra...) + out = append(out, loading.WithRoot(root), loading.WithHTTPClient(RestrictedHTTPClient())) + + return out +} + +// JSONDocRestricted returns a JSON [DocLoader] that confines local reads to root (via +// [github.com/go-openapi/swag/loading.WithRoot]) and restricts remote fetches with +// [RestrictedHTTPClient]. +// +// The returned loader may be registered with [WithDocLoader] or [AddLoader]. The confinement +// always takes precedence over any option passed here or at call time, so a caller cannot +// loosen it through [WithLoadingOptions]. +// +// Like [JSONDoc], it loads JSON only: it does not convert YAML. For specs whose references may +// point at YAML documents, prefer [SpecRestricted], which keeps the default JSON/YAML chain. +func JSONDocRestricted(root string, opts ...loading.Option) DocLoader { + // one restricted client, reused for every path and $ref + return restrictedDocLoader(JSONDoc, restrictedLoadingOptions(root, opts)) +} + +// restrictedDocLoader wraps a [DocLoader] so that the confinement options in base are always +// applied, appended after any call-time options so they take precedence (loading options are +// last-wins). +func restrictedDocLoader(fn DocLoader, base []loading.Option) DocLoader { + return func(path string, callOpts ...loading.Option) (json.RawMessage, error) { + if len(callOpts) == 0 { + return fn(path, base...) + } + + all := make([]loading.Option, 0, len(callOpts)+len(base)) + all = append(all, callOpts...) + all = append(all, base...) // confinement (tail of base) still wins + + return fn(path, all...) + } +} + +// JSONSpecRestricted loads a JSON spec like [JSONSpec], but confines local reads to root and +// restricts remote fetches with [RestrictedHTTPClient]. +// +// The confinement is attached to the document's loader, so it also applies to every "$ref" +// resolved by [Document.Expanded]. Extra [github.com/go-openapi/swag/loading] options (custom +// headers, basic auth, timeout, ...) may be supplied; the confinement always wins over them. +func JSONSpecRestricted(path, root string, opts ...loading.Option) (*Document, error) { + return JSONSpec(path, WithLoadingOptions(restrictedLoadingOptions(root, opts)...)) +} + +// SpecRestricted loads a spec like [Spec] — with JSON/YAML auto-detection — but confines local +// reads to root and restricts remote fetches with [RestrictedHTTPClient]. +// +// The confinement is attached to the document's loader, so it also applies to every "$ref" +// resolved by [Document.Expanded]. Extra [github.com/go-openapi/swag/loading] options (custom +// headers, basic auth, timeout, ...) may be supplied; the confinement always wins over them. +func SpecRestricted(path, root string, opts ...loading.Option) (*Document, error) { + return Spec(path, WithLoadingOptions(restrictedLoadingOptions(root, opts)...)) +} + +// SetRestrictedLoaders hardens the package-level default in a single call: it installs a +// confined JSON/YAML loader chain — local reads rooted at root, remote fetches through +// [RestrictedHTTPClient] — as the global default and as +// [github.com/go-openapi/spec.PathLoader]. +// +// After this call, every load that relies on the package default ([Spec], [JSONSpec], and any +// cross-package "$ref" resolution) is confined, with no unconfined fallback left behind. It is +// the global counterpart of [SpecRestricted]; a single restricted client is shared across the +// chain. Extra [github.com/go-openapi/swag/loading] options may be supplied; the confinement +// always wins over them. +// +// # Concurrency +// +// Like [SetLoaders], this mutates package-level and [github.com/go-openapi/spec] globals and is +// not safe to call concurrently. Configure it once at startup, before serving. To revert, call +// [SetLoaders] with no arguments. +func SetRestrictedLoaders(root string, opts ...loading.Option) { + base := restrictedLoadingOptions(root, opts) // one restricted client shared by the whole chain + + SetLoaders( + NewDocLoaderWithMatch(restrictedDocLoader(loading.YAMLDoc, base), loading.YAMLMatcher), + NewDocLoaderWithMatch(restrictedDocLoader(JSONDoc, base), nil), // nil matcher: JSON catch-all fallback + ) +} diff --git a/vendor/github.com/go-openapi/loads/spec.go b/vendor/github.com/go-openapi/loads/spec.go index 606a01d8e9f..40eaff2c73b 100644 --- a/vendor/github.com/go-openapi/loads/spec.go +++ b/vendor/github.com/go-openapi/loads/spec.go @@ -77,6 +77,14 @@ func Embedded(orig, flat json.RawMessage, opts ...LoaderOption) (*Document, erro // Spec loads a new spec document from a local or remote path. // // By default it uses a JSON or YAML loader, with auto-detection based on the resource extension. +// +// Security: by default the path is read with no confinement (local) and fetched with +// [net/http.DefaultClient] (remote), and any "$ref" later resolved by [Document.Expanded] is +// loaded the same way. When the path or the spec contents may derive from untrusted input, +// confine loading with [WithLoadingOptions] (for example +// [github.com/go-openapi/swag/loading.WithRoot] and +// [github.com/go-openapi/swag/loading.WithHTTPClient]). See the package documentation on +// Security. func Spec(path string, opts ...LoaderOption) (*Document, error) { ldr := loaderFromOptions(opts) @@ -157,6 +165,14 @@ func trimData(in json.RawMessage) (json.RawMessage, error) { } // Expanded expands the $ref fields in the spec [Document] and returns a new expanded [Document]. +// +// Security: expansion resolves every "$ref" by calling the document's loader recursively, so +// the spec contents drive further loads. A spec from an untrusted source can thus trigger +// arbitrary local reads or SSRF through its references. The loader carries the +// [github.com/go-openapi/swag/loading] options supplied via [WithLoadingOptions] at load time; +// configure confinement there so it applies to expansion as well. When no document loader is +// set, expansion falls back to the unconfined package-level loader. See the package +// documentation on Security. func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) { swspec := new(spec.Swagger) if err := json.Unmarshal(d.raw, swspec); err != nil { diff --git a/vendor/github.com/go-openapi/runtime/.codecov.yml b/vendor/github.com/go-openapi/runtime/.codecov.yml new file mode 100644 index 00000000000..a5ba8e96d8e --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/.codecov.yml @@ -0,0 +1,9 @@ +codecov: + notify: + after_n_builds: 2 + +coverage: + status: + patch: + default: + target: 80% diff --git a/vendor/github.com/go-openapi/runtime/.gitignore b/vendor/github.com/go-openapi/runtime/.gitignore index d8f4186fe59..c0bc15bebe6 100644 --- a/vendor/github.com/go-openapi/runtime/.gitignore +++ b/vendor/github.com/go-openapi/runtime/.gitignore @@ -3,3 +3,5 @@ .idea .env .mcp.json +go.work.sum +.worktrees/ diff --git a/vendor/github.com/go-openapi/runtime/.golangci.yml b/vendor/github.com/go-openapi/runtime/.golangci.yml index 0087ed31130..affd69c88a4 100644 --- a/vendor/github.com/go-openapi/runtime/.golangci.yml +++ b/vendor/github.com/go-openapi/runtime/.golangci.yml @@ -2,13 +2,9 @@ version: "2" linters: default: all disable: - - cyclop - depguard - err113 # disabled temporarily: there are just too many issues to address - - errchkjson - - errorlint - exhaustruct - - forcetypeassert - funlen - gochecknoglobals - gochecknoinits @@ -16,12 +12,12 @@ linters: - godot - godox - gomoddirectives # moved to mono-repo, multi-modules, so replace directives are needed + - gomodguard + - gomodguard_v2 - gosmopolitan - inamedparam - - ireturn - - lll + - ireturn # this repo adopted a pattern where there are quite many returned interfaces. To be challenged with v2 - musttag - - nestif - nilerr # nilerr crashes on this repo - nlreturn - noinlineerr @@ -31,7 +27,6 @@ linters: - testpackage - thelper - tparallel - - unparam - varnamelen - whitespace - wrapcheck @@ -41,10 +36,19 @@ linters: dupl: threshold: 200 goconst: - min-len: 2 + min-len: 9 min-occurrences: 3 + cyclop: + max-complexity: 25 gocyclo: - min-complexity: 45 + min-complexity: 25 + gocognit: + min-complexity: 35 + exhaustive: + default-signifies-exhaustive: true + default-case-required: true + lll: + line-length: 180 exclusions: generated: lax presets: @@ -53,6 +57,7 @@ linters: - legacy - std-error-handling paths: + - .worktrees - third_party$ - builtin$ - examples$ @@ -60,12 +65,17 @@ formatters: enable: - gofmt - goimports + settings: + # local prefixes regroup imports from these packages + goimports: + local-prefixes: + - github.com/go-openapi exclusions: generated: lax paths: + - .worktrees - third_party$ - builtin$ - - examples$ issues: # Maximum issues count per one linter. # Set to 0 to disable. diff --git a/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md b/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md index 541fd575e01..9c959ef4823 100644 --- a/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/runtime/CONTRIBUTORS.md @@ -4,20 +4,21 @@ | Total Contributors | Total Contributions | | --- | --- | -| 69 | 490 | +| 71 | 570 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | | @casualjim | 268 | | -| @fredbi | 69 | | +| @fredbi | 144 | | | @youyuanwu | 19 | | | @josephwoodward | 13 | | | @kenjones-cisco | 12 | | | @GlenDC | 7 | | -| @elakito | 6 | | | @moenning | 6 | | | @mstoykov | 6 | | +| @elakito | 6 | | | @ifraixedes | 5 | | +| @Copilot | 4 | | | @zeitlinger | 4 | | | @jkawamoto | 3 | | | @stoyanr | 3 | | @@ -44,7 +45,7 @@ | @petrkotas | 1 | | | @maxatome | 1 | | | @maxkarelov | 1 | | -| @aleksandr-vin | 1 | | +| @tooolbox | 1 | | | @akutz | 1 | | | @yabberyabber | 1 | | | @elv-gilles | 1 | | @@ -56,6 +57,7 @@ | @tte | 1 | | | @martian4202 | 1 | | | @yan-zhuang | 1 | | +| @aleksandr-vin | 1 | | | @azylman | 1 | | | @anasmuhmd | 1 | | | @ArFe | 1 | | @@ -74,8 +76,8 @@ | @JoakimSoderberg | 1 | | | @robbert229 | 1 | | | @jonathaningram | 1 | | +| @KuaaMU | 1 | | | @germanhs | 1 | | | @pracucci | 1 | | -| @tooolbox | 1 | | _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/runtime/README.md b/vendor/github.com/go-openapi/runtime/README.md index fa749062b34..134d930cd9f 100644 --- a/vendor/github.com/go-openapi/runtime/README.md +++ b/vendor/github.com/go-openapi/runtime/README.md @@ -8,8 +8,7 @@ [![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url] -[![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] - +[![Doc][doc-badge]][doc-url] [![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge] --- A runtime for go OpenAPI toolkit. @@ -18,13 +17,44 @@ The runtime component for use in code generation or as untyped usage. ## Announcements -* **2025-12-19** : new community chat on discord - * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** +[**Complete documentation as github pages**][doc-url] + +**Changes to the API surface in `v0.30.0`**: + +* utility package `header` has now moved to `github.com/go-openapi/runtime/server-middleware/negotiate/header` + +> A shim is provided to support existing programs, with a deprecation notice. + +**Changes in semantics in `v0.30.0`**: + +Function `negotiate.NegotiateContentType` (available as an alias for backward compatibility as `middleware.NegotiateContentType` +now performs a full match considering MIME parameters. + +The previous behavior (matching in order of appearance after stripping parameters) may be enabled explicitly with +option `negotiate.WithIgnoreParameters`. + +* **2026-05-07** : exposed UI and Spec middleware as a separate, dependency-free module. + +> Newly available package: `github.com/go-openapi/runtime/server-middleware/docui` that now holds our +> UI and spec serve middleware. +> +> A shim is available in `github.com/go-openapi/runtime/middleware` to bridge the older UI options to the new ones, +> with a deprecation notice. +> +> Methods that were unduly exported and purely used to manipulate options (e.g. `SwaggerUIOpts.EnsureDefaults`) have been +> removed. New options in `docui` should be used instead. + +> Users may reuse this middleware to serve a Redoc, Rapidoc or SwaggerUI documentation without +> importing the complete go-openapi scaffolding. -You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] +* **2026-05-05** : exposed content negotiation methods as a separate, dependency-free module -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] +> Users may reuse these utilities to support content-negotiation without extra dependencies. +> +> Newly available module: `github.com/go-openapi/runtime/server-middleware` +> +> Newly available packages: `github.com/go-openapi/runtime/server-middleware/negotiate` and +> `github.com/go-openapi/runtime/server-middleware/mediatype`. ## Status @@ -40,18 +70,21 @@ go get github.com/go-openapi/runtime See -For pre-v0.30.0 releases see [release notes](docs/NOTES.md). +For v0.29.0 release see [release notes](docs/NOTES.md). +From that release onwards, changes are tracked in the github release notes. **What coming next?** Moving forward, we want to : -* [ ] continue narrowing down the scope of dependencies: - * yaml support in an independent module +* [x] fix a few known issues with some file upload requests (e.g. #286) +* [] continue narrowing down the scope of dependencies: + * [x] split middleware and other useful utilities as a separate dependency-free module + * yaml support in an independent module (v2) * introduce more up-to-date support for opentelemetry as a separate module that evolves independently from the main package (to avoid breaking changes, the existing API - will remain maintained, but evolve at a slower pace than opentelemetry). -* [ ] fix a few known issues with some file upload requests (e.g. #286) + will remain maintained, but evolve at a slower pace than opentelemetry). (v2) +* [] publish proper documentation and examples ## Licensing @@ -62,11 +95,11 @@ on top of which it has been built. ## Other documentation -* [FAQ](docs/FAQ.md) +* [FAQ](https://go-openapi.github.io/runtime/tutorials/faq/) · [Media-type selection](https://go-openapi.github.io/runtime/tutorials/media-types/) · [Client keep-alive](https://go-openapi.github.io/runtime/tutorials/keep-alive/) * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -95,11 +128,10 @@ Maintainers can cut a new release by either: [codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/runtime [codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/runtime +[doc-badge]: https://img.shields.io/badge/doc-site-blue?link=https%3A%2F%2Fgo-openapi.github.io%2Fruntime%2F +[doc-url]: https://go-openapi.github.io/runtime [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/runtime [godoc-url]: http://pkg.go.dev/github.com/go-openapi/runtime -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue [discord-url]: https://discord.gg/FfnFYaC3k5 @@ -111,3 +143,7 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/runtime/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/runtime [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/runtime/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/runtime/bytestream.go b/vendor/github.com/go-openapi/runtime/bytestream.go index 8701c8e3d66..9371ea4ea1f 100644 --- a/vendor/github.com/go-openapi/runtime/bytestream.go +++ b/vendor/github.com/go-openapi/runtime/bytestream.go @@ -97,7 +97,7 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer { } default: // check for the underlying type to be pointer to []byte or string, - if ptr := reflect.TypeOf(data); ptr.Kind() != reflect.Ptr { + if ptr := reflect.TypeOf(data); ptr.Kind() != reflect.Pointer { return errors.New("destination must be a pointer") } @@ -126,13 +126,13 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer { // // Supported input underlying types and interfaces, prioritized in this order: // -// - [io.WriterTo] (for maximum control) -// - [io.Reader] (performs [io.Copy]). A ReadCloser is closed before exiting. -// - [encoding.BinaryMarshaler] -// - error (writes as a string) -// - []byte -// - string -// - struct, other slices: writes as JSON. +// - [io.WriterTo] (for maximum control) +// - [io.Reader] (performs [io.Copy]). A ReadCloser is closed before exiting. +// - [encoding.BinaryMarshaler] +// - error (writes as a string) +// - []byte +// - string +// - struct, other slices: writes as JSON. func ByteStreamProducer(opts ...byteStreamOpt) Producer { var vals byteStreamOpts for _, opt := range opts { diff --git a/vendor/github.com/go-openapi/runtime/client/httptrace.go b/vendor/github.com/go-openapi/runtime/client/httptrace.go new file mode 100644 index 00000000000..5bdea4e2418 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/client/httptrace.go @@ -0,0 +1,520 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package client + +import ( + "context" + "crypto/tls" + "fmt" + "io" + "net/http/httptrace" + "strings" + "sync" + "time" + + "github.com/go-openapi/runtime/logger" +) + +// traceSession owns the per-request state for [Runtime.Trace]. +// +// It tracks the t=0 anchor for the connection phase, accumulates +// per-phase timestamps (for the trailing summary), and emits each +// event to the runtime logger as it fires. One session per +// SubmitContext call. +type traceSession struct { + logger logger.Logger + method string + url string + + // tlsCfg points at the *tls.Config of the http.Transport that + // will run the request, when introspectable (i.e. the transport + // is an *http.Transport). Used by the TLS diagnostic mode to + // cross-check user configuration against what the handshake + // actually attempted. Nil when the transport is custom and + // the config cannot be reached. + tlsCfg *tls.Config + + mu sync.Mutex + start time.Time + last time.Time // last printed event, for relative-dt rendering + phases phaseTimings + gotConn httptrace.GotConnInfo + tlsDone tlsResult + + dnsStartAt time.Time + connectStartAt time.Time + tlsHandshakeStartAt time.Time + wait100StartAt time.Time + gotConnAt time.Time + wroteHeadersAt time.Time + wroteRequestAt time.Time + ttfbAt time.Time + + statusCode int + rtError error +} + +// phaseTimings holds the per-phase durations for the trailing +// summary line. Zero values mean "phase did not occur" (e.g. no +// DNS lookup on a reused conn, no TLS on http://). +type phaseTimings struct { + dns time.Duration + dial time.Duration + tls time.Duration + ttfb time.Duration // time from GotConn to first response byte +} + +// tlsResult captures whatever we learned from TLSHandshakeDone. +// On the happy path err is nil and state is fully populated; on +// failure state may be partial (and is what the TLS diagnostic +// mode in httptrace_tls.go works from). +type tlsResult struct { + state tls.ConnectionState + err error + done bool +} + +const tracePrefix = "[trace] " + +// staleIdleThreshold is the idle duration above which a reused +// pooled connection earns a HEADS-UP annotation. Per-runtime +// configurability is deferred to v2; 30s matches the issue #336 +// territory (typical NAT idle timeouts start in the 60–350s +// range, so a 30s reuse is already in "could be stale" zone). +const staleIdleThreshold = 30 * time.Second + +// newTraceSession allocates a session and pre-renders the opening +// line (method + url). The session is not yet attached to a +// context — that's the caller's responsibility via session.attach. +// +// tlsCfg may be nil; when non-nil it is used by the TLS diagnostic +// mode to cross-check user-configured constraints (MinVersion, +// CipherSuites, custom RootCAs) against handshake failures. +func newTraceSession(log logger.Logger, method, url string, tlsCfg *tls.Config) *traceSession { + s := &traceSession{ + logger: log, + method: method, + url: url, + tlsCfg: tlsCfg, + start: time.Now(), + } + s.last = s.start + s.emitf("%s %s", method, url) + return s +} + +// attach installs the session's ClientTrace on ctx and returns the +// derived context. Callers pass the returned context to +// http.Client.Do (typically by setting it on req via +// req.WithContext) so the transport fires the hooks. +func (s *traceSession) attach(ctx context.Context) context.Context { + return httptrace.WithClientTrace(ctx, s.clientTrace()) +} + +// clientTrace wires every httptrace hook to the corresponding +// session method. Each callback is responsible for its own +// locking; the stdlib does not serialize trace callbacks. +func (s *traceSession) clientTrace() *httptrace.ClientTrace { + return &httptrace.ClientTrace{ + GetConn: s.onGetConn, + GotConn: s.onGotConn, + PutIdleConn: s.onPutIdleConn, + GotFirstResponseByte: s.onGotFirstResponseByte, + Got100Continue: s.onGot100Continue, + DNSStart: s.onDNSStart, + DNSDone: s.onDNSDone, + ConnectStart: s.onConnectStart, + ConnectDone: s.onConnectDone, + TLSHandshakeStart: s.onTLSHandshakeStart, + TLSHandshakeDone: s.onTLSHandshakeDone, + WroteHeaders: s.onWroteHeaders, + Wait100Continue: s.onWait100Continue, + WroteRequest: s.onWroteRequest, + } +} + +// --------------------------------------------------------------- +// Phase callbacks (stdlib httptrace hooks) +// --------------------------------------------------------------- + +func (s *traceSession) onGetConn(hostPort string) { + s.emitTf("GetConn(%s)", hostPort) +} + +func (s *traceSession) onGotConn(info httptrace.GotConnInfo) { + s.mu.Lock() + s.gotConn = info + s.gotConnAt = time.Now() + s.mu.Unlock() + + if info.Reused { + s.emitTf("GotConn(reused=true, idle=%t, idle-time=%s)", + info.WasIdle, info.IdleTime.Round(time.Millisecond)) + } else { + s.emitTf("GotConn(reused=false)") + } + + if isStaleIdleReuse(info) { + s.emitf("# HEADS-UP: reused idle connection (idle for %s).", + info.IdleTime.Round(time.Second)) + s.emitf("# If this request fails with EOF/connection reset, the server") + s.emitf("# or an in-path NAT may have dropped the conn silently.") + } +} + +// isStaleIdleReuse reports whether a GotConn info indicates the +// connection came from the idle pool after sitting idle for +// longer than [staleIdleThreshold]. This is the issue #336 +// pattern: long-idle pooled conns are the ones most likely to be +// dead by the time the next request tries to use them. +func isStaleIdleReuse(info httptrace.GotConnInfo) bool { + return info.Reused && info.WasIdle && info.IdleTime > staleIdleThreshold +} + +func (s *traceSession) onPutIdleConn(err error) { + if err != nil { + s.emitTf("PutIdleConn(err=%v)", err) + return + } + s.emitTf("PutIdleConn") +} + +func (s *traceSession) onGotFirstResponseByte() { + s.mu.Lock() + s.ttfbAt = time.Now() + if !s.gotConnAt.IsZero() { + s.phases.ttfb = s.ttfbAt.Sub(s.gotConnAt) + } + s.mu.Unlock() + s.emitTf("GotFirstResponseByte (TTFB)") +} + +func (s *traceSession) onGot100Continue() { + s.emitTf("Got100Continue") +} + +func (s *traceSession) onDNSStart(info httptrace.DNSStartInfo) { + s.mu.Lock() + s.dnsStartAt = time.Now() + s.mu.Unlock() + s.emitTf("DNSStart(host=%s)", info.Host) +} + +func (s *traceSession) onDNSDone(info httptrace.DNSDoneInfo) { + s.mu.Lock() + if !s.dnsStartAt.IsZero() { + s.phases.dns = time.Since(s.dnsStartAt) + } + s.mu.Unlock() + + addrs := make([]string, 0, len(info.Addrs)) + for _, a := range info.Addrs { + addrs = append(addrs, a.String()) + } + if info.Err != nil { + s.emitTf("DNSDone(err=%v, addrs=[%s], coalesced=%t)", + info.Err, strings.Join(addrs, " "), info.Coalesced) + return + } + s.emitTf("DNSDone(addrs=[%s], coalesced=%t)", + strings.Join(addrs, " "), info.Coalesced) +} + +func (s *traceSession) onConnectStart(network, addr string) { + s.mu.Lock() + s.connectStartAt = time.Now() + s.mu.Unlock() + s.emitTf("ConnectStart(%s %s)", network, addr) +} + +func (s *traceSession) onConnectDone(network, addr string, err error) { + s.mu.Lock() + if !s.connectStartAt.IsZero() { + s.phases.dial = time.Since(s.connectStartAt) + } + s.mu.Unlock() + + if err != nil { + s.emitTf("ConnectDone(%s %s, err=%v)", network, addr, err) + return + } + s.emitTf("ConnectDone(%s %s)", network, addr) +} + +func (s *traceSession) onTLSHandshakeStart() { + s.mu.Lock() + s.tlsHandshakeStartAt = time.Now() + s.mu.Unlock() + s.emitTf("TLSHandshakeStart") +} + +func (s *traceSession) onTLSHandshakeDone(state tls.ConnectionState, err error) { + s.mu.Lock() + if !s.tlsHandshakeStartAt.IsZero() { + s.phases.tls = time.Since(s.tlsHandshakeStartAt) + } + s.tlsDone = tlsResult{state: state, err: err, done: true} + s.mu.Unlock() + + if err != nil { + s.emitTf("TLSHandshakeDone(err=%v)", err) + s.emitTLSDiagnostic(state, err) + return + } + s.emitTf("TLSHandshakeDone(tls=%s, cipher=%s, server=%s%s)", + tlsVersionName(state.Version), + tls.CipherSuiteName(state.CipherSuite), + state.ServerName, + certExpiryFragment(state), + ) +} + +func (s *traceSession) onWroteHeaders() { + s.mu.Lock() + s.wroteHeadersAt = time.Now() + s.mu.Unlock() + s.emitTf("WroteHeaders") +} + +func (s *traceSession) onWait100Continue() { + s.mu.Lock() + s.wait100StartAt = time.Now() + s.mu.Unlock() + s.emitTf("Wait100Continue") +} + +func (s *traceSession) onWroteRequest(info httptrace.WroteRequestInfo) { + s.mu.Lock() + s.wroteRequestAt = time.Now() + s.mu.Unlock() + + if info.Err != nil { + s.emitTf("WroteRequest(err=%v)", info.Err) + return + } + s.emitTf("WroteRequest") +} + +// --------------------------------------------------------------- +// Body wrapping +// --------------------------------------------------------------- + +// bodySide identifies which direction an instrumented body is on. +type bodySide string + +const ( + bodySend bodySide = "Sent" + bodyRecv bodySide = "Received" +) + +// instrumentedBody wraps an [io.ReadCloser] and emits a +// BodyChunk{Sent,Received} trace event per Read call. Tracks the +// inter-read delay in `dt` so users can see streaming-body +// cadence. +// +// Read granularity: bytes returned by the underlying body, not +// HTTP/1.1 chunked-framing units. For wire-level chunking, use +// [Runtime.Debug] instead. +// +// Concurrency: a single body is read from a single goroutine in +// practice (http.Transport for request bodies, the application +// for response bodies), so no internal locking is needed beyond +// what the underlying ReadCloser provides. +type instrumentedBody struct { + wrapped io.ReadCloser + sess *traceSession + side bodySide + last time.Time +} + +func (b *instrumentedBody) Read(p []byte) (int, error) { + n, err := b.wrapped.Read(p) + if n > 0 { + first := b.last.IsZero() + var dt time.Duration + if !first { + dt = time.Since(b.last) + } + b.last = time.Now() + b.sess.onBodyChunk(b.side, n, dt, first) + } + return n, err +} + +func (b *instrumentedBody) Close() error { + return b.wrapped.Close() +} + +// wrapRequestBody returns an instrumented wrapper around the +// outgoing request body, or the original body if nil (which is +// the common case for GET requests). The wrapper observes +// Transport-side reads, so BodyChunkSent events appear between +// WroteHeaders and WroteRequest in the trace timeline. +func (s *traceSession) wrapRequestBody(body io.ReadCloser) io.ReadCloser { + if body == nil { + return nil + } + return &instrumentedBody{wrapped: body, sess: s, side: bodySend} +} + +// wrapResponseBody returns an instrumented wrapper around the +// incoming response body. Stacks cleanly above +// [KeepAliveTransport]'s drain-on-close behavior. +func (s *traceSession) wrapResponseBody(body io.ReadCloser) io.ReadCloser { + if body == nil { + return nil + } + return &instrumentedBody{wrapped: body, sess: s, side: bodyRecv} +} + +// onBodyChunk renders a single BodyChunk{Sent,Received} event. +// dt is the duration since the previous Read on the same body and +// is meaningful only when `first` is false. The first chunk has no +// preceding read, so the dt= field is suppressed; every subsequent +// chunk emits dt= unconditionally — even when the measured value +// rounds to zero (common on Windows, where the system clock +// resolution is coarser than a fast loopback read loop). +func (s *traceSession) onBodyChunk(side bodySide, n int, dt time.Duration, first bool) { + if first { + s.emitTf("BodyChunk%s(n=%d)", side, n) + return + } + s.emitTf("BodyChunk%s(n=%d, dt=%s)", side, n, round(dt)) +} + +// --------------------------------------------------------------- +// Submit-level lifecycle hooks (called from SubmitContext) +// --------------------------------------------------------------- + +// onRoundTripError is called by SubmitContext when http.Client.Do +// returns an error. It records the error for the summary line. +func (s *traceSession) onRoundTripError(err error) { + s.mu.Lock() + s.rtError = err + s.mu.Unlock() + s.emitTf("! error: %v", err) +} + +// onResponse is called when http.Client.Do returns successfully. +// It records the status code for the summary line. +func (s *traceSession) onResponse(statusCode int) { + s.mu.Lock() + s.statusCode = statusCode + s.mu.Unlock() +} + +// finish renders the trailing single-line summary and is called +// by SubmitContext after the response body has been consumed (or +// on error path, after the error was recorded). When a round-trip +// error happened on a stale-idle reused connection, a tail block +// flags the issue #336 pattern explicitly. +func (s *traceSession) finish() { + s.mu.Lock() + defer s.mu.Unlock() + + total := time.Since(s.start) + var b strings.Builder + fmt.Fprintf(&b, "Summary: %s — ", s.method) + if s.rtError != nil { + fmt.Fprintf(&b, "FAILED (%v)", s.rtError) + } else { + fmt.Fprintf(&b, "%d", s.statusCode) + } + if s.phases.dns > 0 { + fmt.Fprintf(&b, ", dns=%s", round(s.phases.dns)) + } + if s.phases.dial > 0 { + fmt.Fprintf(&b, ", dial=%s", round(s.phases.dial)) + } + if s.phases.tls > 0 { + fmt.Fprintf(&b, ", tls=%s", round(s.phases.tls)) + } + if s.phases.ttfb > 0 { + fmt.Fprintf(&b, ", ttfb=%s", round(s.phases.ttfb)) + } + fmt.Fprintf(&b, ", total=%s", round(total)) + + s.emitRaw(b.String()) + + // issue #336 tail annotation: a round-trip failure on a + // stale-idle reused conn is the canonical pattern. + if s.rtError != nil && isStaleIdleReuse(s.gotConn) { + s.emitf("# FAILED on a reused idle conn (%s idle).", + s.gotConn.IdleTime.Round(time.Second)) + s.emitf("# Silently closed the conn while it sat in the idle pool.") + s.emitf("# Consider lowering http.Transport.IdleConnTimeout to evict") + s.emitf("# pooled conns before the NAT/server side does.") + } +} + +// --------------------------------------------------------------- +// Emission helpers +// --------------------------------------------------------------- + +// emitf prints a plain event line (no t= timestamp). Used for the +// opening line and the summary. +func (s *traceSession) emitf(format string, args ...any) { + s.logger.Debugf(tracePrefix+format, args...) +} + +// emitRaw is like emitf but takes an already-rendered string. Used +// by finish() which builds its line via strings.Builder. +func (s *traceSession) emitRaw(line string) { + s.logger.Debugf("%s", tracePrefix+line) +} + +// emitTf prints a phase event with a cumulative t=... offset from +// the session start. +func (s *traceSession) emitTf(format string, args ...any) { + t := round(time.Since(s.start)) + msg := fmt.Sprintf(format, args...) + s.logger.Debugf(tracePrefix+"%s (t=%s)", msg, t) +} + +// traceRoundUnit is the rounding granularity for >=1ms durations +// rendered in trace output. 100µs keeps lines readable while +// preserving enough resolution to spot millisecond-scale phase +// differences. +const traceRoundUnit = 100 * time.Microsecond + +// round trims durations for human-readable trace output. +// Sub-millisecond durations round to 1µs (preserves visibility on +// fast loopback servers); >=1ms durations round to [traceRoundUnit]. +func round(d time.Duration) time.Duration { + if d <= 0 { + return 0 + } + if d < time.Millisecond { + return d.Round(time.Microsecond) + } + return d.Round(traceRoundUnit) +} + +// --------------------------------------------------------------- +// TLS rendering helpers +// --------------------------------------------------------------- + +func tlsVersionName(v uint16) string { + switch v { + case tls.VersionTLS10: + return "1.0" + case tls.VersionTLS11: + return "1.1" + case tls.VersionTLS12: + return "1.2" + case tls.VersionTLS13: + return "1.3" + default: + return fmt.Sprintf("0x%04x", v) + } +} + +// certExpiryFragment renders ", expires=YYYY-MM-DD" for the leaf +// cert when available, or an empty string otherwise. +func certExpiryFragment(state tls.ConnectionState) string { + if len(state.PeerCertificates) == 0 { + return "" + } + return ", expires=" + state.PeerCertificates[0].NotAfter.UTC().Format("2006-01-02") +} diff --git a/vendor/github.com/go-openapi/runtime/client/httptrace_tls.go b/vendor/github.com/go-openapi/runtime/client/httptrace_tls.go new file mode 100644 index 00000000000..063fb259272 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/client/httptrace_tls.go @@ -0,0 +1,353 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package client + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "net/http" + "strings" + "time" +) + +// TLS alert codes used by the diagnostic to classify handshake +// failures. The crypto/tls package does not export named constants +// for individual alerts, so we declare the ones we care about. +// Values are from RFC 8446 §6 (the TLS 1.3 alert protocol; the +// numbering is shared with earlier TLS versions for these alerts). +// +// The `err`-prefixed names satisfy the errname linter — tls.AlertError +// implements error, so these are sentinel errors. +const ( + errTLSAlertHandshakeFailure tls.AlertError = 40 + errTLSAlertProtocolVersion tls.AlertError = 70 +) + +// introspectTLSConfig returns the *tls.Config of the http.Transport +// that will run a request, when reachable, or nil otherwise. +// +// Reachable means the client's Transport is an *http.Transport +// (the default and most common case). Custom transports — wrappers +// around the default, or entirely user-provided — break introspection; +// the TLS diagnostic falls back to "configured: not introspectable" +// in that case. +// +// A nil client (zero value) or nil Transport falls through to +// [http.DefaultTransport], whose TLSClientConfig is also nil; the +// function returns nil and the diagnostic reports defaults. +func introspectTLSConfig(client *http.Client) *tls.Config { + if client == nil { + return nil + } + transport := client.Transport + if transport == nil { + transport = http.DefaultTransport + } + t, ok := transport.(*http.Transport) + if !ok { + return nil + } + return t.TLSClientConfig +} + +// emitTLSDiagnostic renders the failure-mode TLS diagnostic block. +// Called from [traceSession.onTLSHandshakeDone] when err != nil. +// +// The block covers three axes (per the plan): +// +// 1. Protocol-version negotiation — detected from +// [errTLSAlertProtocolVersion] or a "protocol version" substring. +// 2. Cipher-suite negotiation — detected from +// [errTLSAlertHandshakeFailure] when the user pinned CipherSuites. +// 3. Certificate-chain validity — detected from +// [x509.CertificateInvalidError], [x509.UnknownAuthorityError] +// or [x509.HostnameError]. +// +// When none of the specific axes match, a generic fallback emits +// the raw error and whatever inspectable config the session holds. +func (s *traceSession) emitTLSDiagnostic(state tls.ConnectionState, err error) { + s.emitf("# TLS DIAGNOSTIC") + + // tlsAxisGeneric is handled by the default branch. + switch axis := classifyTLSError(err); axis { + case tlsAxisProtocolVersion: + s.diagnoseProtocolVersion(state, err) + case tlsAxisCipher: + s.diagnoseCipher(err) + case tlsAxisCertChain: + s.diagnoseCertChain(err) + default: + s.diagnoseTLSGeneric(err) + } +} + +// tlsAxis is the diagnostic dimension a TLS handshake error maps +// to. Axes are mutually exclusive at classification time. +type tlsAxis int + +const ( + tlsAxisGeneric tlsAxis = iota + tlsAxisProtocolVersion + tlsAxisCipher + tlsAxisCertChain +) + +// classifyTLSError maps a TLS handshake error to one of the +// diagnostic axes. The ordering matters: cert-chain errors win +// over the generic handshake_failure alert because the alert is +// what the server sends back, but the local error type carries +// the more specific reason. +func classifyTLSError(err error) tlsAxis { + if err == nil { + return tlsAxisGeneric + } + + // Cert-chain errors are the most specific local diagnostic + // and should be reported even if a generic alert is also + // present in the chain. + var certInvalid x509.CertificateInvalidError + if errors.As(err, &certInvalid) { + return tlsAxisCertChain + } + var unknownAuth x509.UnknownAuthorityError + if errors.As(err, &unknownAuth) { + return tlsAxisCertChain + } + var hostnameErr x509.HostnameError + if errors.As(err, &hostnameErr) { + return tlsAxisCertChain + } + + // TLS alert classification. + var alert tls.AlertError + if errors.As(err, &alert) { + switch alert { + case errTLSAlertProtocolVersion: + return tlsAxisProtocolVersion + case errTLSAlertHandshakeFailure: + return tlsAxisCipher + } + } + + // Fall back on substring detection for protocol-version + // failures that arrive via the local error path rather than + // a server-side alert (e.g. when the client refuses the + // server's offered version). + msg := err.Error() + if strings.Contains(msg, "protocol version") || strings.Contains(msg, "unsupported protocol") { + return tlsAxisProtocolVersion + } + + return tlsAxisGeneric +} + +// --------------------------------------------------------------- +// Axis renderers +// --------------------------------------------------------------- + +func (s *traceSession) diagnoseProtocolVersion(state tls.ConnectionState, err error) { + s.emitf("# axis: protocol-version") + s.emitf("# error: %v", err) + + configuredMin, configuredMax := configuredVersionRange(s.tlsCfg) + s.emitf("# client offered: TLS %s — TLS %s", + tlsVersionName(configuredMin), tlsVersionName(configuredMax)) + + if state.Version != 0 { + s.emitf("# negotiated up to: TLS %s", tlsVersionName(state.Version)) + } + s.emitf("# suggested: widen TLSClientOptions.MinVersion/MaxVersion,") + s.emitf("# or pin to a version the server speaks.") +} + +func (s *traceSession) diagnoseCipher(err error) { + s.emitf("# axis: cipher-suite") + s.emitf("# error: %v", err) + + if s.tlsCfg != nil && len(s.tlsCfg.CipherSuites) > 0 { + s.emitf("# client configured: [%s]", + strings.Join(cipherSuiteNames(s.tlsCfg.CipherSuites), ", ")) + s.emitf("# server set: not exposed by Go stdlib") + s.emitf("# (capture with: openssl s_client -cipher ALL)") + s.emitf("# suggested: drop the explicit CipherSuites restriction,") + s.emitf("# or align it with the server's policy.") + return + } + // No client-side restriction. The handshake_failure alert + // is generic; without more info we can only surface the + // fact and suggest investigation. + s.emitf("# client configured: defaults (no CipherSuites restriction)") + s.emitf("# note: alert 40 is generic; the server may have rejected") + s.emitf("# the handshake for a non-cipher reason. Try") + s.emitf("# openssl s_client to capture details.") +} + +func (s *traceSession) diagnoseCertChain(err error) { + s.emitf("# axis: cert-chain") + + var certInvalid x509.CertificateInvalidError + if errors.As(err, &certInvalid) { + s.diagnoseCertInvalid(certInvalid) + return + } + + var unknownAuth x509.UnknownAuthorityError + if errors.As(err, &unknownAuth) { + s.diagnoseUnknownAuthority(unknownAuth) + return + } + + var hostnameErr x509.HostnameError + if errors.As(err, &hostnameErr) { + s.diagnoseHostnameMismatch(hostnameErr) + return + } + + // Defensive: should not happen — classifyTLSError already + // matched one of the three. + s.emitf("# error: %v", err) +} + +func (s *traceSession) diagnoseCertInvalid(certInvalid x509.CertificateInvalidError) { + cert := certInvalid.Cert + s.emitf("# reason: %s", certInvalidReasonName(certInvalid.Reason)) + + switch certInvalid.Reason { + case x509.Expired: + s.emitf("# leaf: subject=%s", cert.Subject) + s.emitf("# NotBefore=%s", cert.NotBefore.UTC().Format(time.RFC3339)) + s.emitf("# NotAfter=%s", cert.NotAfter.UTC().Format(time.RFC3339)) + s.emitf("# now=%s", time.Now().UTC().Format(time.RFC3339)) + delta := time.Since(cert.NotAfter).Round(time.Hour) + s.emitf("# expired %s ago", delta) + s.emitf("# suggested: renew the server cert.") + case x509.NameMismatch, x509.CANotAuthorizedForThisName: + s.emitf("# leaf: subject=%s", cert.Subject) + s.emitf("# DNS SANs=%v", cert.DNSNames) + s.emitf("# suggested: set TLSClientOptions.ServerName to match") + s.emitf("# one of the cert SANs, or fix the cert.") + default: + // Less-common reasons render via the default branch (issuer + NotAfter dump). + s.emitf("# leaf: subject=%s, issuer=%s", cert.Subject, cert.Issuer) + s.emitf("# NotBefore=%s", cert.NotBefore.UTC().Format(time.RFC3339)) + s.emitf("# NotAfter=%s", cert.NotAfter.UTC().Format(time.RFC3339)) + s.emitf("# error: %v", certInvalid) + } +} + +func (s *traceSession) diagnoseUnknownAuthority(unknownAuth x509.UnknownAuthorityError) { + s.emitf("# reason: chain root not in trust store (unknown-CA)") + if cert := unknownAuth.Cert; cert != nil { + s.emitf("# offending: subject=%s", cert.Subject) + s.emitf("# issuer=%s", cert.Issuer) + s.emitf("# NotAfter=%s", cert.NotAfter.UTC().Format(time.RFC3339)) + } + + trust := "SystemCertPool" + if s.tlsCfg != nil && s.tlsCfg.RootCAs != nil { + trust = "TLSClientOptions.CA (custom RootCAs)" + } + s.emitf("# trust store in use: %s", trust) + + s.emitf("# suggested: set TLSClientOptions.CA to a bundle that") + s.emitf("# includes the issuing CA, or add it to the") + s.emitf("# OS trust store.") +} + +func (s *traceSession) diagnoseHostnameMismatch(hostnameErr x509.HostnameError) { + s.emitf("# reason: hostname mismatch") + s.emitf("# dialed: %s", hostnameErr.Host) + if cert := hostnameErr.Certificate; cert != nil { + s.emitf("# leaf: subject=%s", cert.Subject) + s.emitf("# DNS SANs=%v", cert.DNSNames) + s.emitf("# IP SANs=%v", cert.IPAddresses) + } + if s.tlsCfg != nil && s.tlsCfg.ServerName != "" { + s.emitf("# TLSClientOptions.ServerName=%q", s.tlsCfg.ServerName) + } + s.emitf("# suggested: dial the hostname listed in the cert SANs,") + s.emitf("# or set TLSClientOptions.ServerName to match.") +} + +func (s *traceSession) diagnoseTLSGeneric(err error) { + s.emitf("# axis: unclassified") + s.emitf("# error: %v", err) + if s.tlsCfg != nil { + minV, maxV := configuredVersionRange(s.tlsCfg) + s.emitf("# configured: MinVersion=TLS %s, MaxVersion=TLS %s", + tlsVersionName(minV), tlsVersionName(maxV)) + if s.tlsCfg.InsecureSkipVerify { + s.emitf("# note: TLSClientOptions.InsecureSkipVerify=true — yet") + s.emitf("# a TLS error still surfaced. Something deeper than") + s.emitf("# certificate verification is failing.") + } + } +} + +// --------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------- + +// configuredVersionRange returns the effective (Min, Max) TLS +// version range a client config negotiates. Zero values in the +// stdlib config mean "use Go default", which is TLS 1.2 .. 1.3 in +// modern Go. We materialize those defaults for display. +func configuredVersionRange(cfg *tls.Config) (uint16, uint16) { + const ( + defaultMin = tls.VersionTLS12 + defaultMax = tls.VersionTLS13 + ) + if cfg == nil { + return defaultMin, defaultMax + } + minV := cfg.MinVersion + if minV == 0 { + minV = defaultMin + } + maxV := cfg.MaxVersion + if maxV == 0 { + maxV = defaultMax + } + return minV, maxV +} + +func cipherSuiteNames(ids []uint16) []string { + out := make([]string, 0, len(ids)) + for _, id := range ids { + out = append(out, tls.CipherSuiteName(id)) + } + return out +} + +// certInvalidReasonName renders an x509.InvalidReason as a short +// human-readable label. The stdlib does not expose a String() +// method for these, so we keep a small table. +// +// Anything outside the listed cases falls through to the numeric default. +func certInvalidReasonName(r x509.InvalidReason) string { + switch r { + case x509.NotAuthorizedToSign: + return "not-authorized-to-sign" + case x509.Expired: + return "expired" + case x509.CANotAuthorizedForThisName: + return "ca-not-authorized-for-this-name" + case x509.TooManyIntermediates: + return "too-many-intermediates" + case x509.IncompatibleUsage: + return "incompatible-usage" + case x509.NameMismatch: + return "name-mismatch" + case x509.NameConstraintsWithoutSANs: + return "name-constraints-without-sans" + case x509.TooManyConstraints: + return "too-many-constraints" + case x509.CANotAuthorizedForExtKeyUsage: + return "ca-not-authorized-for-ext-key-usage" + default: + return fmt.Sprintf("invalid-reason-%d", r) + } +} diff --git a/vendor/github.com/go-openapi/runtime/client/internal/request/request.go b/vendor/github.com/go-openapi/runtime/client/internal/request/request.go new file mode 100644 index 00000000000..22d3f64c01b --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/client/internal/request/request.go @@ -0,0 +1,945 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package request + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "log" + "mime" + "mime/multipart" + "net/http" + "net/textproto" + "net/url" + "os" + "path" + "path/filepath" + "strings" + "time" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +var _ runtime.ClientRequest = new(Request) // ensure compliance to the interface + +// Request represents a swagger client request. +// It binds parameters to a HTTP request. +// +// The main purpose of this struct is to hide the machinery of adding OpenAPI v2 parameters to a transport request. +// +// A generated client only implements what is necessary to turn a parameter into a valid value for these methods. +// +// There is no parameter validation here, it is assumed to be used after a spec has been validated. +// +// # Request binding +// +// The binding of parameters is carried out by method [Request.BuildHTTPContext]. +// +// It analyzes parameters, which may come in different flavors: +// +// - a file or multipart form containing a file +// - a body which is a [io.Reader] +// - a buffered body (regular schema body, including urlencoded form) +// +// In all cases, we may also have query or path parameters encoded in the URL, or header parameters. +// +// The result is a [http.Request], with the following properties: +// +// - file, multipart form or [io.Reader] body: a streaming request with an attached go routine that consumes the [io.Reader]. +// - buffered body: a simple request +// +// The caller passes the parent [context.Context] to [Request.BuildHTTPContext] and receives back a cancel +// function to release the resources held by the derived request context once the response is consumed. +// +// # Authentication +// +// Authentication is built in the request by using a [runtime.ClientAuthInfoWriter]. +// This helper may need to inspect the body of the request before sending authentication info. +// To cover that case, streaming bodies use a copy of the body [io.Reader] for the [runtime.ClientAuthInfoWriter] +// to consume if it wants to. +// +// # Content negotiation +// +// The [Request] detects `multipart/form-data` to switch to streamed request. +// +// `application/x-www-form-urlencoded` is also honored, even for file parameters, which are not streamed in this case. +// File parameters default behavior is `multipart/form-data`. +// +// The natural way to define the `Content-Type` header is to use the `contentType` parameter to switch to the map of +// available body producers. +// +// For buffered requests, this setting override any `Content-Type` header possibly set by calling [Request.SetHeaderParam]. +// +// For streamed requests, users may want more flexibility, as we enter custom territory, with use-cases not supported by OpenAPI v2. +// +// The `Content-Type` header of a streamed request is defined using the following sequence: +// +// 1. if the caller sets an explicit value already in header — the user set it via +// [Request.SetHeaderParam] during WriteToRequest, and we treat that as an intentional escape hatch +// 2. use payload's [runtime.ContentTyper] declaration (in this case, the produced payload knows its content type) +// 3. use `application/octet-stream` if it is available in the registered producers +// 4. otherwise set the picker's mediaType +// +// For multi-part requests, the content type of each part is auto-detected using the following sequence: +// +// 1. use [runtime.ContentTyper] declaration (in this case, the file payload knows its content type) +// 2. use [http.DetectContentType] on the first 512 bytes of the file +// +// # Concurrency +// +// A [Request] is a disposable object that is NOT intended to be reused or called concurrently. +// +// # Future evolutions +// +// There might be other similar structs that convert to other transports. +type Request struct { + pathPattern string + method string + writer runtime.ClientRequestWriter + + pathParams map[string]string + header http.Header + query url.Values + formFields url.Values + fileFields map[string][]runtime.NamedReadCloser + payload any + // consumes carries the operation's full ConsumesMediaTypes list so + // that buildHTTP — which runs after the writer populates the payload + // — can apply payload-aware fallback rules (see streamFallbackMime). + // + // This is set by Runtime.createHttpRequest. + consumes []string + timeout time.Duration + buf *bytes.Buffer + + getBody func(r *Request) []byte +} + +// New creates a new http client [Request] to handle OpenAPI v2 parameters. +func New(method, pathPattern string, writer runtime.ClientRequestWriter) *Request { + return &Request{ + pathPattern: pathPattern, + method: method, + writer: writer, + header: make(http.Header), + query: make(url.Values), + timeout: 0, + getBody: getRequestBuffer, + } +} + +// GetMethod yields the method being used. +func (r *Request) GetMethod() string { + return r.method +} + +// GetPath yields the URL path being used. +func (r *Request) GetPath() string { + pth := r.pathPattern + for k, v := range r.pathParams { + pth = strings.ReplaceAll(pth, "{"+k+"}", v) + } + + return pth +} + +// GetBody returns the request body, if any. +// +// For streaming requests, this is a copy of the original [io.Reader]. +func (r *Request) GetBody() []byte { + return r.getBody(r) +} + +// SetHeaderParam adds a header parameter to the request. +// +// The header key is always canonicalized. +// +// - when there is only 1 value provided, it will set it. +// - when there are several values provided, it will add all of those (no overriding). +func (r *Request) SetHeaderParam(name string, values ...string) error { + if r.header == nil { + r.header = make(http.Header) + } + r.header[http.CanonicalHeaderKey(name)] = values + + return nil +} + +// GetHeaderParams returns all headers currently set for the request. +func (r *Request) GetHeaderParams() http.Header { + return r.header +} + +// SetQueryParam adds a query parameter to the request. +// +// - when there is only 1 value provided, it will set it. +// - when there are several values provided, it will add all of those (no overriding). +func (r *Request) SetQueryParam(name string, values ...string) error { + if r.query == nil { + r.query = make(url.Values) + } + r.query[name] = values + + return nil +} + +// GetQueryParams returns a copy of all query params currently set for the request. +func (r *Request) GetQueryParams() url.Values { + result := make(url.Values, len(r.query)) + for key, values := range r.query { + result[key] = append([]string{}, values...) + } + + return result +} + +// SetFormParam adds a form param to the request. +// +// - when there is only 1 value provided, it will set it. +// - when there are several values provided, it will add all of those (no overriding). +func (r *Request) SetFormParam(name string, values ...string) error { + if r.formFields == nil { + r.formFields = make(url.Values) + } + r.formFields[name] = values + + return nil +} + +// SetPathParam adds a path param to the request. +func (r *Request) SetPathParam(name string, value string) error { + if r.pathParams == nil { + r.pathParams = make(map[string]string) + } + + r.pathParams[name] = value + + return nil +} + +// SetFileParam adds a file parameter to the request. +// +// Files must implement [runtime.NamedReadCloser]. +// +// [runtime.File] is proposed as the default concrete implementation. +func (r *Request) SetFileParam(name string, files ...runtime.NamedReadCloser) error { + for _, file := range files { + if actualFile, ok := file.(*os.File); ok { + fi, err := os.Stat(actualFile.Name()) + if err != nil { + return err + } + + if fi.IsDir() { + return fmt.Errorf("%q is a directory, only files are supported", file.Name()) + } + } + } + + if r.fileFields == nil { + r.fileFields = make(map[string][]runtime.NamedReadCloser) + } + + if r.formFields == nil { + r.formFields = make(url.Values) + } + + r.fileFields[name] = files + + return nil +} + +// GetFileParam yields all file parameters. +func (r *Request) GetFileParam() map[string][]runtime.NamedReadCloser { + return r.fileFields +} + +// SetBodyParam sets a body parameter on the request. +// +// This does not yet serialize the object: actual serialization happens as late as possible. +func (r *Request) SetBodyParam(payload any) error { + r.payload = payload + + return nil +} + +// GetBodyParam returns the body payload. +func (r *Request) GetBodyParam() any { + return r.payload +} + +// GetTimeout sets the timeout for a request. +func (r *Request) GetTimeout() time.Duration { + return r.timeout +} + +// SetTimeout sets the timeout for a request. +func (r *Request) SetTimeout(timeout time.Duration) error { + r.timeout = timeout + + return nil +} + +// SetConsumes sets the list of registered consumed content for a request. +func (r *Request) SetConsumes(consumers []string) { + r.consumes = consumers +} + +// BuildHTTPContext binds the request parameters and returns a ready-to-send [http.Request]. +// +// Dispatch picks one of two end-to-end builders based on whether: +// +// - the body source is a stream (multipart pipe or stream payload) +// - or a buffer (urlencoded form, producer output, or no body) +// +// It starts by writing the request, then proceed with adding authentication, +// then finally assembling URL or header parameters. +// +// The split mirrors the auth question: streaming bodies require a lazy body-copy closure during [AuthenticateRequest], +// whereas buffered bodies do not. +// +// The returned [http.Request] carries a context derived from parentCtx that: +// +// - inherits any deadline or cancellation already set on parentCtx; +// - additionally honors the per-request timeout set via [Request.SetTimeout] +// (the [runtime.ClientRequestWriter] may override the runtime default during +// WriteToRequest, which is why the derivation happens here rather than +// at the call site). +// +// The returned cancel must be invoked by the caller (typically deferred) +// once the response has been fully read; otherwise resources held by the +// derived context — including any timeout timer — are leaked. +// +// On error the cancel is invoked internally and a no-op cancel is returned, +// so callers can defer cancel unconditionally. +func (r *Request) BuildHTTPContext(parentCtx context.Context, mediaType, basePath string, + producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter, +) (*http.Request, context.CancelFunc, error) { + if err := r.writer.WriteToRequest(r, registry); err != nil { + return nil, noop, err + } + + ctx, cancel := deriveRequestContext(parentCtx, r.timeout) + r.buf = bytes.NewBuffer(nil) + + var ( + httpReq *http.Request + err error + ) + if r.usesStreamingBody(mediaType) { + httpReq, err = r.buildStreamingRequest(ctx, mediaType, basePath, producers, registry, auth) + } else { + httpReq, err = r.buildBufferedRequest(ctx, mediaType, basePath, producers, registry, auth) + } + if err != nil { + cancel() + return nil, noop, err + } + return httpReq, cancel, nil +} + +func noop() {} + +// deriveRequestContext returns a child of parent bounded by timeout. +// If timeout == 0 the child is only canceled when the caller invokes +// cancel; any deadline already on parent is preserved. If timeout > 0 +// the child uses the shortest of timeout and parent's existing deadline. +func deriveRequestContext(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc) { + if timeout == 0 { + return context.WithCancel(parent) + } + return context.WithTimeout(parent, timeout) +} + +// usesStreamingBody reports whether the request body must be assembled +// as a stream (an io.Pipe for multipart, or the payload's own reader +// for stream payloads). +// +// The complementary case is a fully buffered body in r.buf — urlencoded form, producer output, or no body at all. +func (r *Request) usesStreamingBody(mediaType string) bool { + if (len(r.formFields) > 0 || len(r.fileFields) > 0) && r.isMultipart(mediaType) { + return true + } + + if r.payload != nil { + if _, ok := r.payload.(io.Reader); ok { + return true + } + } + + return false +} + +func (r *Request) isMultipart(mediaType string) bool { + // Strip media-type parameters before comparing: callers may legally + // pass `multipart/form-data; boundary=…` or + // `application/x-www-form-urlencoded; charset=utf-8` per RFC 7231, + // and a bare-string compare would route those to the wrong flow. + // + // mime.ParseMediaType lowercases the type/subtype and is + // case-insensitive on input, so plain == against our (lowercase) + // constants is sufficient on the happy path. + base, _, err := mime.ParseMediaType(mediaType) + if err != nil { + // Malformed mediaType: only the file-presence shortcut can + // fire — by definition we cannot recognize either canonical + // form mime in unparseable input. + return len(r.fileFields) > 0 + } + + // An explicit application/x-www-form-urlencoded choice is honored even when + // file fields are present: the spec allows files to travel as URL-encoded + // form values, although it does not stream and is discouraged. Without this + // short-circuit, picking urlencoded with files would silently fall back to + // multipart and emit an inconsistent Content-Type. + if base == runtime.URLencodedFormMime { + return false + } + + if len(r.fileFields) > 0 { + return true + } + + return base == runtime.MultipartFormMime +} + +// buildBufferedRequest assembles a request whose body is fully +// buffered in r.buf before AuthenticateRequest runs — urlencoded form, +// producer-serialized payload, or no body. +// +// Auth is trivial in this flow because the buffer is already populated when the auth helper +// asks for the body via r.GetBody(). +func (r *Request) buildBufferedRequest(ctx context.Context, mediaType, basePath string, + producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter, +) (*http.Request, error) { + var body io.Reader + var err error + + switch { + case len(r.formFields) > 0 || len(r.fileFields) > 0: + body, err = r.writeURLEncodedBody(mediaType) + case r.payload != nil: + body, err = r.writeNonStreamPayload(mediaType, producers) + } + if err != nil { + return nil, err + } + + if runtime.CanHaveBody(r.method) && body != nil && r.header.Get(runtime.HeaderContentType) == "" { + r.header.Set(runtime.HeaderContentType, mediaType) + } + + if auth != nil { + if err := auth.AuthenticateRequest(r, registry); err != nil { + return nil, err + } + } + + return r.assembleRequest(ctx, basePath, body) +} + +// buildStreamingRequest assembles a request whose body is a stream — +// either an io.Pipe filled by the multipart goroutine, or the +// payload's own io.Reader. +// +// AuthenticateRequest consumes the body lazily through the getBody closure installed by +// applyAuthWithBodyCopy, which buffers the stream into r.buf so the http.Request can use the buffered copy. +// +// On any error path before the http.Request takes ownership of body, we close the body to release +// the underlying resource. +// +// For multipart this unblocks the spawned writer goroutine +// (it would otherwise park forever on pw.Write with no reader). +// +// For stream payloads it closes the user-provided io.ReadCloser. +func (r *Request) buildStreamingRequest(ctx context.Context, mediaType, basePath string, + producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter, +) (req *http.Request, retErr error) { + var body io.Reader + if len(r.formFields) > 0 || len(r.fileFields) > 0 { + body = r.writeMultipartBody(ctx, mediaType) + } else { + body = r.writeStreamPayload(mediaType, producers) + } + + defer func() { + if retErr == nil { + return + } + if c, ok := body.(io.Closer); ok { + _ = c.Close() + } + }() + + if runtime.CanHaveBody(r.method) && body != nil && r.header.Get(runtime.HeaderContentType) == "" { + r.header.Set(runtime.HeaderContentType, mediaType) + } + + body, err := r.applyAuthWithBodyCopy(auth, body, registry) + if err != nil { + return nil, err + } + + return r.assembleRequest(ctx, basePath, body) +} + +// assembleRequest is the shared tail of both flows: build the URL +// path, create the http.Request, merge static query parameters, and +// finalize headers/query. +func (r *Request) assembleRequest(ctx context.Context, basePath string, body io.Reader) (*http.Request, error) { + urlPath, staticQueryParams, err := r.resolveURLPath(basePath) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, r.method, urlPath, body) + if err != nil { + return nil, err + } + + if err := r.mergeStaticQuery(staticQueryParams); err != nil { + return nil, err + } + + req.URL.RawQuery = r.query.Encode() + req.Header = r.header + + return req, nil +} + +// resolveURLPath builds the final url path string and returns the static +// query parameters extracted from basePath and r.pathPattern. +// +// Static query parameters from the path pattern take precedence over those +// from the base path; merging with r.query is the caller's responsibility +// (see [request.mergeStaticQuery]). +// +// The path is assembled from basePath + pathPattern with path-param +// substitution and trailing-slash preservation when the original +// pathPattern carried one. +func (r *Request) resolveURLPath(basePath string) (string, url.Values, error) { + basePathURL, err := url.Parse(basePath) + if err != nil { + return "", nil, err + } + staticQueryParams := basePathURL.Query() + + pathPatternURL, err := url.Parse(r.pathPattern) + if err != nil { + return "", nil, err + } + for name, values := range pathPatternURL.Query() { + if _, present := staticQueryParams[name]; present { + staticQueryParams.Del(name) + } + for _, value := range values { + staticQueryParams.Add(name, value) + } + } + + // path.Join strips trailing slashes; reinstate one whenever the + // pathPattern carried it, including the bare-root case ("/" under a + // non-empty basePath, which path.Join would collapse to "/basepath"). + // The HasSuffix check on urlPath keeps the rewrite idempotent and + // avoids producing "//" when basePath is "/" or empty. + reinstateSlash := strings.HasSuffix(pathPatternURL.Path, "/") + + urlPath := path.Join(basePathURL.Path, pathPatternURL.Path) + for k, v := range r.pathParams { + urlPath = strings.ReplaceAll(urlPath, "{"+k+"}", url.PathEscape(v)) + } + if reinstateSlash && !strings.HasSuffix(urlPath, "/") { + urlPath += "/" + } + + return urlPath, staticQueryParams, nil +} + +// applyAuthWithBodyCopy runs auth.AuthenticateRequest for the +// streaming flow, where the http.Request body is a pipe or a payload +// reader rather than r.buf. If AuthenticateRequest asks for the body +// via r.GetBody(), the lazy closure copies the stream into r.buf on +// demand and reassigns body to r.buf so the post-auth source passed +// to http.NewRequestWithContext is the buffered copy. +// +// The closure is registered lazily because there is no way to know +// ahead of time whether AuthenticateRequest will read the body. +// +// On error precedence: a copy error is reported in preference to the +// AuthenticateRequest error, because a mis-read body may have +// interfered with auth. +// +// No-op when auth is nil; returns body unchanged. +func (r *Request) applyAuthWithBodyCopy(auth runtime.ClientAuthInfoWriter, body io.Reader, registry strfmt.Registry) (io.Reader, error) { + if auth == nil { + return body, nil + } + + var copyErr error + var copied bool + r.getBody = func(r *Request) []byte { + if copied { + return getRequestBuffer(r) + } + + defer func() { + copied = true + }() + + if _, copyErr = io.Copy(r.buf, body); copyErr != nil { + return nil + } + + if closer, ok := body.(io.ReadCloser); ok { + if copyErr = closer.Close(); copyErr != nil { + return nil + } + } + + body = r.buf + return getRequestBuffer(r) + } + + authErr := auth.AuthenticateRequest(r, registry) + + // On error we return body alongside the error so the caller's + // cleanup defer (in buildStreamingRequest) can close the + // underlying pipe/stream. Caller treats body as ignorable when + // err != nil per Go convention; the defer reads it via closure. + if copyErr != nil { + return body, fmt.Errorf("error copying the request body: %w", copyErr) + } + + if authErr != nil { + return body, authErr + } + + return body, nil +} + +// mergeStaticQuery overlays staticQuery onto r.query. On conflict r.query +// wins — the parameters set by the client take precedence over the ones +// extracted from basePath / pathPattern. +func (r *Request) mergeStaticQuery(staticQuery url.Values) error { + originalParams := r.GetQueryParams() + for k, v := range staticQuery { + if _, present := originalParams[k]; present { + continue + } + if err := r.SetQueryParam(k, v...); err != nil { + return err + } + } + return nil +} + +// writeURLEncodedBody serializes form fields (and any file fields, per +// Swagger 2.0 fallback semantics) into r.buf as +// application/x-www-form-urlencoded. Sets Content-Type to mediaType and +// returns r.buf as the body source. +// +// Per Swagger 2.0, file form parameters can be sent under +// application/x-www-form-urlencoded by including the file content as a +// regular form-field value. The whole form is then percent-encoded as +// usual. This buffers the entire payload and does not preserve a +// per-file Content-Type — multipart/form-data is preferred when both +// are advertised by the operation. +func (r *Request) writeURLEncodedBody(mediaType string) (io.Reader, error) { + r.header.Set(runtime.HeaderContentType, mediaType) + values := url.Values{} + for k, vs := range r.formFields { + values[k] = append(values[k], vs...) + } + for fn, ff := range r.fileFields { + for _, fi := range ff { + data, ferr := io.ReadAll(fi) + if cerr := fi.Close(); cerr != nil && ferr == nil { + ferr = cerr + } + if ferr != nil { + return nil, ferr + } + values.Add(fn, string(data)) + } + } + r.buf.WriteString(values.Encode()) + return r.buf, nil +} + +// writeMultipartBody assembles a multipart/form-data body via an +// io.Pipe. A goroutine streams form fields and files into the pipe +// writer; the pipe reader is returned as the body. Sets Content-Type to +// the multipart media type with the writer's boundary parameter. +// +// The goroutine owns the pipe writer's lifecycle: it closes the +// multipart writer (flushing the closing boundary) and the pipe writer +// when it finishes or hits an error. +func (r *Request) writeMultipartBody(ctx context.Context, mediaType string) io.Reader { + pr, pw := io.Pipe() + mp := multipart.NewWriter(pw) + r.header.Set(runtime.HeaderContentType, mangleContentType(mediaType, mp.Boundary())) + + go r.streamMultipartParts(ctx, mp, pw) + + return pr +} + +// streamMultipartParts writes form fields then file fields to mp, +// closing mp and pw when done. +// +// Errors are reported by closing pw with the error so the consumer of pr observes them on its next Read. +// +// Context cancellation is observed at iteration boundaries (between +// fields and between files) and during file copy via a context-aware +// reader. When ctx is canceled the pipe writer is closed with ctx.Err() +// so the body consumer surfaces the cancellation as the read error. +func (r *Request) streamMultipartParts(ctx context.Context, mp *multipart.Writer, pw *io.PipeWriter) { + defer func() { + mp.Close() + pw.Close() + }() + + for fn, v := range r.formFields { + for _, vi := range v { + if err := ctx.Err(); err != nil { + _ = pw.CloseWithError(err) + return + } + if err := mp.WriteField(fn, vi); err != nil { + logClose(err, pw) + return + } + } + } + + defer func() { + for _, ff := range r.fileFields { + for _, ffi := range ff { + ffi.Close() + } + } + }() + + for fn, f := range r.fileFields { + for _, fi := range f { + if err := ctx.Err(); err != nil { + _ = pw.CloseWithError(err) + return + } + + var fileContentType string + if p, ok := fi.(runtime.ContentTyper); ok { + fileContentType = p.ContentType() + } else { + // Need to read the data so that we can detect the content type + const contentTypeBufferSize = 512 + buf := make([]byte, contentTypeBufferSize) + size, err := fi.Read(buf) + if err != nil && !errors.Is(err, io.EOF) { + logClose(err, pw) + return + } + fileContentType = http.DetectContentType(buf) + fi = runtime.NamedReader(fi.Name(), io.MultiReader(bytes.NewReader(buf[:size]), fi)) + } + + // Create the MIME headers for the new part + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", + fmt.Sprintf(`form-data; name="%s"; filename="%s"`, + escapeQuotes(fn), escapeQuotes(filepath.Base(fi.Name())))) + h.Set("Content-Type", fileContentType) + + wrtr, err := mp.CreatePart(h) + if err != nil { + logClose(err, pw) + return + } + if _, err := io.Copy(wrtr, &ctxReader{ctx: ctx, r: fi}); err != nil { + logClose(err, pw) + return + } + } + } +} + +// ctxReader wraps an [io.Reader] with a context check on each Read. Once +// ctx is done, subsequent Reads return ctx.Err() instead of delegating +// to the underlying reader. It does not preempt a Read already in flight +// — that is the source's responsibility (e.g. *os.File honors Close from +// another goroutine, network sources honor SetDeadline). +type ctxReader struct { + ctx context.Context //nolint:containedctx // io.Reader's Read method has no ctx parameter, so the wrapper must carry it on the struct + r io.Reader +} + +func (cr *ctxReader) Read(p []byte) (int, error) { + if err := cr.ctx.Err(); err != nil { + return 0, err + } + return cr.r.Read(p) +} + +// writeStreamPayload handles a stream payload (io.Reader / +// io.ReadCloser). The bytes flow through verbatim — no producer is +// invoked. The wire Content-Type is resolved via setStreamContentType +// (priority: existing header, payload's ContentTyper, +// streamFallbackMime, mediaType). +// +// Caller must ensure r.payload satisfies io.Reader (see +// [request.usesStreamingBody]). +func (r *Request) writeStreamPayload(mediaType string, producers map[string]runtime.Producer) io.Reader { + setStreamContentType(r.header, r.payload, mediaType, r.consumes, producers) + if rdr, ok := r.payload.(io.ReadCloser); ok { + return rdr + } + + rdr, ok := r.payload.(io.Reader) + if !ok { + panic("internal error: payload expected to be an io.Reader") // guaranteed by earlier checks + } + + return rdr +} + +// writeNonStreamPayload runs the producer registered for mediaType +// against r.payload, writing into r.buf. The Content-Type header +// reflects the picker. +// +// SetHeaderParam("Content-Type", …) is intentionally NOT honored on +// the producer path because the producer is dispatched off mediaType — +// the wire header would otherwise misrepresent the body. +// +// The same reasoning applies to the form/multipart branch. +func (r *Request) writeNonStreamPayload(mediaType string, producers map[string]runtime.Producer) (io.Reader, error) { + r.header.Set(runtime.HeaderContentType, mediaType) + producer, ok := producers[mediaType] + if !ok { + return nil, fmt.Errorf("no producer registered for content type %q (register one with Runtime.Producers)", mediaType) + } + + if err := producer.Produce(r.buf, r.payload); err != nil { + return nil, err + } + return r.buf, nil +} + +var quoter = strings.NewReplacer( + "\\", "\\\\", + `"`, "\\\"", + "\r", "_", + "\n", "_", +) + +// escapeQuotes escapes backslash and double-quote for embedding in a +// quoted-string Content-Disposition parameter value, and rewrites +// CR / LF to '_' to prevent header-injection through attacker-influenced +// field names or filenames. +// +// RFC 7578 §4.2 limits parameter values to printable characters; this +// is the conservative subset relevant to security (control characters +// that would split the header line into a forged header or part). +// Mirrors the known stdlib gap golang/go#19038. +func escapeQuotes(s string) string { + return quoter.Replace(s) +} + +// setStreamContentType resolves and writes the wire Content-Type for a +// stream payload (io.Reader / io.ReadCloser). Priority: +// +// 1. an explicit value already in header — the user set it via +// SetHeaderParam during [ClientRequestWriter.WriteToRequest], and we treat that as an +// intentional escape hatch; +// 2. payload's [runtime.ContentTyper] declaration; +// 3. [streamFallbackMime] (Stage-2 octet-stream upgrade); +// 4. the picker's mediaType (passed in as the chain's terminal +// fallback). +// +// Does not apply to non-stream payloads or to form/multipart bodies — +// see the comment above the call site in [request.buildHTTP]. +func setStreamContentType( + header http.Header, + payload any, + mediaType string, + candidates []string, + producers map[string]runtime.Producer, +) { + if header.Get(runtime.HeaderContentType) != "" { + return + } + fallback := streamFallbackMime(mediaType, candidates, producers) + header.Set(runtime.HeaderContentType, payloadContentType(payload, fallback)) +} + +// payloadContentType returns the payload's declared content type when +// it implements [runtime.ContentTyper] with a non-empty result, and +// fallback otherwise. Mirrors the per-file convention already used for +// multipart upload parts (see [request.buildHTTP] file-fields branch). +func payloadContentType(payload any, fallback string) string { + if t, ok := payload.(runtime.ContentTyper); ok { + if ct := t.ContentType(); ct != "" { + return ct + } + } + + return fallback +} + +// streamFallbackMime selects a wire content-type for a stream payload +// (io.Reader / io.ReadCloser) that has neither implemented +// `ContentType() string` nor declared an explicit value. +// +// The picker (Stage 1) ran without seeing the payload, so its choice +// may be wildly wrong for raw bytes — e.g. picking application/json +// for a payload that is just a stream of opaque data. When the +// candidate consumes list also offers application/octet-stream and +// the runtime has an octet-stream producer registered, that's a +// safer wire type than the picker's choice: it advertises "raw bytes" +// rather than making a structural claim about the body. +// +// If octet-stream is unavailable in either the candidate list or the +// producer set, the picker's choice is preserved. The wire header +// then continues to misrepresent the body — but no correct +// alternative exists and we cannot infer one without more +// information from the caller. +func streamFallbackMime(picked string, candidates []string, producers map[string]runtime.Producer) string { + if strings.EqualFold(picked, runtime.DefaultMime) { + return picked + } + + for _, c := range candidates { + if strings.EqualFold(c, runtime.DefaultMime) { + if _, ok := producers[runtime.DefaultMime]; ok { + return runtime.DefaultMime + } + } + } + + return picked +} + +func getRequestBuffer(r *Request) []byte { + if r.buf == nil { + return nil + } + return r.buf.Bytes() +} + +func logClose(err error, pw *io.PipeWriter) { + log.Println(err) + closeErr := pw.CloseWithError(err) + if closeErr != nil { + log.Println(closeErr) + } +} + +func mangleContentType(mediaType, boundary string) string { + _ = mediaType // reserved for future enhancement: honor caller-provided media type + // Proposal for enhancement: honor caller's boundary if specified + return "multipart/form-data; boundary=" + boundary +} diff --git a/vendor/github.com/go-openapi/runtime/client/keepalive.go b/vendor/github.com/go-openapi/runtime/client/keepalive.go index 3bac5e272cf..6b6097d206f 100644 --- a/vendor/github.com/go-openapi/runtime/client/keepalive.go +++ b/vendor/github.com/go-openapi/runtime/client/keepalive.go @@ -34,20 +34,20 @@ func (k *keepAliveTransport) RoundTrip(r *http.Request) (*http.Response, error) type drainingReadCloser struct { rdr io.ReadCloser - seenEOF uint32 + seenEOF atomic.Uint32 } func (d *drainingReadCloser) Read(p []byte) (n int, err error) { n, err = d.rdr.Read(p) if err == io.EOF || n == 0 { - atomic.StoreUint32(&d.seenEOF, 1) + d.seenEOF.Store(1) } return } func (d *drainingReadCloser) Close() error { // drain buffer - if atomic.LoadUint32(&d.seenEOF) != 1 { + if d.seenEOF.Load() != 1 { // If the reader side (a HTTP server) is misbehaving, it still may send // some bytes, but the closer ignores them to keep the underling // connection open. diff --git a/vendor/github.com/go-openapi/runtime/client/opentelemetry.go b/vendor/github.com/go-openapi/runtime/client/opentelemetry.go index 5054878c06c..e422f83cb12 100644 --- a/vendor/github.com/go-openapi/runtime/client/opentelemetry.go +++ b/vendor/github.com/go-openapi/runtime/client/opentelemetry.go @@ -4,18 +4,20 @@ package client import ( + "context" "fmt" "net/http" "strings" - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/propagation" semconv "go.opentelemetry.io/otel/semconv/v1.37.0" "go.opentelemetry.io/otel/trace" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" ) const ( @@ -23,6 +25,52 @@ const ( tracerName = "go-openapi" ) +// WithOpenTelemetry adds opentelemetry support to the provided runtime. +// A new client span is created for each request. +// The provided opts are applied to each spans - for example to add global tags. +// +// The returned transport satisfies [runtime.ContextualTransport]: callers +// should prefer [openTelemetryTransport.SubmitContext] over the +// legacy [runtime.ClientOperation.Context] field. Setting that +// field is still honored on the [openTelemetryTransport.Submit] +// compatibility path. +func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOpt) runtime.ContextualTransport { + return newOpenTelemetryTransport(r, r.Host, opts) +} + +// WithOpenTracing adds opentracing support to the provided runtime. +// A new client span is created for each request. +// If the context of the client operation does not contain an active span, no span is created. +// The provided opts are applied to each spans - for example to add global tags. +// +// Deprecated: use [WithOpenTelemetry] instead, as opentracing is now archived and superseded by opentelemetry. +// +// # Deprecation notice +// +// The [Runtime.WithOpenTracing] method has been deprecated in favor of [Runtime.WithOpenTelemetry]. +// +// The method is still around so programs calling it will still build. However, it will return +// an opentelemetry transport. +// +// If you have a strict requirement on using opentracing, you may still do so by importing +// module [github.com/go-openapi/runtime/client-[middleware]/opentracing] and using +// [github.com/go-openapi/runtime/client-[middleware]/opentracing.WithOpenTracing] with your +// usual opentracing options and opentracing-enabled transport. +// +// Passed options are ignored unless they are of type [OpenTelemetryOpt]. +func (r *Runtime) WithOpenTracing(opts ...any) runtime.ContextualTransport { + otelOpts := make([]OpenTelemetryOpt, 0, len(opts)) + for _, o := range opts { + otelOpt, ok := o.(OpenTelemetryOpt) + if !ok { + continue + } + otelOpts = append(otelOpts, otelOpt) + } + + return r.WithOpenTelemetry(otelOpts...) +} + type config struct { Tracer trace.Tracer Propagator propagation.TextMapPropagator @@ -113,11 +161,31 @@ func newOpenTelemetryTransport(transport runtime.ClientTransport, host string, o return tr } +// Submit implements [runtime.ClientTransport]. It honors the legacy +// [runtime.ClientOperation.Context] field for backward compatibility +// — that field is being phased out; new code should call +// [openTelemetryTransport.SubmitContext] directly with an explicit +// context. func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (any, error) { - if op.Context == nil { - return t.transport.Submit(op) + ctx := op.Context + if ctx == nil { + ctx = context.Background() } + return t.SubmitContext(ctx, op) +} +// SubmitContext submits an operation with an explicit context that +// drives both the tracing span and (when supported) the wrapped +// transport's SubmitContext call. The legacy +// [runtime.ClientOperation.Context] field is not consulted. +// +// When the wrapped transport implements [runtime.ContextualTransport], ctx is +// forwarded directly via its SubmitContext. Otherwise, the legacy +// Submit path is used: ctx is stamped onto op.Context for the +// duration of that call and restored afterwards, so the wrapped +// transport still receives a usable context. The legacy fallback +// disappears once SubmitContext is universal (v2). +func (t *openTelemetryTransport) SubmitContext(ctx context.Context, op *runtime.ClientOperation) (any, error) { params := op.Params reader := op.Reader @@ -129,7 +197,7 @@ func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (any, error }() op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error { - span = t.newOpenTelemetrySpan(op, req.GetHeaderParams()) + span = t.newOpenTelemetrySpan(ctx, op, req.GetHeaderParams()) return params.WriteToRequest(req, reg) }) @@ -149,7 +217,7 @@ func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (any, error return reader.ReadResponse(response, consumer) }) - submit, err := t.transport.Submit(op) + submit, err := t.submitWrapped(ctx, op) if err != nil && span != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error()) @@ -158,9 +226,18 @@ func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (any, error return submit, err } -func (t *openTelemetryTransport) newOpenTelemetrySpan(op *runtime.ClientOperation, header http.Header) trace.Span { - ctx := op.Context +//nolint:contextcheck // ctx is forwarded verbatim; the legacy Submit branch only stamps it onto op.Context for the wrapped transport. +func (t *openTelemetryTransport) submitWrapped(ctx context.Context, op *runtime.ClientOperation) (any, error) { + if sc, ok := t.transport.(runtime.ContextualTransport); ok { + return sc.SubmitContext(ctx, op) + } + prev := op.Context + op.Context = ctx + defer func() { op.Context = prev }() + return t.transport.Submit(op) +} +func (t *openTelemetryTransport) newOpenTelemetrySpan(ctx context.Context, op *runtime.ClientOperation, header http.Header) trace.Span { tracer := t.tracer if tracer == nil { if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() { diff --git a/vendor/github.com/go-openapi/runtime/client/request.go b/vendor/github.com/go-openapi/runtime/client/request.go deleted file mode 100644 index f16ee487bab..00000000000 --- a/vendor/github.com/go-openapi/runtime/client/request.go +++ /dev/null @@ -1,468 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -package client - -import ( - "bytes" - "context" - "fmt" - "io" - "log" - "mime/multipart" - "net/http" - "net/textproto" - "net/url" - "os" - "path" - "path/filepath" - "strings" - "time" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" -) - -var _ runtime.ClientRequest = new(request) // ensure compliance to the interface - -// Request represents a swagger client request. -// -// This Request struct converts to a HTTP request. -// There might be others that convert to other transports. -// There is no error checking here, it is assumed to be used after a spec has been validated. -// so impossible combinations should not arise (hopefully). -// -// The main purpose of this struct is to hide the machinery of adding params to a transport request. -// The generated code only implements what is necessary to turn a param into a valid value for these methods. -type request struct { - pathPattern string - method string - writer runtime.ClientRequestWriter - - pathParams map[string]string - header http.Header - query url.Values - formFields url.Values - fileFields map[string][]runtime.NamedReadCloser - payload any - timeout time.Duration - buf *bytes.Buffer - - getBody func(r *request) []byte -} - -// NewRequest creates a new swagger http client request. -func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) *request { - return &request{ - pathPattern: pathPattern, - method: method, - writer: writer, - header: make(http.Header), - query: make(url.Values), - timeout: DefaultTimeout, - getBody: getRequestBuffer, - } -} - -// BuildHTTP creates a new http request based on the data from the params. -func (r *request) BuildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry) (*http.Request, error) { - return r.buildHTTP(mediaType, basePath, producers, registry, nil) -} - -func (r *request) GetMethod() string { - return r.method -} - -func (r *request) GetPath() string { - path := r.pathPattern - for k, v := range r.pathParams { - path = strings.ReplaceAll(path, "{"+k+"}", v) - } - return path -} - -func (r *request) GetBody() []byte { - return r.getBody(r) -} - -// SetHeaderParam adds a header param to the request -// when there is only 1 value provided for the varargs, it will set it. -// when there are several values provided for the varargs it will add it (no overriding). -func (r *request) SetHeaderParam(name string, values ...string) error { - if r.header == nil { - r.header = make(http.Header) - } - r.header[http.CanonicalHeaderKey(name)] = values - return nil -} - -// GetHeaderParams returns the all headers currently set for the request. -func (r *request) GetHeaderParams() http.Header { - return r.header -} - -// SetQueryParam adds a query param to the request -// when there is only 1 value provided for the varargs, it will set it. -// when there are several values provided for the varargs it will add it (no overriding). -func (r *request) SetQueryParam(name string, values ...string) error { - if r.query == nil { - r.query = make(url.Values) - } - r.query[name] = values - return nil -} - -// GetQueryParams returns a copy of all query params currently set for the request. -func (r *request) GetQueryParams() url.Values { - var result = make(url.Values) - for key, value := range r.query { - result[key] = append([]string{}, value...) - } - return result -} - -// SetFormParam adds a forn param to the request -// when there is only 1 value provided for the varargs, it will set it. -// when there are several values provided for the varargs it will add it (no overriding). -func (r *request) SetFormParam(name string, values ...string) error { - if r.formFields == nil { - r.formFields = make(url.Values) - } - r.formFields[name] = values - return nil -} - -// SetPathParam adds a path param to the request. -func (r *request) SetPathParam(name string, value string) error { - if r.pathParams == nil { - r.pathParams = make(map[string]string) - } - - r.pathParams[name] = value - return nil -} - -// SetFileParam adds a file param to the request. -func (r *request) SetFileParam(name string, files ...runtime.NamedReadCloser) error { - for _, file := range files { - if actualFile, ok := file.(*os.File); ok { - fi, err := os.Stat(actualFile.Name()) - if err != nil { - return err - } - if fi.IsDir() { - return fmt.Errorf("%q is a directory, only files are supported", file.Name()) - } - } - } - - if r.fileFields == nil { - r.fileFields = make(map[string][]runtime.NamedReadCloser) - } - if r.formFields == nil { - r.formFields = make(url.Values) - } - - r.fileFields[name] = files - return nil -} - -func (r *request) GetFileParam() map[string][]runtime.NamedReadCloser { - return r.fileFields -} - -// SetBodyParam sets a body parameter on the request. -// This does not yet serialze the object, this happens as late as possible. -func (r *request) SetBodyParam(payload any) error { - r.payload = payload - return nil -} - -func (r *request) GetBodyParam() any { - return r.payload -} - -// SetTimeout sets the timeout for a request. -func (r *request) SetTimeout(timeout time.Duration) error { - r.timeout = timeout - return nil -} - -func (r *request) isMultipart(mediaType string) bool { - if len(r.fileFields) > 0 { - return true - } - - return runtime.MultipartFormMime == mediaType -} - -func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) { //nolint:gocyclo,maintidx - // build the data - if err := r.writer.WriteToRequest(r, registry); err != nil { - return nil, err - } - - // Our body must be an io.Reader. - // When we create the http.Request, if we pass it a - // bytes.Buffer then it will wrap it in an io.ReadCloser - // and set the content length automatically. - var body io.Reader - var pr *io.PipeReader - var pw *io.PipeWriter - - r.buf = bytes.NewBuffer(nil) - if r.payload != nil || len(r.formFields) > 0 || len(r.fileFields) > 0 { - body = r.buf - if r.isMultipart(mediaType) { - pr, pw = io.Pipe() - body = pr - } - } - - // check if this is a form type request - if len(r.formFields) > 0 || len(r.fileFields) > 0 { - if !r.isMultipart(mediaType) { - r.header.Set(runtime.HeaderContentType, mediaType) - formString := r.formFields.Encode() - r.buf.WriteString(formString) - goto DoneChoosingBodySource - } - - mp := multipart.NewWriter(pw) - r.header.Set(runtime.HeaderContentType, mangleContentType(mediaType, mp.Boundary())) - - go func() { - defer func() { - mp.Close() - pw.Close() - }() - - for fn, v := range r.formFields { - for _, vi := range v { - if err := mp.WriteField(fn, vi); err != nil { - logClose(err, pw) - return - } - } - } - - defer func() { - for _, ff := range r.fileFields { - for _, ffi := range ff { - ffi.Close() - } - } - }() - for fn, f := range r.fileFields { - for _, fi := range f { - var fileContentType string - if p, ok := fi.(interface { - ContentType() string - }); ok { - fileContentType = p.ContentType() - } else { - // Need to read the data so that we can detect the content type - const contentTypeBufferSize = 512 - buf := make([]byte, contentTypeBufferSize) - size, err := fi.Read(buf) - if err != nil && err != io.EOF { - logClose(err, pw) - return - } - fileContentType = http.DetectContentType(buf) - fi = runtime.NamedReader(fi.Name(), io.MultiReader(bytes.NewReader(buf[:size]), fi)) - } - - // Create the MIME headers for the new part - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", - fmt.Sprintf(`form-data; name="%s"; filename="%s"`, - escapeQuotes(fn), escapeQuotes(filepath.Base(fi.Name())))) - h.Set("Content-Type", fileContentType) - - wrtr, err := mp.CreatePart(h) - if err != nil { - logClose(err, pw) - return - } - if _, err := io.Copy(wrtr, fi); err != nil { - logClose(err, pw) - } - } - } - }() - - goto DoneChoosingBodySource - } - - // if there is payload, use the producer to write the payload, and then - // set the header to the content-type appropriate for the payload produced - if r.payload != nil { - // Enhancement proposal: https://github.com/go-openapi/runtime/issues/387 - r.header.Set(runtime.HeaderContentType, mediaType) - if rdr, ok := r.payload.(io.ReadCloser); ok { - body = rdr - goto DoneChoosingBodySource - } - - if rdr, ok := r.payload.(io.Reader); ok { - body = rdr - goto DoneChoosingBodySource - } - - producer := producers[mediaType] - if err := producer.Produce(r.buf, r.payload); err != nil { - return nil, err - } - } - -DoneChoosingBodySource: - - if runtime.CanHaveBody(r.method) && body != nil && r.header.Get(runtime.HeaderContentType) == "" { - r.header.Set(runtime.HeaderContentType, mediaType) - } - - if auth != nil { - // If we're not using r.buf as our http.Request's body, - // either the payload is an io.Reader or io.ReadCloser, - // or we're doing a multipart form/file. - // - // In those cases, if the AuthenticateRequest call asks for the body, - // we must read it into a buffer and provide that, then use that buffer - // as the body of our http.Request. - // - // This is done in-line with the GetBody() request rather than ahead - // of time, because there's no way to know if the AuthenticateRequest - // will even ask for the body of the request. - // - // If for some reason the copy fails, there's no way to return that - // error to the GetBody() call, so return it afterwards. - // - // An error from the copy action is prioritized over any error - // from the AuthenticateRequest call, because the mis-read - // body may have interfered with the auth. - // - var copyErr error - if buf, ok := body.(*bytes.Buffer); body != nil && (!ok || buf != r.buf) { - var copied bool - r.getBody = func(r *request) []byte { - if copied { - return getRequestBuffer(r) - } - - defer func() { - copied = true - }() - - if _, copyErr = io.Copy(r.buf, body); copyErr != nil { - return nil - } - - if closer, ok := body.(io.ReadCloser); ok { - if copyErr = closer.Close(); copyErr != nil { - return nil - } - } - - body = r.buf - return getRequestBuffer(r) - } - } - - authErr := auth.AuthenticateRequest(r, registry) - - if copyErr != nil { - return nil, fmt.Errorf("error retrieving the response body: %v", copyErr) - } - - if authErr != nil { - return nil, authErr - } - } - - // In case the basePath or the request pathPattern include static query parameters, - // parse those out before constructing the final path. The parameters themselves - // will be merged with the ones set by the client, with the priority given first to - // the ones set by the client, then the path pattern, and lastly the base path. - basePathURL, err := url.Parse(basePath) - if err != nil { - return nil, err - } - staticQueryParams := basePathURL.Query() - - pathPatternURL, err := url.Parse(r.pathPattern) - if err != nil { - return nil, err - } - for name, values := range pathPatternURL.Query() { - if _, present := staticQueryParams[name]; present { - staticQueryParams.Del(name) - } - for _, value := range values { - staticQueryParams.Add(name, value) - } - } - - // create http request - var reinstateSlash bool - if pathPatternURL.Path != "" && pathPatternURL.Path != "/" && pathPatternURL.Path[len(pathPatternURL.Path)-1] == '/' { - reinstateSlash = true - } - - urlPath := path.Join(basePathURL.Path, pathPatternURL.Path) - for k, v := range r.pathParams { - urlPath = strings.ReplaceAll(urlPath, "{"+k+"}", url.PathEscape(v)) - } - if reinstateSlash { - urlPath += "/" - } - - req, err := http.NewRequestWithContext(context.Background(), r.method, urlPath, body) - if err != nil { - return nil, err - } - - originalParams := r.GetQueryParams() - - // Merge the query parameters extracted from the basePath with the ones set by - // the client in this struct. In case of conflict, the client wins. - for k, v := range staticQueryParams { - _, present := originalParams[k] - if !present { - if err = r.SetQueryParam(k, v...); err != nil { - return nil, err - } - } - } - - req.URL.RawQuery = r.query.Encode() - req.Header = r.header - - return req, nil -} - -func escapeQuotes(s string) string { - return strings.NewReplacer("\\", "\\\\", `"`, "\\\"").Replace(s) -} - -func getRequestBuffer(r *request) []byte { - if r.buf == nil { - return nil - } - return r.buf.Bytes() -} - -func logClose(err error, pw *io.PipeWriter) { - log.Println(err) - closeErr := pw.CloseWithError(err) - if closeErr != nil { - log.Println(closeErr) - } -} - -func mangleContentType(mediaType, boundary string) string { - if strings.ToLower(mediaType) == runtime.URLencodedFormMime { - return fmt.Sprintf("%s; boundary=%s", mediaType, boundary) - } - return "multipart/form-data; boundary=" + boundary -} diff --git a/vendor/github.com/go-openapi/runtime/client/runtime.go b/vendor/github.com/go-openapi/runtime/client/runtime.go index eeb17dfb24e..b890f9f4133 100644 --- a/vendor/github.com/go-openapi/runtime/client/runtime.go +++ b/vendor/github.com/go-openapi/runtime/client/runtime.go @@ -5,25 +5,19 @@ package client import ( "context" - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/tls" - "crypto/x509" - "encoding/pem" - "errors" "fmt" "mime" "net/http" "net/http/httputil" - "os" "strings" "sync" "time" "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/client/internal/request" "github.com/go-openapi/runtime/logger" "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/runtime/server-middleware/mediatype" "github.com/go-openapi/runtime/yamlpc" "github.com/go-openapi/strfmt" ) @@ -36,184 +30,6 @@ const ( // DefaultTimeout the default request timeout. var DefaultTimeout = 30 * time.Second -// TLSClientOptions to configure client authentication with mutual TLS. -type TLSClientOptions struct { - // Certificate is the path to a PEM-encoded certificate to be used for - // client authentication. If set then Key must also be set. - Certificate string - - // LoadedCertificate is the certificate to be used for client authentication. - // This field is ignored if Certificate is set. If this field is set, LoadedKey - // is also required. - LoadedCertificate *x509.Certificate - - // Key is the path to an unencrypted PEM-encoded private key for client - // authentication. This field is required if Certificate is set. - Key string - - // LoadedKey is the key for client authentication. This field is required if - // LoadedCertificate is set. - LoadedKey crypto.PrivateKey - - // CA is a path to a PEM-encoded certificate that specifies the root certificate - // to use when validating the TLS certificate presented by the server. If this field - // (and LoadedCA) is not set, the system certificate pool is used. This field is ignored if LoadedCA - // is set. - CA string - - // LoadedCA specifies the root certificate to use when validating the server's TLS certificate. - // If this field (and CA) is not set, the system certificate pool is used. - LoadedCA *x509.Certificate - - // LoadedCAPool specifies a pool of RootCAs to use when validating the server's TLS certificate. - // If set, it will be combined with the other loaded certificates (see LoadedCA and CA). - // If neither LoadedCA or CA is set, the provided pool with override the system - // certificate pool. - // The caller must not use the supplied pool after calling TLSClientAuth. - LoadedCAPool *x509.CertPool - - // ServerName specifies the hostname to use when verifying the server certificate. - // If this field is set then InsecureSkipVerify will be ignored and treated as - // false. - ServerName string - - // InsecureSkipVerify controls whether the certificate chain and hostname presented - // by the server are validated. If true, any certificate is accepted. - InsecureSkipVerify bool - - // VerifyPeerCertificate, if not nil, is called after normal - // certificate verification. It receives the raw ASN.1 certificates - // provided by the peer and also any verified chains that normal processing found. - // If it returns a non-nil error, the handshake is aborted and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. If normal verification is disabled by - // setting InsecureSkipVerify then this callback will be considered but - // the verifiedChains argument will always be nil. - VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error - - // VerifyConnection, if not nil, is called after normal certificate - // verification and after [TLSClientOptions.VerifyPeerCertificate] by either a TLS client or - // server. It receives the [tls.ConnectionState] which may be inspected. - // - // Unlike VerifyPeerCertificate, this callback is invoked on every - // connection, including resumed ones, making it suitable for checks - // that must always apply (e.g. certificate pinning). - // - // If it returns a non-nil error, the handshake is aborted and that error results. - VerifyConnection func(tls.ConnectionState) error - - // SessionTicketsDisabled may be set to true to disable session ticket and - // PSK (resumption) support. Note that on clients, session ticket support is - // also disabled if ClientSessionCache is nil. - SessionTicketsDisabled bool - - // ClientSessionCache is a cache of ClientSessionState entries for TLS - // session resumption. It is only used by clients. - ClientSessionCache tls.ClientSessionCache - - // Prevents callers using unkeyed fields. - _ struct{} -} - -// TLSClientAuth creates a [tls.Config] for mutual auth. -func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) { - // create client tls config - cfg := &tls.Config{ - MinVersion: tls.VersionTLS12, - } - - // load client cert if specified - if opts.Certificate != "" { - cert, err := tls.LoadX509KeyPair(opts.Certificate, opts.Key) - if err != nil { - return nil, fmt.Errorf("tls client cert: %v", err) - } - cfg.Certificates = []tls.Certificate{cert} - } else if opts.LoadedCertificate != nil { - block := pem.Block{Type: "CERTIFICATE", Bytes: opts.LoadedCertificate.Raw} - certPem := pem.EncodeToMemory(&block) - - var keyBytes []byte - switch k := opts.LoadedKey.(type) { - case *rsa.PrivateKey: - keyBytes = x509.MarshalPKCS1PrivateKey(k) - case *ecdsa.PrivateKey: - var err error - keyBytes, err = x509.MarshalECPrivateKey(k) - if err != nil { - return nil, fmt.Errorf("tls client priv key: %v", err) - } - default: - return nil, errors.New("tls client priv key: unsupported key type") - } - - block = pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes} - keyPem := pem.EncodeToMemory(&block) - - cert, err := tls.X509KeyPair(certPem, keyPem) - if err != nil { - return nil, fmt.Errorf("tls client cert: %v", err) - } - cfg.Certificates = []tls.Certificate{cert} - } - - cfg.InsecureSkipVerify = opts.InsecureSkipVerify - - cfg.VerifyPeerCertificate = opts.VerifyPeerCertificate - cfg.VerifyConnection = opts.VerifyConnection - cfg.SessionTicketsDisabled = opts.SessionTicketsDisabled - cfg.ClientSessionCache = opts.ClientSessionCache - - // When no CA certificate is provided, default to the system cert pool - // that way when a request is made to a server known by the system trust store, - // the name is still verified - switch { - case opts.LoadedCA != nil: - caCertPool := basePool(opts.LoadedCAPool) - caCertPool.AddCert(opts.LoadedCA) - cfg.RootCAs = caCertPool - case opts.CA != "": - // load ca cert - caCert, err := os.ReadFile(opts.CA) - if err != nil { - return nil, fmt.Errorf("tls client ca: %v", err) - } - caCertPool := basePool(opts.LoadedCAPool) - caCertPool.AppendCertsFromPEM(caCert) - cfg.RootCAs = caCertPool - case opts.LoadedCAPool != nil: - cfg.RootCAs = opts.LoadedCAPool - } - - // apply servername overrride - if opts.ServerName != "" { - cfg.InsecureSkipVerify = false - cfg.ServerName = opts.ServerName - } - - return cfg, nil -} - -// TLSTransport creates a [http] client transport suitable for mutual [tls] auth. -func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) { - cfg, err := TLSClientAuth(opts) - if err != nil { - return nil, err - } - - return &http.Transport{TLSClientConfig: cfg}, nil -} - -// TLSClient creates a [http.Client] for mutual auth. -func TLSClient(opts TLSClientOptions) (*http.Client, error) { - transport, err := TLSTransport(opts) - if err != nil { - return nil, err - } - return &http.Client{Transport: transport}, nil -} - // Runtime represents an API client that uses the transport // to make [http] requests based on a swagger specification. type Runtime struct { @@ -228,17 +44,50 @@ type Runtime struct { Host string BasePath string Formats strfmt.Registry - Context context.Context //nolint:containedctx // we precisely want this type to contain the request context + // Deprecated: prefer [runtime.ContextualTransport.SubmitContext] to pass the request context explicitly. + Context context.Context //nolint:containedctx // we precisely want this type to contain the request context + + Debug bool + + // Trace enables connection-level diagnostic output via + // [net/http/httptrace]. When true, the runtime narrates the + // connection lifecycle of every request through r.logger.Debugf: + // DNS, dial, TLS handshake, idle-pool reuse, request body + // transfer, time-to-first-byte, response body transfer, and a + // trailing per-request summary line. + // + // Trace is orthogonal to Debug: Debug dumps wire bytes (request + // and response headers and body), Trace narrates how the + // connection got there. Both may be enabled independently. + // + // Trace is not coupled to the SWAGGER_DEBUG / DEBUG environment + // variables: it defaults to false and is only enabled by + // explicit assignment. + // + // Trace is primarily intended as a problem-investigation tool + // (the local equivalent of curl -vvv), not an always-on tracer. + // For distributed-trace correlation, use the OpenTelemetry + // integration ([Runtime.WithOpenTelemetry]). + Trace bool - Debug bool logger logger.Logger + // MatchSuffix enables RFC 6839 structured-syntax suffix tolerance + // for codec lookup. When true, a response with Content-Type + // "application/problem+json" finds the JSON consumer registered + // under "application/json"; with the default false, the lookup + // is strict and falls through to the "*/*" wildcard if present. + // See [mediatype.AllowSuffix] for the semantics. + MatchSuffix bool + clientOnce *sync.Once client *http.Client schemes []string response ClientResponseFunc } +var _ runtime.ContextualTransport = &Runtime{} + // New creates a new default runtime for a swagger api runtime.Client. func New(host, basePath string, schemes []string) *Runtime { var rt Runtime @@ -246,13 +95,15 @@ func New(host, basePath string, schemes []string) *Runtime { // Enhancement proposal: https://github.com/go-openapi/runtime/issues/385 rt.Consumers = map[string]runtime.Consumer{ - runtime.YAMLMime: yamlpc.YAMLConsumer(), - runtime.JSONMime: runtime.JSONConsumer(), - runtime.XMLMime: runtime.XMLConsumer(), - runtime.TextMime: runtime.TextConsumer(), - runtime.HTMLMime: runtime.TextConsumer(), - runtime.CSVMime: runtime.CSVConsumer(), - runtime.DefaultMime: runtime.ByteStreamConsumer(), + runtime.YAMLMime: yamlpc.YAMLConsumer(), + runtime.JSONMime: runtime.JSONConsumer(), + runtime.XMLMime: runtime.XMLConsumer(), + runtime.TextMime: runtime.TextConsumer(), + runtime.HTMLMime: runtime.TextConsumer(), + runtime.CSVMime: runtime.CSVConsumer(), + runtime.MultipartFormMime: runtime.ByteStreamConsumer(), + runtime.URLencodedFormMime: runtime.ByteStreamConsumer(), + runtime.DefaultMime: runtime.ByteStreamConsumer(), } rt.Producers = map[string]runtime.Producer{ runtime.YAMLMime: yamlpc.YAMLProducer(), @@ -294,47 +145,6 @@ func NewWithClient(host, basePath string, schemes []string, client *http.Client) return rt } -// WithOpenTracing adds opentracing support to the provided runtime. -// A new client span is created for each request. -// If the context of the client operation does not contain an active span, no span is created. -// The provided opts are applied to each spans - for example to add global tags. -// -// Deprecated: use [WithOpenTelemetry] instead, as opentracing is now archived and superseded by opentelemetry. -// -// # Deprecation notice -// -// The [Runtime.WithOpenTracing] method has been deprecated in favor of [Runtime.WithOpenTelemetry]. -// -// The method is still around so programs calling it will still build. However, it will return -// an opentelemetry transport. -// -// If you have a strict requirement on using opentracing, you may still do so by importing -// module [github.com/go-openapi/runtime/client-[middleware]/opentracing] and using -// [github.com/go-openapi/runtime/client-[middleware]/opentracing.WithOpenTracing] with your -// usual opentracing options and opentracing-enabled transport. -// -// Passed options are ignored unless they are of type [OpenTelemetryOpt]. -func (r *Runtime) WithOpenTracing(opts ...any) runtime.ClientTransport { - otelOpts := make([]OpenTelemetryOpt, 0, len(opts)) - for _, o := range opts { - otelOpt, ok := o.(OpenTelemetryOpt) - if !ok { - continue - } - otelOpts = append(otelOpts, otelOpt) - } - - return r.WithOpenTelemetry(otelOpts...) -} - -// WithOpenTelemetry adds opentelemetry support to the provided runtime. -// A new client span is created for each request. -// If the context of the client operation does not contain an active span, no span is created. -// The provided opts are applied to each spans - for example to add global tags. -func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOpt) runtime.ClientTransport { - return newOpenTelemetryTransport(r, r.Host, opts) -} - // EnableConnectionReuse drains the remaining body from a response // so that go will reuse the TCP connections. // @@ -357,105 +167,109 @@ func (r *Runtime) EnableConnectionReuse() { ) } +// CreateHTTPRequestContext creates the requests and bind the parameters, but does not send it over the wire +// like [Runtime.SubmitContext]. +// +// The [http.Request] is complete with authentication, headers and body (including streamed body) and ready for callers +// to submit it to a [http.Client] of their choice, then consume the [http.Response]. +// +// Most users would simply use [Runtime.SubmitContext], which wraps all these operations in one call. +func (r *Runtime) CreateHTTPRequestContext(ctx context.Context, operation *runtime.ClientOperation) (req *http.Request, cancel context.CancelFunc, err error) { + req, cancel, err = r.createHTTPRequestContext(ctx, operation) + return +} + +// CreateHttpRequest builds the [http.Request] for the given operation, using +// [context.Background] as the request context. +// +// Any per-operation timeout declared by the operation's [runtime.ClientRequestWriter] +// is silently ignored here, which can leak a context-cancellation channel if the +// caller relies on it. +// +// Deprecated: use [Runtime.CreateHTTPRequestContext] instead, with explicit +// control over the request context and its cancellation. func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) { //nolint:revive - _, req, err = r.createHttpRequest(operation) + req, _, err = r.createHTTPRequestContext(context.Background(), operation) return } // Submit a request and when there is a body on success it will turn that into the result // all other things are turned into an api error for swagger which retains the status code. +// +// This call inherits the context possibly put in the operation, otherwise the one possibly put in the [Runtime]. +// If none are set, use [context.Background]. +// +// Any timeout set by parameters is honored. func (r *Runtime) Submit(operation *runtime.ClientOperation) (any, error) { - _, readResponse, _ := operation.Params, operation.Reader, operation.AuthInfo + return r.SubmitContext(r.ensureContext(operation), operation) +} - request, req, err := r.createHttpRequest(operation) +// SubmitContext submits a request and returns the result. +// +// Errors are turned into an api error for swagger which retains the status code. +// +// Unlike [Submit], [SubmitContext] only injects the context provided by the caller: +// contexts possibly cached in operation or runtime are ignored. +// +// On the other hand, a timeout set by parameters is honored. +func (r *Runtime) SubmitContext(parentCtx context.Context, operation *runtime.ClientOperation) (any, error) { + req, cancel, err := r.createHTTPRequestContext(parentCtx, operation) if err != nil { return nil, err } + defer cancel() - r.clientOnce.Do(func() { - r.client = &http.Client{ - Transport: r.Transport, - Jar: r.Jar, - } - }) - - if r.Debug { - b, err2 := httputil.DumpRequestOut(req, true) - if err2 != nil { - return nil, err2 - } - r.logger.Debugf("%s\n", string(b)) - } + r.ensureClient() - var parentCtx context.Context - switch { - case operation.Context != nil: - parentCtx = operation.Context - case r.Context != nil: - parentCtx = r.Context - default: - parentCtx = context.Background() + if err := r.dumpRequest(req); err != nil { + return nil, err } - var ( - ctx context.Context - cancel context.CancelFunc - ) - if request.timeout == 0 { - // There may be a deadline in the context passed to the operation. - // Otherwise, there is no timeout set. - ctx, cancel = context.WithCancel(parentCtx) - } else { - // Sets the timeout passed from request params (by default runtime.DefaultTimeout). - // If there is already a deadline in the parent context, the shortest will - // apply. - ctx, cancel = context.WithTimeout(parentCtx, request.timeout) + // Attach the trace session before Do so the httptrace hooks + // fire during the round-trip. The session emits its trailing + // summary on finish; the response body is consumed by + // ReadResponse downstream, after which finish is called. + var trace *traceSession + if r.Trace { + trace = newTraceSession(r.logger, req.Method, req.URL.String(), + introspectTLSConfig(r.pickClient(operation))) + //nolint:contextcheck // We intentionally derive from req.Context() to layer the trace hooks onto the existing request context. + req = req.WithContext(trace.attach(req.Context())) + if req.Body != nil { + req.Body = trace.wrapRequestBody(req.Body) + } + defer trace.finish() } - defer cancel() - var client *http.Client - if operation.Client != nil { - client = operation.Client - } else { - client = r.client - } - req = req.WithContext(ctx) - res, err := client.Do(req) // make requests, by default follows 10 redirects before failing + res, err := r.pickClient(operation).Do(req) if err != nil { + if trace != nil { + trace.onRoundTripError(err) + } return nil, err } defer res.Body.Close() + if trace != nil { + trace.onResponse(res.StatusCode) + res.Body = trace.wrapResponseBody(res.Body) + } + ct := res.Header.Get(runtime.HeaderContentType) if ct == "" { // this should really never occur ct = r.DefaultMediaType } - if r.Debug { - printBody := true - if ct == runtime.DefaultMime { - printBody = false // Spare the terminal from a binary blob. - } - b, err2 := httputil.DumpResponse(res, printBody) - if err2 != nil { - return nil, err2 - } - r.logger.Debugf("%s\n", string(b)) + if err := r.dumpResponse(res, ct); err != nil { + return nil, err } - mt, _, err := mime.ParseMediaType(ct) + cons, err := r.resolveConsumer(ct) if err != nil { - return nil, fmt.Errorf("parse content type: %s", err) + return nil, err } - cons, ok := r.Consumers[mt] - if !ok { - if cons, ok = r.Consumers["*/*"]; !ok { - // scream about not knowing what to do - return nil, fmt.Errorf("no consumer: %q", ct) - } - } - return readResponse.ReadResponse(r.response(res), cons) + return operation.Reader.ReadResponse(r.response(res), cons) } // SetDebug changes the debug flag. @@ -482,6 +296,17 @@ func (r *Runtime) SetResponseReader(f ClientResponseFunc) { r.response = f } +func (r *Runtime) ensureContext(operation *runtime.ClientOperation) context.Context { + switch { + case operation.Context != nil: //nolint:staticcheck // kept for backward compatibility + return operation.Context + case r.Context != nil: + return r.Context + default: + return context.Background() + } +} + func (r *Runtime) pickScheme(schemes []string) string { if v := r.selectScheme(r.schemes); v != "" { return v @@ -518,16 +343,121 @@ func transportOrDefault(left, right http.RoundTripper) http.RoundTripper { return left } -// takes a client operation and creates equivalent http.Request. -func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) { //nolint:revive +// ensureClient lazily initializes r.client from r.Transport and r.Jar +// on first use. Safe under concurrent calls via sync.Once. +func (r *Runtime) ensureClient() { + r.clientOnce.Do(func() { + r.client = &http.Client{ + Transport: r.Transport, + Jar: r.Jar, + } + }) +} + +// pickClient returns the http.Client to use for this operation: the +// per-operation override if set, else the runtime's shared client. +func (r *Runtime) pickClient(operation *runtime.ClientOperation) *http.Client { + if operation.Client != nil { + return operation.Client + } + return r.client +} + +// dumpRequest writes the outgoing request to the debug logger when +// r.Debug is enabled. No-op otherwise. Returns the dump error so the +// caller can decide whether to abort the submit. +func (r *Runtime) dumpRequest(req *http.Request) error { + if !r.Debug { + return nil + } + b, err := httputil.DumpRequestOut(req, true) + if err != nil { + return err + } + r.logger.Debugf("%s\n", string(b)) + return nil +} + +// dumpResponse writes the incoming response to the debug logger when +// r.Debug is enabled. The body is omitted for runtime.DefaultMime +// (binary blob). No-op otherwise. +func (r *Runtime) dumpResponse(res *http.Response, ct string) error { + if !r.Debug { + return nil + } + printBody := ct != runtime.DefaultMime // Spare the terminal from a binary blob. + b, err := httputil.DumpResponse(res, printBody) + if err != nil { + return err + } + r.logger.Debugf("%s\n", string(b)) + return nil +} + +// resolveConsumer parses ct and returns the registered Consumer for +// that media type. Lookup is alias-aware (RFC 9512 §2.1 — yaml +// aliases) and, when [Runtime.MatchSuffix] is true, also tolerates +// RFC 6839 structured-syntax suffix media types (+json, +xml, +yaml). +// Falls back to the "*/*" entry if no match found. +func (r *Runtime) resolveConsumer(ct string) (runtime.Consumer, error) { + if _, _, err := mime.ParseMediaType(ct); err != nil { + return nil, fmt.Errorf("parse content type: %w", err) + } + if cons, ok := mediatype.Lookup(r.Consumers, ct, r.matchOpts()...); ok { + return cons, nil + } + if cons, ok := r.Consumers["*/*"]; ok { + return cons, nil + } + // scream about not knowing what to do + return nil, fmt.Errorf("no consumer: %q", ct) +} + +// matchOpts builds the mediatype.MatchOption slice for codec +// lookups on the Runtime, currently just the AllowSuffix opt-in. +func (r *Runtime) matchOpts() []mediatype.MatchOption { + if !r.MatchSuffix { + return nil + } + + return []mediatype.MatchOption{mediatype.AllowSuffix()} +} + +// createHTTPRequestContext is the context-aware builder of a [http.Request]. +// +// The returned [http.Request] carries a context derived from parentCtx that +// honors the per-request timeout set during WriteToRequest. Callers must +// invoke cancel once the response is fully read. +func (r *Runtime) createHTTPRequestContext(parentCtx context.Context, operation *runtime.ClientOperation) (*http.Request, context.CancelFunc, error) { + req, cmt, auth, err := r.prepareRequest(operation) + if err != nil { + return nil, nil, err + } + + httpReq, cancel, err := req.BuildHTTPContext(parentCtx, cmt, r.BasePath, r.Producers, r.Formats, auth) + if err != nil { + return nil, nil, err + } + + r.applyHostScheme(httpReq, operation) + + return httpReq, cancel, nil +} + +// prepareRequest performs the operation-to-request setup that is +// independent of how the http.Request is finally assembled: parameters, +// headers, default authentication, and consumes-media-type selection. +func (r *Runtime) prepareRequest(operation *runtime.ClientOperation) (*request.Request, string, runtime.ClientAuthInfoWriter, error) { params, _, auth := operation.Params, operation.Reader, operation.AuthInfo - request := newRequest(operation.Method, operation.PathPattern, params) + req := request.New(operation.Method, operation.PathPattern, params) + _ = req.SetTimeout(DefaultTimeout) // the timeout may be overridden by ClientRequestWriter + req.SetConsumes(operation.ConsumesMediaTypes) accept := make([]string, 0, len(operation.ProducesMediaTypes)) accept = append(accept, operation.ProducesMediaTypes...) - if err := request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil { - return nil, nil, err + if err := req.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil { + return nil, "", nil, err } if auth == nil && r.DefaultAuthentication != nil { @@ -538,39 +468,75 @@ func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*reques return r.DefaultAuthentication.AuthenticateRequest(req, reg) }) } - // if auth != nil { - // if err := auth.AuthenticateRequest(request, r.Formats); err != nil { - // return nil, err - // } - //} - - // Enhancement proposal: https://github.com/go-openapi/runtime/issues/386 - cmt := r.DefaultMediaType - for _, mediaType := range operation.ConsumesMediaTypes { - // Pick first non-empty media type - if mediaType != "" { - cmt = mediaType - break - } - } - if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime { - return nil, nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt) + cmt := pickConsumesMediaType(operation.ConsumesMediaTypes, r.Producers, r.DefaultMediaType, r.matchOpts()...) + if _, ok := mediatype.Lookup(r.Producers, cmt, r.matchOpts()...); !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime { + return nil, "", nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt) } - req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth) - if err != nil { - return nil, nil, err - } - req.URL.Scheme = r.pickScheme(operation.Schemes) - req.URL.Host = r.Host - req.Host = r.Host - return request, req, nil + return req, cmt, auth, nil } -func basePool(pool *x509.CertPool) *x509.CertPool { - if pool == nil { - return x509.NewCertPool() +// applyHostScheme stamps the runtime's host and the operation-selected +// scheme onto the freshly built http.Request. +func (r *Runtime) applyHostScheme(httpReq *http.Request, operation *runtime.ClientOperation) { + httpReq.URL.Scheme = r.pickScheme(operation.Schemes) + httpReq.URL.Host = r.Host + httpReq.Host = r.Host +} + +// pickConsumesMediaType selects which Content-Type the client will send. +// +// Selection rules, in priority order: +// +// 1. multipart/form-data if any consumes entry advertises it (it streams +// and preserves per-file Content-Type, regardless of codegen ordering; +// resolves issue #286); +// 2. the first non-empty entry whose mime is either structural +// (multipart/form-data or application/x-www-form-urlencoded — these +// do not need a producer in the map) or has a producer registered in +// producers — this lets the client gracefully skip unregistered +// spec entries instead of erroring at the gate that follows; +// 3. the first non-empty entry overall (preserves the historical error +// path: the gate at the call site reports "none of producers" with +// the unregistered mime, so the diagnostic is unchanged when nothing +// in consumes is registered); +// 4. def, if consumes is empty or all empty strings. +// +// Step 2 closes part of issues #32 and #386: an operation declaring +// `consumes: [application/x-vendor, application/json]` with no vendor +// producer registered now silently uses JSON instead of erroring. +func pickConsumesMediaType(consumes []string, producers map[string]runtime.Producer, def string, opts ...mediatype.MatchOption) string { + for _, mt := range consumes { + if strings.EqualFold(mt, runtime.MultipartFormMime) { + return mt + } + } + var firstNonEmpty string + for _, mt := range consumes { + if mt == "" { + continue + } + if firstNonEmpty == "" { + firstNonEmpty = mt + } + if isStructuralMime(mt) { + return mt + } + if _, ok := mediatype.Lookup(producers, mt, opts...); ok { + return mt + } + } + if firstNonEmpty != "" { + return firstNonEmpty } - return pool + return def +} + +// isStructuralMime reports whether mt is a media type whose body shape +// is owned by the runtime (multipart envelope, urlencoded form). These +// do not require an entry in the producers map. +func isStructuralMime(mt string) bool { + return strings.EqualFold(mt, runtime.MultipartFormMime) || + strings.EqualFold(mt, runtime.URLencodedFormMime) } diff --git a/vendor/github.com/go-openapi/runtime/client/tls.go b/vendor/github.com/go-openapi/runtime/client/tls.go new file mode 100644 index 00000000000..017694fae08 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/client/tls.go @@ -0,0 +1,197 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package client + +import ( + "crypto" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "fmt" + "net/http" + "os" +) + +// TLSClientOptions to configure client authentication with mutual TLS. +type TLSClientOptions struct { + // Certificate is the path to a PEM-encoded certificate to be used for + // client authentication. If set then Key must also be set. + Certificate string + + // LoadedCertificate is the certificate to be used for client authentication. + // This field is ignored if Certificate is set. If this field is set, LoadedKey + // is also required. + LoadedCertificate *x509.Certificate + + // Key is the path to an unencrypted PEM-encoded private key for client + // authentication. This field is required if Certificate is set. + Key string + + // LoadedKey is the key for client authentication. This field is required if + // LoadedCertificate is set. + LoadedKey crypto.PrivateKey + + // CA is a path to a PEM-encoded certificate that specifies the root certificate + // to use when validating the TLS certificate presented by the server. If this field + // (and LoadedCA) is not set, the system certificate pool is used. This field is ignored if LoadedCA + // is set. + CA string + + // LoadedCA specifies the root certificate to use when validating the server's TLS certificate. + // If this field (and CA) is not set, the system certificate pool is used. + LoadedCA *x509.Certificate + + // LoadedCAPool specifies a pool of RootCAs to use when validating the server's TLS certificate. + // If set, it will be combined with the other loaded certificates (see LoadedCA and CA). + // If neither LoadedCA or CA is set, the provided pool will override the system + // certificate pool. + // + // The caller must not use the supplied pool after calling TLSClientAuth. + LoadedCAPool *x509.CertPool + + // ServerName specifies the hostname to use when verifying the server certificate. + // If this field is set then InsecureSkipVerify will be ignored and treated as + // false. + ServerName string + + // InsecureSkipVerify controls whether the certificate chain and hostname presented + // by the server are validated. If true, any certificate is accepted. + InsecureSkipVerify bool + + // VerifyPeerCertificate, if not nil, is called after normal + // certificate verification. It receives the raw ASN.1 certificates + // provided by the peer and also any verified chains that normal processing found. + // If it returns a non-nil error, the handshake is aborted and that error results. + // + // If normal verification fails then the handshake will abort before + // considering this callback. If normal verification is disabled by + // setting InsecureSkipVerify then this callback will be considered but + // the verifiedChains argument will always be nil. + VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error + + // VerifyConnection, if not nil, is called after normal certificate + // verification and after [TLSClientOptions.VerifyPeerCertificate] by either a TLS client or + // server. It receives the [tls.ConnectionState] which may be inspected. + // + // Unlike VerifyPeerCertificate, this callback is invoked on every + // connection, including resumed ones, making it suitable for checks + // that must always apply (e.g. certificate pinning). + // + // If it returns a non-nil error, the handshake is aborted and that error results. + VerifyConnection func(tls.ConnectionState) error + + // SessionTicketsDisabled may be set to true to disable session ticket and + // PSK (resumption) support. Note that on clients, session ticket support is + // also disabled if ClientSessionCache is nil. + SessionTicketsDisabled bool + + // ClientSessionCache is a cache of ClientSessionState entries for TLS + // session resumption. It is only used by clients. + ClientSessionCache tls.ClientSessionCache + + // Prevents callers using unkeyed fields. + _ struct{} +} + +// TLSClientAuth creates a [tls.Config] for mutual auth. +func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) { + // create client tls config + cfg := &tls.Config{ + MinVersion: tls.VersionTLS12, + } + + // load client cert if specified + if opts.Certificate != "" { + cert, err := tls.LoadX509KeyPair(opts.Certificate, opts.Key) + if err != nil { + return nil, fmt.Errorf("tls client cert: %w", err) + } + cfg.Certificates = []tls.Certificate{cert} + } else if opts.LoadedCertificate != nil { + block := pem.Block{Type: "CERTIFICATE", Bytes: opts.LoadedCertificate.Raw} + certPem := pem.EncodeToMemory(&block) + + // PKCS#8 covers RSA, ECDSA, Ed25519, X25519 (the key types tls.X509KeyPair + // understands) and pairs with the canonical "PRIVATE KEY" PEM label. + keyBytes, err := x509.MarshalPKCS8PrivateKey(opts.LoadedKey) + if err != nil { + return nil, fmt.Errorf("tls client priv key: %w", err) + } + + block = pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes} + keyPem := pem.EncodeToMemory(&block) + + cert, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + return nil, fmt.Errorf("tls client cert: %w", err) + } + cfg.Certificates = []tls.Certificate{cert} + } + + cfg.InsecureSkipVerify = opts.InsecureSkipVerify + + cfg.VerifyPeerCertificate = opts.VerifyPeerCertificate + cfg.VerifyConnection = opts.VerifyConnection + cfg.SessionTicketsDisabled = opts.SessionTicketsDisabled + cfg.ClientSessionCache = opts.ClientSessionCache + + // When no CA certificate is provided, default to the system cert pool + // that way when a request is made to a server known by the system trust store, + // the name is still verified + switch { + case opts.LoadedCA != nil: + caCertPool := basePool(opts.LoadedCAPool) + caCertPool.AddCert(opts.LoadedCA) + cfg.RootCAs = caCertPool + case opts.CA != "": + // load ca cert + caCert, err := os.ReadFile(opts.CA) + if err != nil { + return nil, fmt.Errorf("tls client ca: %w", err) + } + caCertPool := basePool(opts.LoadedCAPool) + caCertPool.AppendCertsFromPEM(caCert) + cfg.RootCAs = caCertPool + case opts.LoadedCAPool != nil: + cfg.RootCAs = opts.LoadedCAPool + } + + // apply servername override + if opts.ServerName != "" { + cfg.InsecureSkipVerify = false + cfg.ServerName = opts.ServerName + } + + return cfg, nil +} + +// TLSTransport creates a [http.RoundTripper] for a client transport,suitable for mutual TLS auth. +func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) { + cfg, err := TLSClientAuth(opts) + if err != nil { + return nil, err + } + + return &http.Transport{TLSClientConfig: cfg}, nil +} + +// TLSClient creates a [http.Client] for mutual auth. +func TLSClient(opts TLSClientOptions) (*http.Client, error) { + transport, err := TLSTransport(opts) + if err != nil { + return nil, err + } + return &http.Client{Transport: transport}, nil +} + +// basePool returns pool if non-nil; otherwise it returns a new empty cert pool. +// +// Clones the pool provided up front by the caller. +func basePool(pool *x509.CertPool) *x509.CertPool { + if pool == nil { + return x509.NewCertPool() + } + + return pool.Clone() +} diff --git a/vendor/github.com/go-openapi/runtime/client_operation.go b/vendor/github.com/go-openapi/runtime/client_operation.go index ad7277e091f..61f6ead34a2 100644 --- a/vendor/github.com/go-openapi/runtime/client_operation.go +++ b/vendor/github.com/go-openapi/runtime/client_operation.go @@ -19,12 +19,30 @@ type ClientOperation struct { AuthInfo ClientAuthInfoWriter Params ClientRequestWriter Reader ClientResponseReader - Context context.Context //nolint:containedctx // we precisely want this type to contain the request context - Client *http.Client + // Deprecated: prefer [ContextualTransport.SubmitContext] to pass the request context explicitly. + Context context.Context //nolint:containedctx // we precisely want this type to contain the request context + Client *http.Client } // A ClientTransport implementor knows how to submit Request objects to some destination. type ClientTransport interface { - // Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error) + // Submit the operation and return the deserialized response or an error. Submit(*ClientOperation) (any, error) } + +// ContextualTransport extends [ClientTransport] with an explicit +// context-aware submission method. +// +// Wrappers such as the OpenTelemetry transport type-assert to this +// interface so they can forward an explicit context to the underlying +// transport without setting the cached [ClientOperation.Context] field. +// +// In v2, SubmitContext will be folded into [ClientTransport] itself +// and the cached [ClientOperation.Context] field removed; this interface +// is the v0.x bridge. +type ContextualTransport interface { + ClientTransport + + // SubmitContext submits the operation using ctx as the request context. + SubmitContext(ctx context.Context, operation *ClientOperation) (any, error) +} diff --git a/vendor/github.com/go-openapi/runtime/client_response.go b/vendor/github.com/go-openapi/runtime/client_response.go index 92668db4ece..7b4b7e40df7 100644 --- a/vendor/github.com/go-openapi/runtime/client_response.go +++ b/vendor/github.com/go-openapi/runtime/client_response.go @@ -59,7 +59,7 @@ func (o *APIError) Error() string { if err, ok := o.Response.(error); ok { resp = []byte("'" + sanitizer.Replace(err.Error()) + "'") } else { - resp, _ = json.Marshal(o.Response) + resp, _ = json.Marshal(o.Response) //nolint:errchkjson // error swallowed as this is our last best effort attempt } return fmt.Sprintf("%s (status %d): %s", o.OperationName, o.Code, resp) diff --git a/vendor/github.com/go-openapi/runtime/constants.go b/vendor/github.com/go-openapi/runtime/constants.go index 80de6c80868..ea86cfadbc1 100644 --- a/vendor/github.com/go-openapi/runtime/constants.go +++ b/vendor/github.com/go-openapi/runtime/constants.go @@ -21,8 +21,12 @@ const ( DefaultMime = "application/octet-stream" // JSONMime the json mime type. JSONMime = "application/json" - // YAMLMime the [yaml] mime type. - YAMLMime = "application/x-yaml" + // YAMLMime the [yaml] mime type. Set to the canonical RFC 9512 + // name (application/yaml). Legacy forms application/x-yaml, + // text/yaml, and text/x-yaml — per RFC 9512 §2.1 "Deprecated + // alias names for this type" — resolve to the same codec via + // the mediatype alias bridge. + YAMLMime = "application/yaml" // XMLMime the [xml] mime type. XMLMime = "application/xml" // TextMime the text mime type. diff --git a/vendor/github.com/go-openapi/runtime/csv.go b/vendor/github.com/go-openapi/runtime/csv.go index 558d0cb99aa..11d60872c3e 100644 --- a/vendor/github.com/go-openapi/runtime/csv.go +++ b/vendor/github.com/go-openapi/runtime/csv.go @@ -100,7 +100,7 @@ func CSVConsumer(opts ...CSVOpt) Consumer { default: // support *[][]string, *[]byte, *string - if ptr := reflect.TypeOf(data); ptr.Kind() != reflect.Ptr { + if ptr := reflect.TypeOf(data); ptr.Kind() != reflect.Pointer { return errors.New("destination must be a pointer") } @@ -159,14 +159,14 @@ func CSVConsumer(opts ...CSVOpt) Consumer { // // Supported input underlying types and interfaces, prioritized in this order: // -// - *[csv.Reader] -// - [CSVReader] (reader options are ignored) -// - [io.Reader] -// - [io.WriterTo] -// - [encoding.BinaryMarshaler] -// - [][]string -// - []byte -// - string +// - *[csv.Reader] +// - [CSVReader] (reader options are ignored) +// - [io.Reader] +// - [io.WriterTo] +// - [encoding.BinaryMarshaler] +// - [][]string +// - []byte +// - string // // The producer prioritizes situations where buffering the input is not required. func CSVProducer(opts ...CSVOpt) Producer { diff --git a/vendor/github.com/go-openapi/runtime/file.go b/vendor/github.com/go-openapi/runtime/file.go index 2a85379a748..0420db9440a 100644 --- a/vendor/github.com/go-openapi/runtime/file.go +++ b/vendor/github.com/go-openapi/runtime/file.go @@ -5,4 +5,10 @@ package runtime import "github.com/go-openapi/swag/fileutils" +// File represents an uploaded file. Re-exported from +// [fileutils.File] for backwards compatibility. +// +// See [BindForm] (in form.go) for the orchestrator that parses +// multipart / urlencoded request bodies and binds declared file +// fields onto handler-side targets. type File = fileutils.File diff --git a/vendor/github.com/go-openapi/runtime/form.go b/vendor/github.com/go-openapi/runtime/form.go new file mode 100644 index 00000000000..213757f1f4c --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/form.go @@ -0,0 +1,362 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package runtime + +import ( + stderrors "errors" + "fmt" + "mime/multipart" + "net/http" + "strings" + + "github.com/go-openapi/errors" +) + +// DefaultMaxUploadFilenameLength is the default cap applied to +// FileHeader.Filename for each declared file when [BindForm] is invoked +// without an explicit [BindFormMaxFilenameLen] option. +// +// Multipart headers are allocated per part; an attacker submitting +// multi-MB filenames inflates the parser's memory footprint. 1 KiB +// matches the IETF guidance for sane filename length and is enough +// for realistic uploads. +const DefaultMaxUploadFilenameLength = 1024 + +// DefaultMaxUploadBodySize limits the size of the body to upload forms to 32MB. +// +// Use an explicit [BindFormMaxBody] option to change this limit. +const DefaultMaxUploadBodySize = int64(32) << 20 + +// filenamePreviewLen caps the byte length of the FileHeader.Filename +// preview embedded as the ParseError.Value field when the helper +// rejects a too-long filename. +const filenamePreviewLen = 32 + +// ValidateFilenameLength enforces the FileHeader.Filename length cap +// that [BindForm] applies via [BindFormFile] declarations. Untyped +// binder paths that fetch the file via [http.Request.FormFile] +// directly (rather than declaring the file through [BindFormFile]) call +// this to opt into the same protection. +// +// Returns nil if filename length is within maxLen or maxLen <= 0. +// Otherwise returns a [*errors.ParseError] suitable for direct return +// from a parameter binder. The error embeds a truncated preview of +// the offending filename to keep the error message bounded. +func ValidateFilenameLength(paramName, paramIn, filename string, maxLen int) error { + if maxLen <= 0 || len(filename) <= maxLen { + return nil + } + preview := filename[:min(len(filename), filenamePreviewLen)] + return errors.NewParseError(paramName, paramIn, preview, + fmt.Errorf("filename length %d exceeds limit %d", len(filename), maxLen)) +} + +// FileBinder is the per-file callback invoked by [BindForm] when a +// declared file field is present. +// +// The callback is responsible for BOTH validating the file (size, MIME, etc.) AND assigning the bound +// file to its destination — typically using: +// +// o.FieldName = &runtime.File{Data: file, Header: header} +// +// Returning a non-nil error surfaces the error in [BindForm]'s per-field +// accumulator. Errors from the binder flow through verbatim — the +// binder is expected to produce HTTP-aware errors (e.g. +// [errors.ExceedsMaximum] from go-openapi/validate). +type FileBinder func(file multipart.File, header *multipart.FileHeader) error + +// BindOption configures [BindForm]. The variadic style keeps simple +// call sites simple and lets new knobs (security caps, additional +// behaviour) be added without breaking the signature. +type BindOption func(*bindConfig) + +type multipartFormLimits struct { + maxBody int64 + maxFiles int + maxFilenameLen int +} + +type bindConfig struct { + multipartFormLimits + + maxParseMemory int64 + files []formFileSpec +} + +type formFileSpec struct { + name string + required bool + bind FileBinder +} + +// BindFormMaxParseMemory caps the in-memory portion of a multipart +// body. Bytes beyond this are spilled to temporary files on disk by +// the stdlib parser. 0 (the default) defers to the stdlib's 32 MB. +// +// This option does NOT cap total body bytes — see [BindFormMaxBody] +// for that. The default body cap ([DefaultMaxUploadBodySize] = 32 MB) +// is applied even when this option is not supplied, so out of the box +// [BindForm] is bounded; callers with stricter or looser requirements +// adjust via [BindFormMaxBody]. +func BindFormMaxParseMemory(n int64) BindOption { + return func(c *bindConfig) { c.maxParseMemory = n } +} + +// BindFormMaxBody caps the size of the body read from a http form before parsing. +// +// The limit is set to 32MB by default. This default limit is applied for any n=0. +// +// The limit is disabled for n<0, assuming the caller has already capped the body size upstream. +func BindFormMaxBody(n int64) BindOption { + return func(c *bindConfig) { c.maxBody = n } +} + +// BindFormMaxFiles rejects parses where the total number of file +// parts across all field names exceeds n. 0 (the default) means no +// cap. Exceeding the cap is a fatal error — [BindForm] returns +// fatal=true and no per-file binders run. +func BindFormMaxFiles(n int) BindOption { + return func(c *bindConfig) { c.maxFiles = n } +} + +// BindFormMaxFilenameLen rejects per-file headers whose Filename +// length exceeds n. 0 means no cap; the default applied when this +// option is not supplied is [DefaultMaxUploadFilenameLength]. The +// cap is a per-field bind error (non-fatal); other declared files +// still run. +func BindFormMaxFilenameLen(n int) BindOption { + return func(c *bindConfig) { c.maxFilenameLen = n } +} + +// BindFormFile declares a file field to bind under the given form +// name. If required is true and the field is absent, [BindForm] +// produces the per-field error. +// +// errors.NewParseError(name, "formData", "", http.ErrMissingFile) +// +// If required is false, absence is silent (no error, no bind). +// +// The bind callback runs only when the field is present. It is the +// site where both validation and assignment happen — see [FileBinder]. +// +// FileHeader.Filename is attacker-controlled text; the binder MUST +// NOT use it directly as a filesystem path. The helper does not +// touch the filesystem. +func BindFormFile(name string, required bool, bind FileBinder) BindOption { + return func(c *bindConfig) { + c.files = append(c.files, formFileSpec{ + name: name, + required: required, + bind: bind, + }) + } +} + +// BindForm parses r as multipart/form-data, falling back to +// application/x-www-form-urlencoded when the request is not +// multipart. On success, r.MultipartForm and r.PostForm are populated; +// the caller can read non-file form values via [Values](r.Form) after +// the call returns. +// +// All errors produced by BindForm itself (parse failure, missing +// required field, cap exceeded) are [*errors.ParseError] values built +// via [errors.NewParseError], matching the untyped +// middleware/parameter.go path. Errors returned by per-file binders +// flow through verbatim — binders own their HTTP-aware error shape. +// +// Per-file binders declared via [BindFormFile] run in declaration +// order after a successful parse. Their errors are accumulated and +// returned wrapped in [errors.CompositeValidationError]; the caller +// typically appends the returned err to its own []error and continues +// with non-file parameter binding. +// +// Return semantics: +// +// - fatal=true, err!=nil: parse failure or a hard cap (e.g. +// [BindFormMaxFiles]) was exceeded. No per-file binders ran; the +// caller MUST return err immediately. +// - fatal=false, err!=nil: one or more per-file binders produced +// errors. The form parsed successfully; r.Form is populated. The +// caller appends err to its accumulator and continues. +// - fatal=false, err==nil: full success. +// +// fatal==true implies err!=nil. +// +// Defaults applied out of the box: +// +// - Total body bytes capped at [DefaultMaxUploadBodySize] (32 MB) +// via [http.MaxBytesReader]. Adjust with [BindFormMaxBody] +// (negative n disables, when the caller has already capped the +// body upstream). +// - FileHeader.Filename length capped at +// [DefaultMaxUploadFilenameLength]. Adjust with +// [BindFormMaxFilenameLen]. +// +// Caller responsibilities the helper does NOT cover: +// +// - Set [http.Server.ReadTimeout] / [http.Server.IdleTimeout] to defend +// against slow-read attacks. +// - Decompress Content-Encoding: gzip request bodies upstream if +// the API accepts them, using a size-limited reader. +// - Treat FileHeader.Filename as untrusted user input; never use +// it directly as a filesystem path. +func BindForm(r *http.Request, opts ...BindOption) (fatal bool, err error) { + cfg := bindConfig{ + multipartFormLimits: multipartFormLimits{ + maxFilenameLen: DefaultMaxUploadFilenameLength, + }, + } + for _, opt := range opts { + opt(&cfg) + } + + if perr := parseFormBody(r, cfg.maxParseMemory, cfg.maxBody); perr != nil { + // Body-cap hit gets the 413 status; everything else maps to a + // 400 ParseError. parseFormBody returns the raw stdlib error + // in both cases — the HTTP-aware wrapping happens here. + var maxBytesErr *http.MaxBytesError + if stderrors.As(perr, &maxBytesErr) { + return true, errors.New(http.StatusRequestEntityTooLarge, "formData: %v", perr) + } + return true, errors.NewParseError("body", "formData", "", perr) + } + + if cfg.maxFiles > 0 { + if got := countFileParts(r); got > cfg.maxFiles { + return true, errors.NewParseError("body", "formData", "", + fmt.Errorf("multipart form contains %d file parts, exceeds limit %d", got, cfg.maxFiles)) + } + } + + var bindErrs []error + for _, spec := range cfg.files { + if e := bindFormFile(r, spec, cfg.maxFilenameLen); e != nil { + bindErrs = append(bindErrs, e) + } + } + if len(bindErrs) > 0 { + return false, errors.CompositeValidationError(bindErrs...) + } + return false, nil +} + +// parseFormBody parses the request body. Content-Type drives the +// parser: multipart/form-data → r.ParseMultipartForm, everything else +// → r.ParseForm (stdlib's parsePostForm only actually reads the body +// when Content-Type is application/x-www-form-urlencoded, so calling +// ParseForm is safe for unrecognised types). +// +// Caveat: ParseMultipartForm calls ParseForm internally and discards its error +// when the body turns out not to be multipart, returning ErrNotMultipart instead +// — the subsequent retry then short-circuits because r.PostForm is already +// set. Content-type-based routing avoids the lossy detour. +// +// Returns the raw stdlib error on failure; the caller (BindForm) +// handles HTTP-aware wrapping (413 for MaxBytesError, 400 ParseError +// otherwise). +// +// maxMemory == 0 falls through to the stdlib default (32 MB). +// maxBody == 0 defaults to DefaultMaxUploadBodySize; maxBody < 0 +// disables the body cap (caller has capped upstream). +func parseFormBody(r *http.Request, maxMemory, maxBody int64) error { + if r.Body != nil && maxBody >= 0 { + if maxBody == 0 { + maxBody = DefaultMaxUploadBodySize + } + r.Body = http.MaxBytesReader(nil, r.Body, maxBody) + } + + mt, _, _ := ContentType(r.Header) + if mt == MultipartFormMime { + //nolint:gosec // G120: false positive -- see below + // gosec doesn't track the Body. + // See https://github.com/securego/gosec/blob/de65614d10a6b84029e3e1215567b8ce7e490f23/testutils/g120_samples.go#L57 + return r.ParseMultipartForm(maxMemory) + } + return r.ParseForm() +} + +func countFileParts(r *http.Request) int { + if r.MultipartForm == nil { + return 0 + } + var n int + for _, fhs := range r.MultipartForm.File { + n += len(fhs) + } + + return n +} + +// FormFile resolves a file field from a parsed form body, transparently +// handling both content types accepted for `type: file` parameters by +// the OpenAPI 2.0 spec: +// +// - multipart/form-data — delegates to [http.Request.FormFile]. +// - application/x-www-form-urlencoded — looks up the field in +// r.PostForm and synthesizes a [multipart.File] backed by the +// value bytes plus a [multipart.FileHeader] with Filename equal +// to the field name and Size set to the byte length. +// +// Returns [http.ErrMissingFile] when the field is absent under either +// content type. Callers must have parsed the body upstream (e.g. via +// [BindForm] or [http.Request.ParseForm]) before reading from the +// urlencoded path — [http.Request.FormFile] takes care of parsing on +// the multipart path. +// +// Presence is the only criterion for binding a urlencoded file: an +// empty value (e.g. `file=`) is bound as a zero-byte file. +func FormFile(r *http.Request, name string) (multipart.File, *multipart.FileHeader, error) { + file, header, err := r.FormFile(name) + if err == nil { + return file, header, nil + } + if !stderrors.Is(err, http.ErrNotMultipart) { + return nil, nil, err + } + + values, present := r.PostForm[name] + if !present { + return nil, nil, http.ErrMissingFile + } + value := values[0] + return urlencodedFile{Reader: strings.NewReader(value)}, + &multipart.FileHeader{Filename: name, Size: int64(len(value))}, + nil +} + +// urlencodedFile adapts a urlencoded form value (already buffered in +// memory by [http.Request.ParseForm]) to the [multipart.File] +// interface. The embedded [strings.Reader] supplies Read/ReadAt/Seek; +// Close is a no-op since there is no resource to release. +type urlencodedFile struct { + *strings.Reader +} + +func (urlencodedFile) Close() error { return nil } + +func bindFormFile(r *http.Request, spec formFileSpec, maxFilenameLen int) error { + file, header, err := FormFile(r, spec.name) + if err != nil { + if stderrors.Is(err, http.ErrMissingFile) { + if spec.required { + return errors.New(http.StatusBadRequest, "formData: %v", http.ErrMissingFile) + } + + return nil + } + + return errors.NewParseError(spec.name, "formData", "", err) + } + + if err := ValidateFilenameLength(spec.name, "formData", header.Filename, maxFilenameLen); err != nil { + return err + } + + if spec.bind == nil { + return nil + } + + return spec.bind(file, header) +} diff --git a/vendor/github.com/go-openapi/runtime/go.work b/vendor/github.com/go-openapi/runtime/go.work index efa29dcac20..73479f9ad8f 100644 --- a/vendor/github.com/go-openapi/runtime/go.work +++ b/vendor/github.com/go-openapi/runtime/go.work @@ -1,6 +1,8 @@ use ( . ./client-middleware/opentracing + ./docs/examples + ./server-middleware ) go 1.25.0 diff --git a/vendor/github.com/go-openapi/runtime/go.work.sum b/vendor/github.com/go-openapi/runtime/go.work.sum deleted file mode 100644 index eaf8fddf6b9..00000000000 --- a/vendor/github.com/go-openapi/runtime/go.work.sum +++ /dev/null @@ -1,119 +0,0 @@ -github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/go-openapi/errors v0.22.2/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0= -github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= -github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= -github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= -github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= -github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= -github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= -github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= -github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= -github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= -github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= -github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= -github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= -github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= -github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= -github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM= -github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -golang.org/x/telemetry v0.0.0-20250807160809-1a19826ec488/go.mod h1:fGb/2+tgXXjhjHsTNdVEEMZNWA0quBnfrO+AfoDSAKw= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= -golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/go-openapi/runtime/interfaces.go b/vendor/github.com/go-openapi/runtime/interfaces.go index a8b4b318d9c..85211989078 100644 --- a/vendor/github.com/go-openapi/runtime/interfaces.go +++ b/vendor/github.com/go-openapi/runtime/interfaces.go @@ -99,3 +99,25 @@ type Validatable interface { type ContextValidatable interface { ContextValidate(context.Context, strfmt.Registry) error } + +// ContentTyper is implemented by values that declare their own MIME +// content type. The client runtime consults it in two places: +// +// - on a body payload set via [SetBodyParam]: when the payload is a +// stream (io.Reader, io.ReadCloser) and ContentType returns a +// non-empty value, that value becomes the wire Content-Type +// header instead of the operation's picked consumes entry. +// +// - on individual file values inside a multipart upload: their per- +// part Content-Type header is taken from ContentType() rather +// than sniffed via http.DetectContentType. +// +// An empty string return is treated as "no opinion" and the runtime +// falls back to its default selection. Values that have no content +// type to declare may simply not implement the interface. +// +// See docs/MEDIA_TYPES.md for the full client-side selection +// algorithm. +type ContentTyper interface { + ContentType() string +} diff --git a/vendor/github.com/go-openapi/runtime/middleware/context.go b/vendor/github.com/go-openapi/runtime/middleware/context.go index 1f85e86b538..12abfd4829d 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/context.go +++ b/vendor/github.com/go-openapi/runtime/middleware/context.go @@ -5,10 +5,9 @@ package middleware import ( stdContext "context" + stderrors "errors" "fmt" "net/http" - "net/url" - "path" "strings" "sync" @@ -17,19 +16,21 @@ import ( "github.com/go-openapi/loads" "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag/typeutils" "github.com/go-openapi/runtime" "github.com/go-openapi/runtime/logger" "github.com/go-openapi/runtime/middleware/untyped" "github.com/go-openapi/runtime/security" + "github.com/go-openapi/runtime/server-middleware/docui" + "github.com/go-openapi/runtime/server-middleware/mediatype" + "github.com/go-openapi/runtime/server-middleware/negotiate" ) // Debug when true turns on verbose logging. var Debug = logger.DebugEnabled() // Logger is the standard library logger used for printing debug messages. -// -// (Note: The correct spelling is "library", not "libra". "Libra" is a zodiac sign/constellation and wouldn't make sense in this context.) var Logger logger.Logger = logger.StandardLogger{} func debugLogfFunc(lg logger.Logger) func(string, ...any) { @@ -75,11 +76,103 @@ func (fn ResponderFunc) WriteResponse(rw http.ResponseWriter, pr runtime.Produce // used throughout to store request context with the standard context attached // to the [http.Request]. type Context struct { - spec *loads.Document - analyzer *analysis.Spec - api RoutableAPI - router Router - debugLogf func(string, ...any) // a logging function to debug context and all components using it + spec *loads.Document + analyzer *analysis.Spec + api RoutableAPI + router Router + debugLogf func(string, ...any) // a logging function to debug context and all components using it + ignoreParameters bool // see SetIgnoreParameters / WithIgnoreParameters + matchSuffix bool // see SetMatchSuffix / WithMatchSuffix +} + +// NewRoutableContext creates a new context for a routable API. +// +// If a nil Router is provided, the [DefaultRouter] ([denco]-based) will be used. +func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Router) *Context { + var an *analysis.Spec + if spec != nil { + an = analysis.New(spec.Spec()) + } + + return NewRoutableContextWithAnalyzedSpec(spec, an, routableAPI, routes) +} + +// NewRoutableContextWithAnalyzedSpec is like [NewRoutableContext] but takes as input an already analysed spec. +// +// If a nil Router is provided, the [DefaultRouter] ([denco]-based) will be used. +func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context { + // Either there are no spec doc and analysis, or both of them. + if (spec != nil || an != nil) && (spec == nil || an == nil) { + panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them")) + } + + return &Context{ + spec: spec, + api: routableAPI, + analyzer: an, + router: routes, + debugLogf: debugLogfFunc(nil), + } +} + +// NewContext creates a new context wrapper. +// +// If a nil Router is provided, the [DefaultRouter] ([denco]-based) will be used. +func NewContext(spec *loads.Document, api *untyped.API, routes Router) *Context { + var an *analysis.Spec + if spec != nil { + an = analysis.New(spec.Spec()) + } + ctx := &Context{ + spec: spec, + analyzer: an, + router: routes, + debugLogf: debugLogfFunc(nil), + } + ctx.api = newRoutableUntypedAPI(spec, api, ctx) + + return ctx +} + +// Serve serves the specified spec with the specified api registrations as a [http.Handler]. +func Serve(spec *loads.Document, api *untyped.API) http.Handler { + return ServeWithBuilder(spec, api, PassthroughBuilder) +} + +// SetIgnoreParameters toggles the legacy parameter-stripping behaviour for +// Accept negotiation server-wide. When set, every internal call to +// [NegotiateContentType] from this Context applies [WithIgnoreParameters]. +// +// Returns the receiver for fluent configuration: +// +// ctx := middleware.NewContext(spec, api, nil).SetIgnoreParameters(true) +// +// See [WithIgnoreParameters] for the rationale and an example. +func (c *Context) SetIgnoreParameters(ignore bool) *Context { + c.ignoreParameters = ignore + + return c +} + +// SetMatchSuffix toggles RFC 6839 structured-syntax suffix tolerance +// server-wide. When enabled, both Accept negotiation and codec lookup +// fall back through the suffix base for the recognised suffixes +// (+json, +xml, +yaml) — so an operation declaring +// consumes: [application/json] also accepts request bodies sent with +// Content-Type: application/vnd.api+json (or any other +json variant). +// +// Default: strict (false). Use only when interoperating with clients +// that do not strictly abide by the spec. +// +// Returns the receiver for fluent configuration: +// +// ctx := middleware.NewContext(spec, api, nil).SetMatchSuffix(true) +// +// See [negotiate.WithMatchSuffix] for the per-call form and rationale. +func (c *Context) SetMatchSuffix(enable bool) *Context { + c.matchSuffix = enable + + return c } type routableUntypedAPI struct { @@ -95,53 +188,57 @@ func newRoutableUntypedAPI(spec *loads.Document, api *untyped.API, context *Cont if spec == nil || api == nil { return nil } + analyzer := analysis.New(spec.Spec()) for method, hls := range analyzer.Operations() { um := strings.ToUpper(method) for path, op := range hls { schemes := analyzer.SecurityRequirementsFor(op) - if oh, ok := api.OperationHandlerFor(method, path); ok { - if handlers == nil { - handlers = make(map[string]map[string]http.Handler) + oh, ok := api.OperationHandlerFor(method, path) + if !ok { + continue + } + + if handlers == nil { + handlers = make(map[string]map[string]http.Handler) + } + if b, ok := handlers[um]; !ok || b == nil { + handlers[um] = make(map[string]http.Handler) + } + + var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // lookup route info in the context + route, rCtx, _ := context.RouteInfo(r) + if rCtx != nil { + r = rCtx } - if b, ok := handlers[um]; !ok || b == nil { - handlers[um] = make(map[string]http.Handler) + + // bind and validate the request using reflection + var bound any + var validation error + bound, r, validation = context.BindAndValidate(r, route) + if validation != nil { + context.Respond(w, r, route.Produces, route, validation) + return } - var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // lookup route info in the context - route, rCtx, _ := context.RouteInfo(r) - if rCtx != nil { - r = rCtx - } - - // bind and validate the request using reflection - var bound any - var validation error - bound, r, validation = context.BindAndValidate(r, route) - if validation != nil { - context.Respond(w, r, route.Produces, route, validation) - return - } - - // actually handle the request - result, err := oh.Handle(bound) - if err != nil { - // respond with failure - context.Respond(w, r, route.Produces, route, err) - return - } - - // respond with success - context.Respond(w, r, route.Produces, route, result) - }) - - if len(schemes) > 0 { - handler = newSecureAPI(context, handler) + // actually handle the request + result, err := oh.Handle(bound) + if err != nil { + // respond with failure + context.Respond(w, r, route.Produces, route, err) + return } - handlers[um][path] = handler + + // respond with success + context.Respond(w, r, route.Produces, route, result) + }) + + if len(schemes) > 0 { + handler = newSecureAPI(context, handler) } + handlers[um][path] = handler } } @@ -192,60 +289,6 @@ func (r *routableUntypedAPI) DefaultConsumes() string { return r.defaultConsumes } -// NewRoutableContext creates a new context for a routable API. -// -// If a nil Router is provided, the [DefaultRouter] ([denco]-based) will be used. -func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Router) *Context { - var an *analysis.Spec - if spec != nil { - an = analysis.New(spec.Spec()) - } - - return NewRoutableContextWithAnalyzedSpec(spec, an, routableAPI, routes) -} - -// NewRoutableContextWithAnalyzedSpec is like [NewRoutableContext] but takes as input an already analysed spec. -// -// If a nil Router is provided, the [DefaultRouter] ([denco]-based) will be used. -func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context { - // Either there are no spec doc and analysis, or both of them. - if (spec != nil || an != nil) && (spec == nil || an == nil) { - panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them")) - } - - return &Context{ - spec: spec, - api: routableAPI, - analyzer: an, - router: routes, - debugLogf: debugLogfFunc(nil), - } -} - -// NewContext creates a new context wrapper. -// -// If a nil Router is provided, the [DefaultRouter] ([denco]-based) will be used. -func NewContext(spec *loads.Document, api *untyped.API, routes Router) *Context { - var an *analysis.Spec - if spec != nil { - an = analysis.New(spec.Spec()) - } - ctx := &Context{ - spec: spec, - analyzer: an, - router: routes, - debugLogf: debugLogfFunc(nil), - } - ctx.api = newRoutableUntypedAPI(spec, api, ctx) - - return ctx -} - -// Serve serves the specified spec with the specified api registrations as a [http.Handler]. -func Serve(spec *loads.Document, api *untyped.API) http.Handler { - return ServeWithBuilder(spec, api, PassthroughBuilder) -} - // ServeWithBuilder serves the specified spec with the specified api registrations as a [http.Handler] that is decorated // by the Builder. func ServeWithBuilder(spec *loads.Document, api *untyped.API, builder Builder) http.Handler { @@ -319,57 +362,42 @@ func (c *Context) RequiredProduces() []string { // BindValidRequest binds a params object to a request but only when the request is valid // if the request is not valid an error will be returned. func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, binder RequestBinder) error { - var res []error var requestContentType string // check and validate content type, select consumer if runtime.HasBody(request) { - ct, _, err := runtime.ContentType(request.Header) + ct, cons, err := c.bindRequestBody(request, route) if err != nil { - res = append(res, err) - } else { - c.debugLogf("validating content type for %q against [%s]", ct, strings.Join(route.Consumes, ", ")) - if err := validateContentType(route.Consumes, ct); err != nil { - res = append(res, err) - } - if len(res) == 0 { - cons, ok := route.Consumers[ct] - if !ok { - res = append(res, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct)) - } else { - route.Consumer = cons - requestContentType = ct - } - } + return errors.CompositeValidationError(err) } + + // happy path + requestContentType = ct + route.Consumer = cons } // check and validate the response format - if len(res) == 0 { - // if the route does not provide Produces and a default contentType could not be identified - // based on a body, typical for GET and DELETE requests, then default contentType to. - if len(route.Produces) == 0 && requestContentType == "" { - requestContentType = "*/*" - } + // if the route does not provide Produces and a default contentType could not be identified + // based on a body, typical for GET and DELETE requests, then default contentType to. + if len(route.Produces) == 0 && requestContentType == "" { + requestContentType = "*/*" + } - if str := NegotiateContentType(request, route.Produces, requestContentType); str == "" { - res = append(res, errors.InvalidResponseFormat(request.Header.Get(runtime.HeaderAccept), route.Produces)) - } + str := negotiate.ContentType(request, route.Produces, requestContentType, c.negotiateOpts()...) + if str == "" { + return errors.CompositeValidationError( + errors.InvalidResponseFormat(request.Header.Get(runtime.HeaderAccept), route.Produces), + ) + } + + if binder == nil { + return nil } // now bind the request with the provided binder // it's assumed the binder will also validate the request and return an error if the // request is invalid - if binder != nil && len(res) == 0 { - if err := binder.BindRequest(request, route); err != nil { - return err - } - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil + return binder.BindRequest(request, route) } // ContentType gets the parsed value of a content type @@ -414,6 +442,7 @@ func (c *Context) RouteInfo(request *http.Request) (*MatchedRoute, *http.Request if route, ok := c.LookupRoute(request); ok { rCtx = stdContext.WithValue(rCtx, ctxMatchedRoute, route) + request.Pattern = route.BasePath + route.PathPattern return route, request.WithContext(rCtx), ok } @@ -431,7 +460,7 @@ func (c *Context) ResponseFormat(r *http.Request, offers []string) (string, *htt return v, r } - format := NegotiateContentType(r, offers, "") + format := negotiate.ContentType(r, offers, "", c.negotiateOpts()...) if format != "" { c.debugLogf("[%s %s] set response format %q in context", r.Method, r.URL.Path, format) r = r.WithContext(stdContext.WithValue(rCtx, ctxResponseFormat, format)) @@ -453,44 +482,6 @@ func (c *Context) ResetAuth(request *http.Request) *http.Request { return request.WithContext(rctx) } -// Authorize authorizes the request -// Returns the principal object and a shallow copy of the request when its -// context doesn't contain the principal, otherwise the same request or an error -// (the last) if one of the authenticators returns one or an Unauthenticated error. -func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (any, *http.Request, error) { - if route == nil || !route.HasAuth() { - return nil, nil, nil - } - - var rCtx = request.Context() - if v := rCtx.Value(ctxSecurityPrincipal); v != nil { - return v, request, nil - } - - applies, usr, err := route.Authenticators.Authenticate(request, route) - if !applies || err != nil || !route.Authenticators.AllowsAnonymous() && usr == nil { - if err != nil { - return nil, nil, err - } - return nil, nil, errors.Unauthenticated("invalid credentials") - } - if route.Authorizer != nil { - if err := route.Authorizer.Authorize(request, usr); err != nil { - if _, ok := err.(errors.Error); ok { - return nil, nil, err - } - - return nil, nil, errors.New(http.StatusForbidden, "%v", err) - } - } - - rCtx = request.Context() - - rCtx = stdContext.WithValue(rCtx, ctxSecurityPrincipal, usr) - rCtx = stdContext.WithValue(rCtx, ctxSecurityScopes, route.Authenticator.AllScopes()) - return usr, request.WithContext(rCtx), nil -} - // BindAndValidate binds and validates the request // Returns the validation map and a shallow copy of the request when its context // doesn't contain the validation, otherwise it returns the same request or an @@ -523,91 +514,29 @@ func (c *Context) NotFound(rw http.ResponseWriter, r *http.Request) { // Respond renders the response after doing some content negotiation. func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []string, route *MatchedRoute, data any) { c.debugLogf("responding to %s %s with produces: %v", r.Method, r.URL.Path, produces) - offers := []string{} - for _, mt := range produces { - if mt != c.api.DefaultProduces() { - offers = append(offers, mt) - } - } - // the default producer is last so more specific producers take precedence - offers = append(offers, c.api.DefaultProduces()) - c.debugLogf("offers: %v", offers) + offers := c.buildOffers(produces) var format string format, r = c.ResponseFormat(r, offers) rw.Header().Set(runtime.HeaderContentType, format) if resp, ok := data.(Responder); ok { - producers := route.Producers - // producers contains keys with normalized format, if a format has MIME type parameter such as `text/plain; charset=utf-8` - // then you must provide `text/plain` to get the correct producer. HOWEVER, format here is not normalized. - prod, ok := producers[normalizeOffer(format)] - if !ok { - prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()})) - pr, ok := prods[c.api.DefaultProduces()] - if !ok { - panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format))) - } - prod = pr - } - resp.WriteResponse(rw, prod) + c.respondWithResponder(rw, r, route, resp, format) return } if err, ok := data.(error); ok { - if format == "" { - rw.Header().Set(runtime.HeaderContentType, runtime.JSONMime) - } - - if realm := security.FailedBasicAuth(r); realm != "" { - rw.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", realm)) - } - - if route == nil || route.Operation == nil { - c.api.ServeErrorFor("")(rw, r, err) - return - } - c.api.ServeErrorFor(route.Operation.ID)(rw, r, err) + c.respondWithError(rw, r, produces, route, err, format) return } if route == nil || route.Operation == nil { - rw.WriteHeader(http.StatusOK) - if r.Method == http.MethodHead { - return - } - producers := c.api.ProducersFor(normalizeOffers(offers)) - prod, ok := producers[format] - if !ok { - panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format))) - } - if err := prod.Produce(rw, data); err != nil { - panic(err) // let the recovery middleware deal with this - } + c.respondWithoutCode(rw, r, data, format, offers) return } if _, code, ok := route.Operation.SuccessResponse(); ok { - rw.WriteHeader(code) - if code == http.StatusNoContent || r.Method == http.MethodHead { - return - } - - producers := route.Producers - prod, ok := producers[format] - if !ok { - if !ok { - prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()})) - pr, ok := prods[c.api.DefaultProduces()] - if !ok { - panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format))) - } - prod = pr - } - } - if err := prod.Produce(rw, data); err != nil { - panic(err) // let the recovery middleware deal with this - } + c.respondWithCode(rw, r, route, code, data, format) return } @@ -618,57 +547,76 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st // // This handler includes a swagger spec, router and the contract defined in the swagger spec. // -// A spec UI ([SwaggerUI]) is served at {API base path}/docs and the spec document at /swagger.json -// (these can be modified with uiOptions). +// A spec UI ([docui.SwaggerUI]) is served at {API base path}/docs and the spec document at /swagger.json +// (these can be modified with combined [UIOption]). +// +// Deprecated: use [Context.APIHandlerWithUI] with [docui.SwaggerUI] middleware instead. func (c *Context) APIHandlerSwaggerUI(builder Builder, opts ...UIOption) http.Handler { - b := builder - if b == nil { - b = PassthroughBuilder - } - - specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts) - var swaggerUIOpts SwaggerUIOpts - fromCommonToAnyOptions(uiOpts, &swaggerUIOpts) - - return Spec(specPath, c.spec.Raw(), SwaggerUI(swaggerUIOpts, c.RoutesHandler(b)), specOpts...) + return c.APIHandlerWithUI(builder, docui.UseSwaggerUI, c.uiOptionsForHandler(opts)...) } // APIHandlerRapiDoc returns a handler to serve the API. // // This handler includes a swagger spec, router and the contract defined in the swagger spec. // -// A spec UI ([RapiDoc]) is served at {API base path}/docs and the spec document at /swagger.json -// (these can be modified with uiOptions). +// A spec UI ([docui.RapiDoc]) is served at {API base path}/docs and the spec document at /swagger.json +// (these can be modified with combined [UIOption]). +// +// Deprecated: use [Context.APIHandlerWithUI] with [docui.UseRapiDoc] middleware instead. func (c *Context) APIHandlerRapiDoc(builder Builder, opts ...UIOption) http.Handler { - b := builder - if b == nil { - b = PassthroughBuilder - } - - specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts) - var rapidocUIOpts RapiDocOpts - fromCommonToAnyOptions(uiOpts, &rapidocUIOpts) - - return Spec(specPath, c.spec.Raw(), RapiDoc(rapidocUIOpts, c.RoutesHandler(b)), specOpts...) + return c.APIHandlerWithUI(builder, docui.UseRapiDoc, c.uiOptionsForHandler(opts)...) } // APIHandler returns a handler to serve the API. // // This handler includes a swagger spec, router and the contract defined in the swagger spec. // -// A spec UI ([Redoc]) is served at {API base path}/docs and the spec document at /swagger.json -// (these can be modified with uiOptions). +// A spec UI ([docui.Redoc]) is served at {API base path}/docs and the spec document at /swagger.json +// (these can be modified with combined [UIOption]). +// +// Notice that you may use [Context.APIHandlerWithUI] to use an alternate UI-serving middleware. func (c *Context) APIHandler(builder Builder, opts ...UIOption) http.Handler { + return c.APIHandlerWithUI(builder, docui.UseRedoc, c.uiOptionsForHandler(opts)...) +} + +// APIHandlerWithUI returns a handler to serve the API with a swagger spec and a UI. +// +// This handler includes a swagger spec, router and the contract defined in the swagger spec. +// +// A spec UI is served at {API base path}/docs and the spec document at /swagger.json +// (these can be modified with combined [UIOption]). +// +// Notice that any function that accepts the [docui.Option] set and returns a valid middleware may be injected here. +// +// [Context.APIHandlerWithUI] extends [Context.APIHandler], and supersedes [Context.APIHandlerRapiDoc] and [Context.APIHandlerSwaggerUI]. +func (c *Context) APIHandlerWithUI(builder Builder, uiMiddleware docui.UIMiddleware, opts ...docui.Option) http.Handler { b := builder if b == nil { b = PassthroughBuilder } - specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts) - var redocOpts RedocOpts - fromCommonToAnyOptions(uiOpts, &redocOpts) + // the UI titles defaults to the title in the spec + const extraOptions = 2 + prepend := make([]docui.Option, 0, len(opts)+extraOptions) + var title string - return Spec(specPath, c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)), specOpts...) + sp := c.spec.Spec() + if sp != nil && sp.Info != nil && sp.Info.Title != "" { + title = sp.Info.Title + } + if title != "" { + prepend = append(prepend, docui.WithUITitle(title)) + } + + prepend = append(prepend, docui.WithUIBasePath(c.BasePath())) + prepend = append(prepend, opts...) + + // aligns spec serve path with UI setting to fetch spec document. + return docui.UseSpec(c.spec.Raw(), docui.WithSpecPathFromOptions(prepend...))( + uiMiddleware(prepend...)( + c.RoutesHandler(b), + ), + ) } // RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec. @@ -680,37 +628,192 @@ func (c *Context) RoutesHandler(builder Builder) http.Handler { return NewRouter(c, b(NewOperationExecutor(c))) } -func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []SpecOption) { - var title string - sp := c.spec.Spec() - if sp != nil && sp.Info != nil && sp.Info.Title != "" { - title = sp.Info.Title +// authorizeImpl is the real authentication+authorization body shared +// between the production and dev-only variants of [Context.Authorize]. +// See context_skipauth_disabled.go (default build) and +// context_skipauth_enabled.go (the `openapi_unsafe_skipauth` build tag). +// +// The doc on the exported Authorize describes the user-facing +// contract; this function MUST NOT change semantics for the +// production path. +func (c *Context) authorizeImpl(request *http.Request, route *MatchedRoute) (any, *http.Request, error) { + if route == nil || !route.HasAuth() { + return nil, nil, nil } - // default options (may be overridden) - const baseOptions = 2 - optsForContext := make([]UIOption, 0, len(opts)+baseOptions) - optsForContext = append(optsForContext, - WithUIBasePath(c.BasePath()), - WithUITitle(title), - ) - optsForContext = append(optsForContext, opts...) - uiOpts := uiOptionsWithDefaults(optsForContext) + var rCtx = request.Context() + if v := rCtx.Value(ctxSecurityPrincipal); v != nil { + return v, request, nil + } + + applies, usr, err := route.Authenticators.Authenticate(request, route) + if !applies || err != nil || !route.Authenticators.AllowsAnonymous() && typeutils.IsZero(usr) { + if err != nil { + return nil, nil, err + } + return nil, nil, errors.Unauthenticated("invalid credentials") + } + if route.Authorizer != nil { + if err := route.Authorizer.Authorize(request, usr); err != nil { + var apiError errors.Error + if stderrors.As(err, &apiError) { + return nil, nil, err + } + + return nil, nil, errors.New(http.StatusForbidden, "%v", err) + } + } + + rCtx = request.Context() + + rCtx = stdContext.WithValue(rCtx, ctxSecurityPrincipal, usr) + rCtx = stdContext.WithValue(rCtx, ctxSecurityScopes, route.Authenticator.AllScopes()) + return usr, request.WithContext(rCtx), nil +} + +func (c *Context) bindRequestBody(request *http.Request, route *MatchedRoute) (string, runtime.Consumer, error) { + ct, _, err := runtime.ContentType(request.Header) + if err != nil { + return "", nil, err + } + + c.debugLogf("validating content type for %q against [%s]", ct, strings.Join(route.Consumes, ", ")) + if err := validateContentType(route.Consumes, ct); err != nil { + return "", nil, err + } + + cons, ok := mediatype.Lookup(route.Consumers, ct, c.matchOpts()...) + if !ok { + return "", nil, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct) + } + + return ct, cons, nil +} + +func (c *Context) respondWithResponder(rw http.ResponseWriter, r *http.Request, route *MatchedRoute, resp Responder, format string) { + _ = r + producers := route.Producers + + // producers contains keys with normalized format, if a format has MIME type parameter such as `text/plain; charset=utf-8` + // then you must provide `text/plain` to get the correct producer. HOWEVER, format here is not normalized. + prod, ok := producers[normalizeOffer(format)] + if !ok { + prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()})) + pr, ok := prods[c.api.DefaultProduces()] + if !ok { + panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format))) + } + prod = pr + } + + resp.WriteResponse(rw, prod) +} + +func (c *Context) respondWithError(rw http.ResponseWriter, r *http.Request, produces []string, route *MatchedRoute, err error, format string) { + _ = produces + + if format == "" { + rw.Header().Set(runtime.HeaderContentType, runtime.JSONMime) + } + + if realm := security.FailedBasicAuth(r); realm != "" { + rw.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", realm)) + } + + if route == nil || route.Operation == nil { + c.api.ServeErrorFor("")(rw, r, err) + return + } + + c.api.ServeErrorFor(route.Operation.ID)(rw, r, err) +} + +func (c *Context) respondWithoutCode(rw http.ResponseWriter, r *http.Request, data any, format string, offers []string) { + rw.WriteHeader(http.StatusOK) + if r.Method == http.MethodHead { + return + } + + producers := c.api.ProducersFor(normalizeOffers(offers)) + prod, ok := producers[format] + if !ok { + panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format))) + } + + if err := prod.Produce(rw, data); err != nil { + panic(err) // let the recovery middleware deal with this + } +} + +func (c *Context) buildOffers(produces []string) []string { + offers := make([]string, 0, len(produces)+1) + + for _, mt := range produces { + if mt != c.api.DefaultProduces() { + offers = append(offers, mt) + } + } + + // the default producer is last so more specific producers take precedence + offers = append(offers, c.api.DefaultProduces()) + c.debugLogf("offers: %v", offers) + + return offers +} + +func (c *Context) respondWithCode(rw http.ResponseWriter, r *http.Request, route *MatchedRoute, code int, data any, format string) { + rw.WriteHeader(code) + if code == http.StatusNoContent || r.Method == http.MethodHead { + return + } + + producers := route.Producers + prod, ok := producers[format] + if !ok { + if !ok { + prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()})) + pr, ok := prods[c.api.DefaultProduces()] + if !ok { + panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format))) + } + prod = pr + } + } - // If spec URL is provided, there is a non-default path to serve the spec. - // This makes sure that the UI middleware is aligned with the Spec middleware. - u, _ := url.Parse(uiOpts.SpecURL) - var specPath string - if u != nil { - specPath = u.Path + if err := prod.Produce(rw, data); err != nil { + panic(err) // let the recovery middleware deal with this } +} + +// uiOptionsForHandler bridges the deprecated [UIOption] set to the new [docui.Option] set. +func (c Context) uiOptionsForHandler(opts []UIOption) []docui.Option { + uiOpts := uiOptionsWithDefaults(opts) - pth, doc := path.Split(specPath) - if pth == "." { - pth = "" + return uiOpts.toFuncOptions() +} + +func (c *Context) negotiateOpts() []negotiate.Option { + var opts []negotiate.Option + if c.ignoreParameters { + opts = append(opts, negotiate.WithIgnoreParameters(true)) + } + if c.matchSuffix { + opts = append(opts, negotiate.WithMatchSuffix(true)) + } + + return opts +} + +// matchOpts builds the mediatype.MatchOption slice that the +// codec-lookup and Content-Type validation paths apply server-wide. +// Mirrors negotiateOpts but at the mediatype level (without going +// through the negotiate.Option wrapper). +func (c *Context) matchOpts() []mediatype.MatchOption { + if !c.matchSuffix { + return nil } - return pth, uiOpts, []SpecOption{WithSpecDocument(doc)} + return []mediatype.MatchOption{mediatype.AllowSuffix()} } func cantFindProducer(format string) string { diff --git a/vendor/github.com/go-openapi/runtime/middleware/context_skipauth_disabled.go b/vendor/github.com/go-openapi/runtime/middleware/context_skipauth_disabled.go new file mode 100644 index 00000000000..c8cd01a4343 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/middleware/context_skipauth_disabled.go @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +//go:build !openapi_unsafe_skipauth + +package middleware + +import "net/http" + +// Authorize authorizes the request. +// +// Returns the principal object and a shallow copy of the request when its +// context doesn't contain the principal, otherwise the same request or an error +// (the last) if one of the authenticators returns one or an Unauthenticated error. +// +// This is the production variant — compiled when the build tag +// `openapi_unsafe_skipauth` is NOT set. There is no skip-auth check +// in this codepath; the field, setter, and storage for the bypass +// flag are entirely absent from the binary. See the alternate +// implementation in context_skipauth_enabled.go for the dev-only +// bypass mechanism. +func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (any, *http.Request, error) { + return c.authorizeImpl(request, route) +} diff --git a/vendor/github.com/go-openapi/runtime/middleware/context_skipauth_enabled.go b/vendor/github.com/go-openapi/runtime/middleware/context_skipauth_enabled.go new file mode 100644 index 00000000000..2ac87068187 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/middleware/context_skipauth_enabled.go @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +//go:build openapi_unsafe_skipauth + +package middleware + +import ( + "log" + "net/http" + "sync/atomic" +) + +// skipAuthEnabled holds the process-wide skip-auth flag. It only +// exists in binaries built with the `openapi_unsafe_skipauth` tag — +// production binaries (built without the tag) have no field, no +// setter, no storage, and no skip-checking branch in [Context.Authorize]. +// Reflection, unsafe-pointer arithmetic, or a debugger cannot flip +// what is not in the binary. +var skipAuthEnabled atomic.Bool + +// SetSkipAuth toggles a PROCESS-WIDE bypass of authentication AND +// authorization for every operation served by every Context in the +// running program. +// +// DANGER: this disables ALL authentication and ALL authorization. +// Every request to every secured endpoint runs as if it had been +// authorized with a nil principal. Use ONLY on developer +// workstations during early prototyping (e.g. while +// authentication is not yet wired up). +// +// This function exists only when the build tag +// `openapi_unsafe_skipauth` is set: +// +// go build -tags openapi_unsafe_skipauth ./... +// +// Production CI MUST NOT pass this tag. Calls compile to a symbol +// that does not exist in production binaries. +// +// Calling with true emits a one-line WARNING via the stdlib `log` +// package (stderr by default) so the bypass is visible at startup. +// Calling with false silently disables it. +func SetSkipAuth(skip bool) { + skipAuthEnabled.Store(skip) + if skip { + log.Println("WARNING: go-openapi/runtime: SetSkipAuth(true) — authentication and authorization are bypassed for ALL operations. This MUST NOT run in production.") + } +} + +// Authorize is the dev-build variant of the production +// [Context.Authorize] (see context_skipauth_disabled.go for the +// production path). When [SetSkipAuth] has enabled the bypass, this +// returns a nil principal with the original request and no error — +// handlers downstream receive a nil-value principal. Otherwise it +// delegates to the standard authentication+authorization body. +func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (any, *http.Request, error) { + if skipAuthEnabled.Load() { + return nil, request, nil + } + return c.authorizeImpl(request, route) +} diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go index f89d761cf2a..e380a138d50 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go +++ b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go @@ -9,6 +9,7 @@ package denco import ( "errors" "fmt" + "slices" "sort" "strings" ) @@ -29,8 +30,8 @@ const ( // PathParamCharacter indicates a RESTCONF path param. PathParamCharacter = '=' - // MaxSize is max size of records and internal slice. - MaxSize = (1 << 22) - 1 //nolint:mnd + // MaxSize is the maximum size of records and internal slice (encoded over 22 bits). + MaxSize = (1 << baseBits) - 1 ) // Router represents a URL router. @@ -53,9 +54,12 @@ func New() *Router { } } -// Lookup returns data and path parameters that associated with path. +// Lookup returns data and path parameters which are associated to the path. +// // params is a slice of the [Param] that arranged in the order in which parameters appeared. -// e.g. when built routing path is "/path/to/:id/:name" and given path is "/path/to/1/alice". params order is [{"id": "1"}, {"name": "alice"}], not [{"name": "alice"}, {"id": "1"}]. +// +// e.g. when built routing path is "/path/to/:id/:name" and given path is "/path/to/1/alice", +// params order is [{"id": "1"}, {"name": "alice"}], not [{"name": "alice"}, {"id": "1"}]. func (rt *Router) Lookup(path string) (data any, params Params, found bool) { if data, found = rt.static[path]; found { return data, nil, true @@ -144,6 +148,7 @@ func newDoubleArray() *doubleArray { type baseCheck uint32 const ( + baseBits = 22 flagsBits = 10 checkBits = 8 ) @@ -157,7 +162,7 @@ func (bc *baseCheck) SetBase(base int) { } func (bc baseCheck) Check() byte { - return byte(bc) //nolint:gosec // integer conversion is ok + return byte(bc) //nolint:gosec // integer conversion is ok: we pick the last 8 bits } func (bc *baseCheck) SetCheck(check byte) { @@ -213,8 +218,8 @@ func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Pa } BACKTRACKING: - for j := len(indices) - 1; j >= 0; j-- { - i, idx := int(indices[j]>>indexOffset), int(indices[j]&indexMask) + for _, j := range slices.Backward(indices) { + i, idx := int(j>>indexOffset), int(j&indexMask) if da.bc[idx].IsSingleParam() { nextIdx := nextIndex(da.bc[idx].Base(), ParamCharacter) if nextIdx >= len(da.bc) { diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/server.go b/vendor/github.com/go-openapi/runtime/middleware/denco/server.go index e6c0976d8b2..3bbbc679d92 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/denco/server.go +++ b/vendor/github.com/go-openapi/runtime/middleware/denco/server.go @@ -9,7 +9,7 @@ import ( "net/http" ) -// Mux represents a multiplexer for HTTP request. +// Mux represents a multiplexer for HTTP requests. type Mux struct{} // NewMux returns a new [Mux]. @@ -17,27 +17,27 @@ func NewMux() *Mux { return &Mux{} } -// GET is shorthand of [Mux].Handler("GET", path, handler). +// GET is shorthand for [Mux.Handler] ("GET", path, handler). func (m *Mux) GET(path string, handler HandlerFunc) Handler { return m.Handler("GET", path, handler) } -// POST is shorthand of [Mux].Handler("POST", path, handler). +// POST is shorthand for [Mux.Handler] ("POST", path, handler). func (m *Mux) POST(path string, handler HandlerFunc) Handler { return m.Handler("POST", path, handler) } -// PUT is shorthand of [Mux].Handler("PUT", path, handler). +// PUT is shorthand for [Mux.Handler] ("PUT", path, handler). func (m *Mux) PUT(path string, handler HandlerFunc) Handler { return m.Handler("PUT", path, handler) } -// HEAD is shorthand of [Mux].Handler("HEAD", path, handler). +// HEAD is shorthand for [Mux.Handler]("HEAD", path, handler). func (m *Mux) HEAD(path string, handler HandlerFunc) Handler { return m.Handler("HEAD", path, handler) } -// Handler returns a handler for HTTP method. +// Handler returns a [Handler] for a HTTP method. func (m *Mux) Handler(method, path string, handler HandlerFunc) Handler { return Handler{ Method: method, @@ -63,7 +63,7 @@ func (m *Mux) Build(handlers []Handler) (http.Handler, error) { return mux, nil } -// Handler represents a handler of HTTP request. +// Handler represents a handler of HTTP requests. type Handler struct { // Method is an HTTP method. Method string @@ -75,7 +75,7 @@ type Handler struct { Func HandlerFunc } -// HandlerFunc is aliased to type of handler function. +// HandlerFunc is an alias to the handler function, similar to [http.HandlerFunc]. type HandlerFunc func(w http.ResponseWriter, r *http.Request, params Params) type serveMux struct { @@ -88,7 +88,7 @@ func newServeMux() *serveMux { } } -// ServeHTTP implements http.Handler interface. +// ServeHTTP implements the [http.Handler] interface. func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { handler, params := mux.handler(r.Method, r.URL.Path) handler(w, r, params) @@ -97,15 +97,17 @@ func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (mux *serveMux) handler(method, path string) (HandlerFunc, []Param) { if router, found := mux.routers[method]; found { if handler, params, found := router.Lookup(path); found { - return handler.(HandlerFunc), params + return handler.(HandlerFunc), params //nolint:forcetypeassert // type is guaranteed when the path is found } } return NotFound, nil } // NotFound replies to the request with an HTTP 404 not found error. -// NotFound is called when unknown HTTP method or a handler not found. -// If you want to use the your own NotFound handler, please overwrite this variable. +// +// NotFound is called when unknown HTTP methods are being user or a handler not found. +// +// If you want to use your own NotFound handler, please overwrite this variable. var NotFound = func(w http.ResponseWriter, r *http.Request, _ Params) { http.NotFound(w, r) } diff --git a/vendor/github.com/go-openapi/runtime/middleware/negotiate.go b/vendor/github.com/go-openapi/runtime/middleware/negotiate.go deleted file mode 100644 index cb0a85283c1..00000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/negotiate.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -// 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 or at -// https://developers.google.com/open-source/licenses/bsd. - -// this file was taken from the github.com/golang/gddo repository - -package middleware - -import ( - "net/http" - "strings" - - "github.com/go-openapi/runtime/middleware/header" -) - -// NegotiateContentEncoding returns the best offered content encoding for the -// request's Accept-Encoding header. If two offers match with equal weight and -// then the offer earlier in the list is preferred. If no offers are -// acceptable, then "" is returned. -func NegotiateContentEncoding(r *http.Request, offers []string) string { - bestOffer := "identity" - bestQ := -1.0 - specs := header.ParseAccept(r.Header, "Accept-Encoding") - for _, offer := range offers { - for _, spec := range specs { - if spec.Q > bestQ && - (spec.Value == "*" || spec.Value == offer) { - bestQ = spec.Q - bestOffer = offer - } - } - } - if bestQ == 0 { - bestOffer = "" - } - return bestOffer -} - -// NegotiateContentType returns the best offered content type for the request's -// Accept header. If two offers match with equal weight, then the more specific -// offer is preferred. For example, text/* trumps */*. If two offers match -// with equal weight and specificity, then the offer earlier in the list is -// preferred. If no offers match, then defaultOffer is returned. -func NegotiateContentType(r *http.Request, offers []string, defaultOffer string) string { - bestOffer := defaultOffer - bestQ := -1.0 - bestWild := 3 - specs := header.ParseAccept(r.Header, "Accept") - for _, rawOffer := range offers { - offer := normalizeOffer(rawOffer) - // No Accept header: just return the first offer. - if len(specs) == 0 { - return rawOffer - } - for _, spec := range specs { - switch { - case spec.Q == 0.0: - // ignore - case spec.Q < bestQ: - // better match found - case spec.Value == "*/*": - if spec.Q > bestQ || bestWild > 2 { - bestQ = spec.Q - bestWild = 2 - bestOffer = rawOffer - } - case strings.HasSuffix(spec.Value, "/*"): - if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) && - (spec.Q > bestQ || bestWild > 1) { - bestQ = spec.Q - bestWild = 1 - bestOffer = rawOffer - } - default: - if spec.Value == offer && - (spec.Q > bestQ || bestWild > 0) { - bestQ = spec.Q - bestWild = 0 - bestOffer = rawOffer - } - } - } - } - return bestOffer -} - -func normalizeOffers(orig []string) (norm []string) { - for _, o := range orig { - norm = append(norm, normalizeOffer(o)) - } - return -} - -func normalizeOffer(orig string) string { - const maxParts = 2 - return strings.SplitN(orig, ";", maxParts)[0] -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/parameter.go b/vendor/github.com/go-openapi/runtime/middleware/parameter.go index a9d2a36460b..4ae8e3d62d6 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/parameter.go +++ b/vendor/github.com/go-openapi/runtime/middleware/parameter.go @@ -6,7 +6,7 @@ package middleware import ( "encoding" "encoding/base64" - "fmt" + stderrors "errors" "io" "net/http" "reflect" @@ -56,126 +56,153 @@ func (p *untypedParamBinder) Type() reflect.Type { } func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, target reflect.Value) error { - // fmt.Println("binding", p.name, "as", p.Type()) switch p.parameter.In { case "query": - data, custom, hasKey, err := p.readValue(runtime.Values(request.URL.Query()), target) - if err != nil { - return err - } - if custom { - return nil - } - - return p.bindValue(data, hasKey, target) + return p.bindQuery(request, routeParams, consumer, target) case "header": - data, custom, hasKey, err := p.readValue(runtime.Values(request.Header), target) - if err != nil { - return err - } - if custom { - return nil - } - return p.bindValue(data, hasKey, target) + return p.bindHeader(request, routeParams, consumer, target) case "path": - data, custom, hasKey, err := p.readValue(routeParams, target) - if err != nil { - return err - } - if custom { - return nil - } - return p.bindValue(data, hasKey, target) + return p.bindPath(request, routeParams, consumer, target) case "formData": - var err error - var mt string + return p.bindFormData(request, routeParams, consumer, target) - mt, _, e := runtime.ContentType(request.Header) - if e != nil { - // because of the interface conversion go thinks the error is not nil - // so we first check for nil and then set the err var if it's not nil - err = e - } + case "body": + return p.bindBody(request, routeParams, consumer, target) + default: + return errors.New(http.StatusInternalServerError, "invalid parameter location: %q", p.parameter.In) + } +} - if err != nil { - return errors.InvalidContentType("", []string{"multipart/form-data", "application/x-www-form-urlencoded"}) - } +func (p *untypedParamBinder) bindQuery(request *http.Request, _ RouteParams, _ runtime.Consumer, target reflect.Value) error { + data, custom, hasKey, err := p.readValue(runtime.Values(request.URL.Query()), target) + if err != nil { + return err + } + if custom { + return nil + } - if mt != "multipart/form-data" && mt != "application/x-www-form-urlencoded" { - return errors.InvalidContentType(mt, []string{"multipart/form-data", "application/x-www-form-urlencoded"}) - } + return p.bindValue(data, hasKey, target) +} - if mt == "multipart/form-data" { - if err = request.ParseMultipartForm(defaultMaxMemory); err != nil { - return errors.NewParseError(p.Name, p.parameter.In, "", err) - } - } +func (p *untypedParamBinder) bindHeader(request *http.Request, _ RouteParams, _ runtime.Consumer, target reflect.Value) error { + data, custom, hasKey, err := p.readValue(runtime.Values(request.Header), target) + if err != nil { + return err + } + if custom { + return nil + } + return p.bindValue(data, hasKey, target) +} - if err = request.ParseForm(); err != nil { - return errors.NewParseError(p.Name, p.parameter.In, "", err) - } +func (p *untypedParamBinder) bindPath(_ *http.Request, routeParams RouteParams, _ runtime.Consumer, target reflect.Value) error { + data, custom, hasKey, err := p.readValue(routeParams, target) + if err != nil { + return err + } + if custom { + return nil + } + return p.bindValue(data, hasKey, target) +} - if p.parameter.Type == "file" { - file, header, ffErr := request.FormFile(p.parameter.Name) - if ffErr != nil { - if p.parameter.Required { - return errors.NewParseError(p.Name, p.parameter.In, "", ffErr) - } +func (p *untypedParamBinder) bindFormData(request *http.Request, _ RouteParams, _ runtime.Consumer, target reflect.Value) error { + mt, _, ctErr := runtime.ContentType(request.Header) + if ctErr != nil { + return errors.InvalidContentType("", []string{runtime.MultipartFormMime, runtime.URLencodedFormMime}) + } - return nil - } + if mt != runtime.MultipartFormMime && mt != runtime.URLencodedFormMime { + return errors.InvalidContentType(mt, []string{runtime.MultipartFormMime, runtime.URLencodedFormMime}) + } - target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header})) - return nil - } + // Parse via the shared helper. The helper routes on Content-Type + // (multipart/form-data → ParseMultipartForm; all non-multipart types, + // including application/x-www-form-urlencoded, → ParseForm) + // and applies the default 32 MiB body cap via http.MaxBytesReader. + // Idempotent across the per-parameter loop: stdlib short-circuits + // when r.MultipartForm / r.PostForm are already populated. + if _, perr := runtime.BindForm(request, runtime.BindFormMaxParseMemory(defaultMaxMemory)); perr != nil { + return perr + } - if request.MultipartForm != nil { - data, custom, hasKey, rvErr := p.readValue(runtime.Values(request.MultipartForm.Value), target) - if rvErr != nil { - return rvErr - } - if custom { + if p.parameter.Type == "file" { + // runtime.FormFile handles both multipart/form-data and + // application/x-www-form-urlencoded (OpenAPI 2.0 permits + // either consumes for `type: file`), and surfaces a + // missing field as http.ErrMissingFile under both. + file, header, ffErr := runtime.FormFile(request, p.parameter.Name) + if ffErr != nil { + if stderrors.Is(ffErr, http.ErrMissingFile) { + if p.parameter.Required { + return errors.NewParseError(p.Name, p.parameter.In, "", http.ErrMissingFile) + } return nil } - return p.bindValue(data, hasKey, target) + return errors.NewParseError(p.Name, p.parameter.In, "", ffErr) } - data, custom, hasKey, err := p.readValue(runtime.Values(request.PostForm), target) - if err != nil { + + // Mirror the FileHeader.Filename length cap that BindForm + // applies to typed (codegen) paths through BindFormFile, so + // untyped formData bindings get the same protection. + if err := runtime.ValidateFilenameLength(p.Name, p.parameter.In, header.Filename, + runtime.DefaultMaxUploadFilenameLength); err != nil { return err } + + target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header})) + return nil + } + + if request.MultipartForm != nil { + data, custom, hasKey, rvErr := p.readValue(runtime.Values(request.MultipartForm.Value), target) + if rvErr != nil { + return rvErr + } if custom { return nil } return p.bindValue(data, hasKey, target) + } + data, custom, hasKey, err := p.readValue(runtime.Values(request.PostForm), target) + if err != nil { + return err + } + if custom { + return nil + } + return p.bindValue(data, hasKey, target) +} - case "body": - newValue := reflect.New(target.Type()) - if !runtime.HasBody(request) { - if p.parameter.Default != nil { - target.Set(reflect.ValueOf(p.parameter.Default)) - } +func (p *untypedParamBinder) bindBody(request *http.Request, _ RouteParams, consumer runtime.Consumer, target reflect.Value) error { + newValue := reflect.New(target.Type()) + if !runtime.HasBody(request) { + if p.parameter.Default != nil { + target.Set(reflect.ValueOf(p.parameter.Default)) + } + return nil + } + + if err := consumer.Consume(request.Body, newValue.Interface()); err != nil { + if stderrors.Is(err, io.EOF) && p.parameter.Default != nil { + target.Set(reflect.ValueOf(p.parameter.Default)) return nil } - if err := consumer.Consume(request.Body, newValue.Interface()); err != nil { - if err == io.EOF && p.parameter.Default != nil { - target.Set(reflect.ValueOf(p.parameter.Default)) - return nil - } - tpe := p.parameter.Type - if p.parameter.Format != "" { - tpe = p.parameter.Format - } - return errors.InvalidType(p.Name, p.parameter.In, tpe, nil) + tpe := p.parameter.Type + if p.parameter.Format != "" { + tpe = p.parameter.Format } - target.Set(reflect.Indirect(newValue)) - return nil - default: - return fmt.Errorf("%d: invalid parameter location %q", http.StatusInternalServerError, p.parameter.In) + return errors.InvalidType(p.Name, p.parameter.In, tpe, nil) } + + target.Set(reflect.Indirect(newValue)) + + return nil } func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type { @@ -261,20 +288,51 @@ func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflec if p.parameter.Type == typeArray { return p.setSliceFieldValue(target, p.parameter.Default, data, hasKey) } + var d string if len(data) > 0 { d = data[len(data)-1] } + return p.setFieldValue(target, p.parameter.Default, d, hasKey) } -func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue any, data string, hasKey bool) error { //nolint:gocyclo +func (p *untypedParamBinder) isMissingAndRequired(hasKey bool, data string) bool { + return p.parameter.Required && + p.parameter.Default == nil && + (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) +} + +func (p *untypedParamBinder) setByte(target, defVal reflect.Value, tpe, data string) error { + if data == "" { + if target.CanSet() { + target.SetBytes(defVal.Bytes()) + } + + return nil + } + + b, err := base64.StdEncoding.DecodeString(data) + if err != nil { + b, err = base64.URLEncoding.DecodeString(data) + if err != nil { + return errors.InvalidType(p.Name, p.parameter.In, tpe, data) + } + } + if target.CanSet() { + target.SetBytes(b) + } + + return nil +} + +func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue any, data string, hasKey bool) error { tpe := p.parameter.Type if p.parameter.Format != "" { tpe = p.parameter.Format } - if (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) && p.parameter.Required && p.parameter.Default == nil { + if p.isMissingAndRequired(hasKey, data) { return errors.Required(p.Name, p.parameter.In, data) } @@ -292,27 +350,15 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue an } if tpe == "byte" { - if data == "" { - if target.CanSet() { - target.SetBytes(defVal.Bytes()) - } - return nil - } - - b, err := base64.StdEncoding.DecodeString(data) - if err != nil { - b, err = base64.URLEncoding.DecodeString(data) - if err != nil { - return errors.InvalidType(p.Name, p.parameter.In, tpe, data) - } - } - if target.CanSet() { - target.SetBytes(b) - } - return nil + return p.setByte(target, defVal, tpe, data) } - switch target.Kind() { //nolint:exhaustive // we want to check only types that map from a swagger parameter + return p.setReflectFieldValue(target, defVal, tpe, data, hasKey) +} + +//nolint:gocyclo,cyclop // not much we can simplify further significantly: the big case with all types is unavoidable. +func (p *untypedParamBinder) setReflectFieldValue(target, defVal reflect.Value, tpe, data string, hasKey bool) error { + switch target.Kind() { // we want to check only types that map from a swagger parameter case reflect.Bool: if data == "" { if target.CanSet() { @@ -327,6 +373,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue an if target.CanSet() { target.SetBool(b) } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if data == "" { if target.CanSet() { @@ -394,8 +441,8 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue an target.SetString(value) } - case reflect.Ptr: - if data == "" && defVal.Kind() == reflect.Ptr { + case reflect.Pointer: + if data == "" && defVal.Kind() == reflect.Pointer { if target.CanSet() { target.Set(defVal) } @@ -412,6 +459,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue an default: return errors.InvalidType(p.Name, p.parameter.In, tpe, data) } + return nil } @@ -419,20 +467,30 @@ func (p *untypedParamBinder) tryUnmarshaler(target reflect.Value, defaultValue a if !target.CanSet() { return false, nil } + // When a type implements encoding.TextUnmarshaler we'll use that instead of reflecting some more - if reflect.PointerTo(target.Type()).Implements(textUnmarshalType) { - if defaultValue != nil && len(data) == 0 { - target.Set(reflect.ValueOf(defaultValue)) - return true, nil - } - value := reflect.New(target.Type()) - if err := value.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(data)); err != nil { - return true, err - } - target.Set(reflect.Indirect(value)) + ttyp := target.Type() + if !reflect.PointerTo(ttyp).Implements(textUnmarshalType) { + return false, nil + } + + if defaultValue != nil && len(data) == 0 { + target.Set(reflect.ValueOf(defaultValue)) return true, nil } - return false, nil + + value := reflect.New(ttyp) + if !value.CanInterface() { + return false, nil + } + + if err := value.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(data)); err != nil { //nolint:forcetypeassert // this is guaranteed by the reflect check above + return true, err + } + + target.Set(reflect.Indirect(value)) + + return true, nil } func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target reflect.Value) ([]string, bool, error) { diff --git a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go b/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go deleted file mode 100644 index 1574defb41a..00000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "bytes" - "fmt" - "html/template" - "net/http" - "path" -) - -// RapiDocOpts configures the [RapiDoc] middlewares. -type RapiDocOpts struct { - // BasePath for the UI, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string - - // RapiDocURL points to the js asset that generates the rapidoc site. - // - // Defaults to https://unpkg.com/rapidoc/dist/rapidoc-min.js - RapiDocURL string -} - -func (r *RapiDocOpts) EnsureDefaults() { - common := toCommonUIOptions(r) - common.EnsureDefaults() - fromCommonToAnyOptions(common, r) - - // rapidoc-specifics - if r.RapiDocURL == "" { - r.RapiDocURL = rapidocLatest - } - if r.Template == "" { - r.Template = rapidocTemplate - } -} - -// RapiDoc creates a [middleware] to serve a documentation site for a swagger spec. -// -// This allows for altering the spec before starting the [http] listener. -func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler { - opts.EnsureDefaults() - - pth := path.Join(opts.BasePath, opts.Path) - tmpl := template.Must(template.New("rapidoc").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - rapidocLatest = "https://unpkg.com/rapidoc/dist/rapidoc-min.js" - rapidocTemplate = ` - - - {{ .Title }} - - - - - - - -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/redoc.go b/vendor/github.com/go-openapi/runtime/middleware/redoc.go deleted file mode 100644 index 1007409a30b..00000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/redoc.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "bytes" - "fmt" - "html/template" - "net/http" - "path" -) - -// RedocOpts configures the [Redoc] middlewares. -type RedocOpts struct { - // BasePath for the UI, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string - - // RedocURL points to the js that generates the redoc site. - // - // Defaults to: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js - RedocURL string -} - -// EnsureDefaults in case some options are missing. -func (r *RedocOpts) EnsureDefaults() { - common := toCommonUIOptions(r) - common.EnsureDefaults() - fromCommonToAnyOptions(common, r) - - // redoc-specifics - if r.RedocURL == "" { - r.RedocURL = redocLatest - } - if r.Template == "" { - r.Template = redocTemplate - } -} - -// Redoc creates a [middleware] to serve a documentation site for a swagger spec. -// -// This allows for altering the spec before starting the [http] listener. -func Redoc(opts RedocOpts, next http.Handler) http.Handler { - opts.EnsureDefaults() - - pth := path.Join(opts.BasePath, opts.Path) - tmpl := template.Must(template.New("redoc").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - redocLatest = "https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js" - redocTemplate = ` - - - {{ .Title }} - - - - - - - - - - - - - -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/request.go b/vendor/github.com/go-openapi/runtime/middleware/request.go index ad781663b8b..2b8aab08d22 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/request.go +++ b/vendor/github.com/go-openapi/runtime/middleware/request.go @@ -40,8 +40,25 @@ func NewUntypedRequestBinder(parameters map[string]spec.Parameter, spec *spec.Sw // Bind perform the databinding and validation. func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, data any) error { + err := o.bind(request, routeParams, consumer, data) + if err == nil { + return nil // avoids returning a nil-interface + } + + return err +} + +// SetLogger allows for injecting a logger to catch debug entries. +// +// The logger is enabled in DEBUG mode only. +func (o *UntypedRequestBinder) SetLogger(lg logger.Logger) { + o.debugLogf = debugLogfFunc(lg) +} + +func (o *UntypedRequestBinder) bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, data any) *errors.CompositeError { val := reflect.Indirect(reflect.ValueOf(data)) isMap := val.Kind() == reflect.Map + var result []error o.debugLogf("binding %d parameters for %s %s", len(o.Parameters), request.Method, request.URL.EscapedPath()) for fieldName, param := range o.Parameters { @@ -56,7 +73,7 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara if isMap { tpe := binder.Type() if tpe == nil { - if param.Schema.Type.Contains(typeArray) { + if param.Schema != nil && param.Schema.Type.Contains(typeArray) { tpe = reflect.TypeFor[[]any]() } else { tpe = reflect.TypeFor[map[string]any]() @@ -94,13 +111,6 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara return nil } -// SetLogger allows for injecting a logger to catch debug entries. -// -// The logger is enabled in DEBUG mode only. -func (o *UntypedRequestBinder) SetLogger(lg logger.Logger) { - o.debugLogf = debugLogfFunc(lg) -} - func (o *UntypedRequestBinder) setDebugLogf(fn func(string, ...any)) { o.debugLogf = fn } diff --git a/vendor/github.com/go-openapi/runtime/middleware/router.go b/vendor/github.com/go-openapi/runtime/middleware/router.go index e828653be7a..939cf7337ab 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/router.go +++ b/vendor/github.com/go-openapi/runtime/middleware/router.go @@ -21,6 +21,7 @@ import ( "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag/stringutils" + "github.com/go-openapi/swag/typeutils" ) // RouteParam is a object to capture route params in a framework agnostic way. @@ -292,7 +293,7 @@ func (ras RouteAuthenticators) Authenticate(req *http.Request, route *MatchedRou continue } applies, usr, err := ra.Authenticate(req, route) - if !applies || err != nil || usr == nil { + if !applies || err != nil || typeutils.IsZero(usr) { if err != nil { lastError = err } @@ -348,49 +349,62 @@ func (m *MatchedRoute) NeedsAuth() bool { func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) { mth := strings.ToUpper(method) d.debugLogf("looking up route for %s %s", method, path) - if Debug { - if len(d.routers) == 0 { + if len(d.routers) == 0 { + if Debug { d.debugLogf("there are no known routers") } + panic("internal error: no router is configured") + } + + if Debug { for meth := range d.routers { d.debugLogf("got a router for %s", meth) } } - if router, ok := d.routers[mth]; ok { - if m, rp, ok := router.Lookup(fpath.Clean(path)); ok && m != nil { - if entry, ok := m.(*routeEntry); ok { - d.debugLogf("found a route for %s %s with %d parameters", method, path, len(entry.Parameters)) - var params RouteParams - for _, p := range rp { - v, err := url.PathUnescape(p.Value) - if err != nil { - d.debugLogf("failed to escape %q: %v", p.Value, err) - v = p.Value - } - // a workaround to handle fragment/composing parameters until they are supported in denco router - // check if this parameter is a fragment within a path segment - const enclosureSize = 2 - if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + enclosureSize; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' { - // extract fragment parameters - ep := strings.Split(entry.PathPattern[xpos:], "/")[0] - pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil) - for i, pname := range pnames { - params = append(params, RouteParam{Name: pname, Value: pvalues[i]}) - } - } else { - // use the parameter directly - params = append(params, RouteParam{Name: p.Name, Value: v}) - } - } - return &MatchedRoute{routeEntry: *entry, Params: params}, true + + router, ok := d.routers[mth] + if !ok { + d.debugLogf("couldn't find a route by method for %s %s", method, path) + return nil, false + } + + m, rp, ok := router.Lookup(fpath.Clean(escapeLiteralColons(path))) + if !ok || m == nil { + d.debugLogf("couldn't find a route by path for %s %s", method, path) + return nil, false + } + + entry, ok := m.(*routeEntry) + if !ok { + return nil, false + } + + d.debugLogf("found a route for %s %s with %d parameters", method, path, len(entry.Parameters)) + var params RouteParams + for _, p := range rp { + v, err := url.PathUnescape(p.Value) + if err != nil { + d.debugLogf("failed to escape %q: %v", p.Value, err) + v = p.Value + } + + // a workaround to handle fragment/composing parameters until they are supported in denco router + // check if this parameter is a fragment within a path segment + const enclosureSize = 2 + if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + enclosureSize; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' { + // extract fragment parameters + ep := strings.Split(entry.PathPattern[xpos:], "/")[0] + pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil) + for i, pname := range pnames { + params = append(params, RouteParam{Name: pname, Value: pvalues[i]}) } } else { - d.debugLogf("couldn't find a route by path for %s %s", method, path) + // use the parameter directly + params = append(params, RouteParam{Name: p.Name, Value: v}) } - } else { - d.debugLogf("couldn't find a route by method for %s %s", method, path) } - return nil, false + + return &MatchedRoute{routeEntry: *entry, Params: params}, true } func (d *defaultRouter) OtherMethods(method, path string) []string { @@ -398,7 +412,7 @@ func (d *defaultRouter) OtherMethods(method, path string) []string { var methods []string for k, v := range d.routers { if k != mn { - if _, _, ok := v.Lookup(fpath.Clean(path)); ok { + if _, _, ok := v.Lookup(fpath.Clean(escapeLiteralColons(path))); ok { methods = append(methods, k) continue } @@ -414,28 +428,39 @@ func (d *defaultRouter) SetLogger(lg logger.Logger) { // convert swagger parameters per path segment into a denco parameter as multiple parameters per segment are not supported in denco. var pathConverter = regexp.MustCompile(`{(.+?)}([^/]*)`) +// escapeLiteralColons replaces literal ':' characters with their URL-encoded +// equivalent "%3A". This prevents the denco router from misinterpreting ':' +// in URL path segments as parameter delimiters. The ':' character is valid in +// URL paths per RFC 3986 section 3.3. +func escapeLiteralColons(path string) string { + return strings.ReplaceAll(path, ":", "%3A") +} + func decodeCompositParams(name string, value string, pattern string, names []string, values []string) ([]string, []string) { pleft := strings.Index(pattern, "{") names = append(names, name) + if pleft < 0 { if strings.HasSuffix(value, pattern) { values = append(values, value[:len(value)-len(pattern)]) } else { values = append(values, "") } + + return names, values + } + + toskip := pattern[:pleft] + pright := strings.Index(pattern, "}") + vright := strings.Index(value, toskip) + if vright >= 0 { + values = append(values, value[:vright]) } else { - toskip := pattern[:pleft] - pright := strings.Index(pattern, "}") - vright := strings.Index(value, toskip) - if vright >= 0 { - values = append(values, value[:vright]) - } else { - values = append(values, "") - value = "" - } - return decodeCompositParams(pattern[pleft+1:pright], value[vright+len(toskip):], pattern[pright+1:], names, values) + values = append(values, "") + value = "" } - return names, values + + return decodeCompositParams(pattern[pleft+1:pright], value[vright+len(toskip):], pattern[pright+1:], names, values) } func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Operation) { @@ -463,7 +488,7 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper requestBinder := NewUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()) requestBinder.setDebugLogf(d.debugLogf) - record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{ + record := denco.NewRecord(pathConverter.ReplaceAllString(escapeLiteralColons(path), ":$1"), &routeEntry{ BasePath: bp, PathPattern: path, Operation: operation, diff --git a/vendor/github.com/go-openapi/runtime/middleware/seam.go b/vendor/github.com/go-openapi/runtime/middleware/seam.go new file mode 100644 index 00000000000..b234395f19c --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/middleware/seam.go @@ -0,0 +1,482 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package middleware + +import ( + "net/http" + "path" + "strings" + + "github.com/go-openapi/runtime/server-middleware/docui" + "github.com/go-openapi/runtime/server-middleware/negotiate" +) + +/////////////////////////////////////////////////////////: +// Seam to the negotiate options introduced in v0.29.5 +/////////////////////////////////////////////////////////: + +// NegotiateOption configures [NegotiateContentType] behaviour. +// +// Deprecated: moved to the [negotiate] package. Use [negotiate.Option] instead. +type NegotiateOption = negotiate.Option + +// NegotiateContentType returns the best offered content type for the +// request's Accept header. +// +// Deprecated: moved to the [negotiate] package. Use [negotiate.ContentType] instead. +func NegotiateContentType(r *http.Request, offers []string, defaultOffer string, opts ...NegotiateOption) string { + return negotiate.ContentType(r, offers, defaultOffer, opts...) +} + +// NegotiateContentEncoding returns the best offered content encoding for +// the request's Accept-Encoding header. +// +// Deprecated: moved to the [negotiate] package. Use [negotiate.ContentEncoding] instead. +func NegotiateContentEncoding(r *http.Request, offers []string) string { + return negotiate.ContentEncoding(r, offers) +} + +// WithIgnoreParameters returns a [NegotiateOption] that strips MIME-type +// parameters from both Accept entries and offers before matching, +// restoring the pre-v0.30 behaviour. +// +// Deprecated: moved to the [negotiate] package. Use [negotiate.WithIgnoreParameters] instead. +func WithIgnoreParameters(ignore bool) NegotiateOption { + return negotiate.WithIgnoreParameters(ignore) +} + +/////////////////////////////////////////////////////////: +// Seam to the UI options +/////////////////////////////////////////////////////////: + +// RapiDoc creates a [http.Handler] to serve a documentation site for a swagger spec. +// +// This allows for altering the spec before starting the [http] listener. +// +// Deprecated: moved to the [docui] package. Use [docui.RapiDoc] instead. +func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler { + return docui.RapiDoc(next, opts.toFuncOptions()...) +} + +// Redoc creates a [http.Handler] to serve a documentation site for a swagger spec. +// +// This allows for altering the spec before starting the [http] listener. +// +// Deprecated: moved to the [docui] package. Use [docui.Redoc] instead. +func Redoc(opts RedocOpts, next http.Handler) http.Handler { + return docui.Redoc(next, opts.toFuncOptions()...) +} + +// SwaggerUI creates a [http.Handler] to serve a documentation site for a swagger spec. +// +// This allows for altering the spec before starting the [http] listener. +// +// Deprecated: moved to the [docui] package. Use [docui.SwaggerUI] instead. +func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler { + return docui.SwaggerUI(next, opts.toFuncOptions()...) +} + +// SwaggerUIOAuth2Callback creates a middleware that serves the OAuth2 callback page used by Swagger UI. +// +// Deprecated: moved to the [docui] package. Use [docui.SwaggerUIOAuth2Callback] instead. +func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler { + return docui.SwaggerUIOAuth2Callback(next, opts.toFuncOptions()...) +} + +/////////////////////////////////////////////////////////: +// Seam to the spec middleware options +/////////////////////////////////////////////////////////: + +// SpecOption can be applied to the [Spec] serving [middleware]. +// +// Deprecated: moved to the [docui] package. Use [docui.SpecOption] instead. +type SpecOption func(*specOptions) + +type specOptions struct { + BasePath string + Path string + Document string +} + +func (o specOptions) fullPath() string { + return path.Join(o.BasePath, o.Path, o.Document) +} + +func specOptionsWithDefaults(basePath string, opts []SpecOption) specOptions { + o := specOptions{ + BasePath: "/", + Path: "", + Document: "swagger.json", + } + + for _, apply := range opts { + apply(&o) + } + if basePath != "" { + o.BasePath = basePath + } + + return o +} + +// Spec creates a [middleware] to serve a swagger spec as a JSON document. +// +// This allows for altering the spec before starting the [http] listener. +// +// The basePath argument indicates the path of the spec document (defaults to "/"). +// Additional [SpecOption] can be used to change the name of the document (defaults to "swagger.json"). +// +// Deprecated: moved to the [docui] package as [docui.ServeSpec]. +func Spec(basePath string, spec []byte, next http.Handler, opts ...SpecOption) http.Handler { + o := specOptionsWithDefaults(basePath, opts) + + return docui.ServeSpec(spec, next, docui.WithSpecPath(o.fullPath())) + +} + +// WithSpecPath sets the path to be joined to the base path of the +// spec-serving middleware (see [docui.ServeSpec]). +// +// This is empty by default. +func WithSpecPath(pth string) SpecOption { + return func(o *specOptions) { + o.Path = pth + } +} + +// WithSpecDocument sets the name of the JSON document served as a spec. +// +// By default, this is "swagger.json". +func WithSpecDocument(doc string) SpecOption { + return func(o *specOptions) { + if doc == "" { + return + } + + o.Document = doc + } +} + +// UIOptions defines common options for UI serving middlewares. +// +// Deprecated: use instead the function options provided by [docui]. +type UIOptions struct { + // BasePath for the UI, defaults to: / + BasePath string + + // Path combines with BasePath to construct the path to the UI, defaults to: "docs". + Path string + + // SpecURL is the URL of the spec document. + // + // Defaults to: /swagger.json + SpecURL string + + // Title for the documentation site, default to: API documentation + Title string + + // Template specifies a custom template to serve the UI + Template string +} + +// toFuncOptions bridges the deprecated options struct with the newer function options in [docui]. +func (o UIOptions) toFuncOptions() []docui.Option { + const structMembers = 5 + opts := make([]docui.Option, 0, structMembers) + + if o.BasePath != "" { + opts = append(opts, docui.WithUIBasePath(o.BasePath)) + } + + if o.Path != "" { + opts = append(opts, docui.WithUIPath(o.Path)) + } + + if o.SpecURL != "" { + opts = append(opts, docui.WithSpecURL(o.SpecURL)) + } + + if o.Title != "" { + opts = append(opts, docui.WithUITitle(o.Title)) + } + + if o.Template != "" { + opts = append(opts, docui.WithUITemplate(o.Template)) + } + + return opts +} + +// RapiDocOpts configures the [RapiDoc] middlewares. +// +// Deprecated: use instead the function options provided by [docui]. +type RapiDocOpts struct { + // BasePath for the UI, defaults to: / + BasePath string + + // Path combines with BasePath to construct the path to the UI, defaults to: "docs". + Path string + + // SpecURL is the URL of the spec document. + // + // Defaults to: /swagger.json + SpecURL string + + // Title for the documentation site, default to: API documentation + Title string + + // Template specifies a custom template to serve the UI + Template string + + // RapiDocURL points to the js asset that generates the rapidoc site. + // + // Defaults to https://unpkg.com/rapidoc/dist/rapidoc-min.js + RapiDocURL string +} + +func (o RapiDocOpts) toFuncOptions() []docui.Option { + const structMembers = 6 + opts := make([]docui.Option, 0, structMembers) + + if o.BasePath != "" { + opts = append(opts, docui.WithUIBasePath(o.BasePath)) + } + + if o.Path != "" { + opts = append(opts, docui.WithUIPath(o.Path)) + } + + if o.SpecURL != "" { + opts = append(opts, docui.WithSpecURL(o.SpecURL)) + } + + if o.Title != "" { + opts = append(opts, docui.WithUITitle(o.Title)) + } + + if o.Template != "" { + opts = append(opts, docui.WithUITemplate(o.Template)) + } + + if o.RapiDocURL != "" { + opts = append(opts, docui.WithUIAssetsURL(o.RapiDocURL)) + } + + return opts +} + +// RedocOpts configures the [Redoc] middlewares. +// +// Deprecated: use instead the function options provided by [docui]. +type RedocOpts struct { + // BasePath for the UI, defaults to: / + BasePath string + + // Path combines with BasePath to construct the path to the UI, defaults to: "docs". + Path string + + // SpecURL is the URL of the spec document. + // + // Defaults to: /swagger.json + SpecURL string + + // Title for the documentation site, default to: API documentation + Title string + + // Template specifies a custom template to serve the UI + Template string + + // RedocURL points to the js that generates the redoc site. + // + // Defaults to: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js + RedocURL string +} + +func (o RedocOpts) toFuncOptions() []docui.Option { + const structMembers = 6 + opts := make([]docui.Option, 0, structMembers) + + if o.BasePath != "" { + opts = append(opts, docui.WithUIBasePath(o.BasePath)) + } + + if o.Path != "" { + opts = append(opts, docui.WithUIPath(o.Path)) + } + + if o.SpecURL != "" { + opts = append(opts, docui.WithSpecURL(o.SpecURL)) + } + + if o.Title != "" { + opts = append(opts, docui.WithUITitle(o.Title)) + } + + if o.Template != "" { + opts = append(opts, docui.WithUITemplate(o.Template)) + } + + if o.RedocURL != "" { + opts = append(opts, docui.WithUIAssetsURL(o.RedocURL)) + } + + return opts +} + +// SwaggerUIOpts configures the [SwaggerUI] [middleware]. +// +// Deprecated: use instead the function options provided by [docui]. +type SwaggerUIOpts struct { + // BasePath for the API, defaults to: / + BasePath string + + // Path combines with BasePath to construct the path to the UI, defaults to: "docs". + Path string + + // SpecURL is the URL of the spec document. + // + // Defaults to: /swagger.json + SpecURL string + + // Title for the documentation site, default to: API documentation + Title string + + // Template specifies a custom template to serve the UI + Template string + + // OAuthCallbackURL the url called after OAuth2 login + // + // NOTE: in the new [docui.SwaggerUIOptions] type, this field is named `OAuth2CallbackURL`, + // which is more appropriate. + OAuthCallbackURL string + + // The three components needed to embed swagger-ui + + // SwaggerURL points to the js that generates the SwaggerUI site. + // + // Defaults to: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js + SwaggerURL string + + SwaggerPresetURL string + SwaggerStylesURL string + + Favicon32 string + Favicon16 string +} + +func (o SwaggerUIOpts) toFuncOptions() []docui.Option { + const structMembers = 6 + opts := make([]docui.Option, 0, structMembers) + + if o.BasePath != "" { + opts = append(opts, docui.WithUIBasePath(o.BasePath)) + } + + if o.Path != "" { + opts = append(opts, docui.WithUIPath(o.Path)) + } + + if o.SpecURL != "" { + opts = append(opts, docui.WithSpecURL(o.SpecURL)) + } + + if o.Title != "" { + opts = append(opts, docui.WithUITitle(o.Title)) + } + + if o.Template != "" { + opts = append(opts, docui.WithUITemplate(o.Template)) + } + + if o.SwaggerURL != "" { + opts = append(opts, docui.WithUIAssetsURL(o.SwaggerURL)) + } + + var empty SwaggerUIOpts + if o != empty { + swaggeruiOpts := docui.SwaggerUIOptions{ + OAuth2CallbackURL: o.OAuthCallbackURL, + SwaggerPresetURL: o.SwaggerPresetURL, + SwaggerStylesURL: o.SwaggerStylesURL, + Favicon32: o.Favicon32, + Favicon16: o.Favicon16, + } + opts = append(opts, docui.WithSwaggerUIOptions(swaggeruiOpts)) + } + + return opts +} + +// UIOption can be applied to UI serving [middleware] to alter the default +// behavior. +// +// Deprecated: use instead the function options provided by [docui]. +type UIOption func(*UIOptions) + +// uiOptionsWithDefaults applies the given options on top of an empty +// [UIOptions]. Per-flavor handlers ([SwaggerUI], [Redoc], [RapiDoc]) +// fill in the remaining defaults via [UIOptions.EnsureDefaults] when +// the option struct is used. +func uiOptionsWithDefaults(opts []UIOption) UIOptions { + var o UIOptions + for _, apply := range opts { + apply(&o) + } + + return o +} + +// WithUIBasePath sets the base path from where to serve the UI assets. +// +// Deprecated: use instead the function options provided by [docui]. +func WithUIBasePath(base string) UIOption { + return func(o *UIOptions) { + if !strings.HasPrefix(base, "/") { + base = "/" + base + } + o.BasePath = base + } +} + +// WithUIPath sets the path from where to serve the UI assets (i.e. /{basepath}/{path}. +// +// Deprecated: use instead the function options provided by [docui]. +func WithUIPath(pth string) UIOption { + return func(o *UIOptions) { + o.Path = pth + } +} + +// WithUISpecURL sets the path from where to serve swagger spec document. +// +// This may be specified as a full URL or a path. +// +// By default, this is "/swagger.json". +// +// Deprecated: use instead the function options provided by [docui]. +func WithUISpecURL(specURL string) UIOption { + return func(o *UIOptions) { + o.SpecURL = specURL + } +} + +// WithUITitle sets the title of the UI. +// +// Deprecated: use instead the function options provided by [docui]. +func WithUITitle(title string) UIOption { + return func(o *UIOptions) { + o.Title = title + } +} + +// WithTemplate allows to set a custom template for the UI. +// +// UI [middleware] will panic if the template does not parse or execute properly. +// +// Deprecated: use instead the function options provided by [docui]. +func WithTemplate(tpl string) UIOption { + return func(o *UIOptions) { + o.Template = tpl + } +} diff --git a/vendor/github.com/go-openapi/runtime/middleware/spec.go b/vendor/github.com/go-openapi/runtime/middleware/spec.go deleted file mode 100644 index 0a64a9572b5..00000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/spec.go +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "net/http" - "path" -) - -const ( - contentTypeHeader = "Content-Type" - applicationJSON = "application/json" -) - -// SpecOption can be applied to the Spec serving [middleware]. -type SpecOption func(*specOptions) - -var defaultSpecOptions = specOptions{ - Path: "", - Document: "swagger.json", -} - -type specOptions struct { - Path string - Document string -} - -func specOptionsWithDefaults(opts []SpecOption) specOptions { - o := defaultSpecOptions - for _, apply := range opts { - apply(&o) - } - - return o -} - -// Spec creates a [middleware] to serve a swagger spec as a JSON document. -// -// This allows for altering the spec before starting the [http] listener. -// -// The basePath argument indicates the path of the spec document (defaults to "/"). -// Additional [SpecOption] can be used to change the name of the document (defaults to "swagger.json"). -func Spec(basePath string, b []byte, next http.Handler, opts ...SpecOption) http.Handler { - if basePath == "" { - basePath = "/" - } - o := specOptionsWithDefaults(opts) - pth := path.Join(basePath, o.Path, o.Document) - - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - if path.Clean(r.URL.Path) == pth { - rw.Header().Set(contentTypeHeader, applicationJSON) - rw.WriteHeader(http.StatusOK) - _, _ = rw.Write(b) - - return - } - - if next != nil { - next.ServeHTTP(rw, r) - - return - } - - rw.Header().Set(contentTypeHeader, applicationJSON) - rw.WriteHeader(http.StatusNotFound) - }) -} - -// WithSpecPath sets the path to be joined to the base path of the Spec [middleware]. -// -// This is empty by default. -func WithSpecPath(pth string) SpecOption { - return func(o *specOptions) { - o.Path = pth - } -} - -// WithSpecDocument sets the name of the JSON document served as a spec. -// -// By default, this is "swagger.json". -func WithSpecDocument(doc string) SpecOption { - return func(o *specOptions) { - if doc == "" { - return - } - - o.Document = doc - } -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go b/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go deleted file mode 100644 index 14ed37ced69..00000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "bytes" - "fmt" - "html/template" - "net/http" - "path" -) - -// SwaggerUIOpts configures the [SwaggerUI] [middleware]. -type SwaggerUIOpts struct { - // BasePath for the API, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string - - // OAuthCallbackURL the url called after OAuth2 login - OAuthCallbackURL string - - // The three components needed to embed swagger-ui - - // SwaggerURL points to the js that generates the SwaggerUI site. - // - // Defaults to: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js - SwaggerURL string - - SwaggerPresetURL string - SwaggerStylesURL string - - Favicon32 string - Favicon16 string -} - -// EnsureDefaults in case some options are missing. -func (r *SwaggerUIOpts) EnsureDefaults() { - r.ensureDefaults() - - if r.Template == "" { - r.Template = swaggeruiTemplate - } -} - -func (r *SwaggerUIOpts) EnsureDefaultsOauth2() { - r.ensureDefaults() - - if r.Template == "" { - r.Template = swaggerOAuthTemplate - } -} - -func (r *SwaggerUIOpts) ensureDefaults() { - common := toCommonUIOptions(r) - common.EnsureDefaults() - fromCommonToAnyOptions(common, r) - - // swaggerui-specifics - if r.OAuthCallbackURL == "" { - r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback") - } - if r.SwaggerURL == "" { - r.SwaggerURL = swaggerLatest - } - if r.SwaggerPresetURL == "" { - r.SwaggerPresetURL = swaggerPresetLatest - } - if r.SwaggerStylesURL == "" { - r.SwaggerStylesURL = swaggerStylesLatest - } - if r.Favicon16 == "" { - r.Favicon16 = swaggerFavicon16Latest - } - if r.Favicon32 == "" { - r.Favicon32 = swaggerFavicon32Latest - } -} - -// SwaggerUI creates a [middleware] to serve a documentation site for a swagger spec. -// -// This allows for altering the spec before starting the [http] listener. -func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler { - opts.EnsureDefaults() - - pth := path.Join(opts.BasePath, opts.Path) - tmpl := template.Must(template.New("swaggerui").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { - panic(fmt.Errorf("cannot execute template: %w", err)) - } - - return serveUI(pth, assets.Bytes(), next) -} - -const ( - swaggerLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" - swaggerPresetLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js" - swaggerStylesLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui.css" - swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png" - swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png" - swaggeruiTemplate = ` - - - - - {{ .Title }} - - - - - - - - -
- - - - - - -` -) diff --git a/vendor/github.com/go-openapi/runtime/middleware/typeutils.go b/vendor/github.com/go-openapi/runtime/middleware/typeutils.go new file mode 100644 index 00000000000..3f7d7976a1f --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/middleware/typeutils.go @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package middleware + +import "strings" + +// normalizeOffer strips the parameter section (";...") from a media-type +// string. +func normalizeOffer(orig string) string { + // NOTE(maintainers): Despite its name (kept for historical reasons), this helper is + // not about Accept negotiation — it is used to derive the bare type that + // keys the producer/consumer maps registered on a [RoutableAPI]. + // Those maps are looked up by the bare media type, so an entry registered as + // "application/json" satisfies a route that declares "application/json; + // charset=utf-8" and vice-versa. + const maxParts = 2 + + return strings.SplitN(orig, ";", maxParts)[0] +} + +// normalizeOffers is the slice form of [normalizeOffer]. +func normalizeOffers(orig []string) []string { + norm := make([]string, 0, len(orig)) + for _, o := range orig { + norm = append(norm, normalizeOffer(o)) + } + + return norm +} diff --git a/vendor/github.com/go-openapi/runtime/middleware/ui_options.go b/vendor/github.com/go-openapi/runtime/middleware/ui_options.go deleted file mode 100644 index ed255426ad8..00000000000 --- a/vendor/github.com/go-openapi/runtime/middleware/ui_options.go +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "bytes" - "encoding/gob" - "fmt" - "net/http" - "path" - "strings" -) - -const ( - // constants that are common to all UI-serving middlewares. - defaultDocsPath = "docs" - defaultDocsURL = "/swagger.json" - defaultDocsTitle = "API Documentation" -) - -// uiOptions defines common options for UI serving middlewares. -type uiOptions struct { - // BasePath for the UI, defaults to: / - BasePath string - - // Path combines with BasePath to construct the path to the UI, defaults to: "docs". - Path string - - // SpecURL is the URL of the spec document. - // - // Defaults to: /swagger.json - SpecURL string - - // Title for the documentation site, default to: API documentation - Title string - - // Template specifies a custom template to serve the UI - Template string -} - -// toCommonUIOptions converts any UI option type to retain the common options. -// -// This uses gob encoding/decoding to convert common fields from one struct to another. -func toCommonUIOptions(opts any) uiOptions { - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - dec := gob.NewDecoder(&buf) - var o uiOptions - err := enc.Encode(opts) - if err != nil { - panic(err) - } - - err = dec.Decode(&o) - if err != nil { - panic(err) - } - - return o -} - -func fromCommonToAnyOptions[T any](source uiOptions, target *T) { - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - dec := gob.NewDecoder(&buf) - err := enc.Encode(source) - if err != nil { - panic(err) - } - - err = dec.Decode(target) - if err != nil { - panic(err) - } -} - -// UIOption can be applied to UI serving [middleware], such as Context.[APIHandler] or -// Context.[APIHandlerSwaggerUI] to alter the default behavior. -type UIOption func(*uiOptions) - -func uiOptionsWithDefaults(opts []UIOption) uiOptions { - var o uiOptions - for _, apply := range opts { - apply(&o) - } - - return o -} - -// WithUIBasePath sets the base path from where to serve the UI assets. -// -// By default, Context [middleware] sets this value to the API base path. -func WithUIBasePath(base string) UIOption { - return func(o *uiOptions) { - if !strings.HasPrefix(base, "/") { - base = "/" + base - } - o.BasePath = base - } -} - -// WithUIPath sets the path from where to serve the UI assets (i.e. /{basepath}/{path}. -func WithUIPath(pth string) UIOption { - return func(o *uiOptions) { - o.Path = pth - } -} - -// WithUISpecURL sets the path from where to serve swagger spec document. -// -// This may be specified as a full URL or a path. -// -// By default, this is "/swagger.json". -func WithUISpecURL(specURL string) UIOption { - return func(o *uiOptions) { - o.SpecURL = specURL - } -} - -// WithUITitle sets the title of the UI. -// -// By default, Context [middleware] sets this value to the title found in the API spec. -func WithUITitle(title string) UIOption { - return func(o *uiOptions) { - o.Title = title - } -} - -// WithTemplate allows to set a custom template for the UI. -// -// UI [middleware] will panic if the template does not parse or execute properly. -func WithTemplate(tpl string) UIOption { - return func(o *uiOptions) { - o.Template = tpl - } -} - -// EnsureDefaults in case some options are missing. -func (r *uiOptions) EnsureDefaults() { - if r.BasePath == "" { - r.BasePath = "/" - } - if r.Path == "" { - r.Path = defaultDocsPath - } - if r.SpecURL == "" { - r.SpecURL = defaultDocsURL - } - if r.Title == "" { - r.Title = defaultDocsTitle - } -} - -// serveUI creates a middleware that serves a templated asset as text/html. -func serveUI(pth string, assets []byte, next http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - if path.Clean(r.URL.Path) == pth { - rw.Header().Set(contentTypeHeader, "text/html; charset=utf-8") - rw.WriteHeader(http.StatusOK) - _, _ = rw.Write(assets) - - return - } - - if next != nil { - next.ServeHTTP(rw, r) - - return - } - - rw.Header().Set(contentTypeHeader, "text/plain") - rw.WriteHeader(http.StatusNotFound) - _, _ = fmt.Fprintf(rw, "%q not found", pth) - }) -} diff --git a/vendor/github.com/go-openapi/runtime/middleware/validation.go b/vendor/github.com/go-openapi/runtime/middleware/validation.go index 8a56490639e..63a78d482a8 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/validation.go +++ b/vendor/github.com/go-openapi/runtime/middleware/validation.go @@ -4,13 +4,14 @@ package middleware import ( - "mime" + stderrors "errors" "net/http" "strings" "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" - "github.com/go-openapi/swag/stringutils" + "github.com/go-openapi/runtime/server-middleware/mediatype" ) type validation struct { @@ -21,24 +22,28 @@ type validation struct { bound map[string]any } -// ContentType validates the content type of a request. -func validateContentType(allowed []string, actual string) error { +// validateContentType maps [mediatype.MatchFirst] to the runtime's +// validation errors: +// +// - actual fails to parse → HTTP 400 ([errors.NewParseError]). +// - actual is well-formed but +// no allowed entry accepts it → HTTP 415 ([errors.InvalidContentType]). +// +// In the standard runtime flow, malformed Content-Type headers are +// already caught upstream by [runtime.ContentType] (which itself returns +// a 400 [errors.ParseError]). This function therefore only sees the +// malformed case when invoked directly by callers that have bypassed +// that step. +func validateContentType(allowed []string, actual string, opts ...mediatype.MatchOption) error { if len(allowed) == 0 { return nil } - mt, _, err := mime.ParseMediaType(actual) - if err != nil { - return errors.InvalidContentType(actual, allowed) - } - if stringutils.ContainsStringsCI(allowed, mt) { - return nil - } - if stringutils.ContainsStringsCI(allowed, "*/*") { + _, ok, err := mediatype.MatchFirst(allowed, actual, opts...) + if ok { return nil } - parts := strings.Split(actual, "/") - if len(parts) == 2 && stringutils.ContainsStringsCI(allowed, parts[0]+"/*") { - return nil + if err != nil { + return errors.NewParseError(runtime.HeaderContentType, "header", actual, err) } return errors.InvalidContentType(actual, allowed) } @@ -69,46 +74,53 @@ func (v *validation) debugLogf(format string, args ...any) { func (v *validation) parameters() { v.debugLogf("validating request parameters for %s %s", v.request.Method, v.request.URL.EscapedPath()) - if result := v.route.Binder.Bind(v.request, v.route.Params, v.route.Consumer, v.bound); result != nil { - if result.Error() == "validation failure list" { - for _, e := range result.(*errors.Validation).Value.([]any) { - v.result = append(v.result, e.(error)) - } - return + result := v.route.Binder.bind(v.request, v.route.Params, v.route.Consumer, v.bound) + if result == nil { + return + } + + for _, e := range result.Errors { + var validationErr *errors.Validation + if stderrors.As(e, &validationErr) { + v.result = append(v.result, validationErr) } - v.result = append(v.result, result) } } func (v *validation) contentType() { - if len(v.result) == 0 && runtime.HasBody(v.request) { - v.debugLogf("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath()) - ct, _, req, err := v.context.ContentType(v.request) - if err != nil { + if len(v.result) > 0 || !runtime.HasBody(v.request) { + return + } + + v.debugLogf("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath()) + ct, _, req, err := v.context.ContentType(v.request) + if err != nil { + v.result = append(v.result, err) + } else { + v.request = req + } + + if len(v.result) == 0 { + v.debugLogf("validating content type for %q against [%s]", ct, strings.Join(v.route.Consumes, ", ")) + if err := validateContentType(v.route.Consumes, ct, v.context.matchOpts()...); err != nil { v.result = append(v.result, err) - } else { - v.request = req } + } - if len(v.result) == 0 { - v.debugLogf("validating content type for %q against [%s]", ct, strings.Join(v.route.Consumes, ", ")) - if err := validateContentType(v.route.Consumes, ct); err != nil { - v.result = append(v.result, err) - } - } - if ct != "" && v.route.Consumer == nil { - cons, ok := v.route.Consumers[ct] - if !ok { - v.result = append(v.result, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct)) - } else { - v.route.Consumer = cons - } - } + if ct == "" || v.route.Consumer != nil { + return + } + + cons, ok := mediatype.Lookup(v.route.Consumers, ct, v.context.matchOpts()...) + if !ok { + v.result = append(v.result, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct)) + } else { + v.route.Consumer = cons } } func (v *validation) responseFormat() { - // if the route provides values for Produces and no format could be identify then return an error. + // if the route provides values for Produces and no format could be identified then return an error. // if the route does not specify values for Produces then treat request as valid since the API designer // choose not to specify the format for responses. if str, rCtx := v.context.ResponseFormat(v.request, v.route.Produces); str == "" && len(v.route.Produces) > 0 { diff --git a/vendor/github.com/go-openapi/runtime/multipart_stream.go b/vendor/github.com/go-openapi/runtime/multipart_stream.go new file mode 100644 index 00000000000..76e1bf4607a --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/multipart_stream.go @@ -0,0 +1,556 @@ +// SPDX-FileCopyrightText: Copyright 2015-2026 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package runtime + +import ( + "context" + stderrors "errors" + "fmt" + "io" + "mime" + "mime/multipart" + "net/http" + "net/textproto" + "net/url" + + "github.com/go-openapi/errors" +) + +// MultipartFormStreamOption configures [NewMultipartFormStream]. +type MultipartFormStreamOption func(*multipartFormStreamConfig) + +const defaultMultipartFormStreamMaxParts = 1000 + +type multipartFormStreamConfig struct { + multipartFormLimits + + maxParts int +} + +// MultipartFormStreamMaxBody caps the total number of request-body bytes read +// by a [MultipartFormStream]. +// +// A value of 0 applies [DefaultMaxUploadBodySize]. A negative value disables +// the cap when the caller has already limited the request body upstream. +func MultipartFormStreamMaxBody(n int64) MultipartFormStreamOption { + return func(c *multipartFormStreamConfig) { c.maxBody = n } +} + +// MultipartFormStreamMaxFiles rejects a multipart stream after more than n +// file parts have been encountered. A value of 0 means no file-count cap. +func MultipartFormStreamMaxFiles(n int) MultipartFormStreamOption { + return func(c *multipartFormStreamConfig) { c.maxFiles = n } +} + +// MultipartFormStreamMaxParts rejects a multipart stream after more than n +// total parts have been encountered. The default is 1000, matching +// [multipart.Reader.ReadForm]. A value of 0 disables the limit. +func MultipartFormStreamMaxParts(n int) MultipartFormStreamOption { + return func(c *multipartFormStreamConfig) { c.maxParts = n } +} + +// MultipartFormStreamMaxFilenameLen rejects file parts whose filename exceeds +// n bytes. A value of 0 disables the limit. When this option is not supplied, +// [DefaultMaxUploadFilenameLength] is used. +func MultipartFormStreamMaxFilenameLen(n int) MultipartFormStreamOption { + return func(c *multipartFormStreamConfig) { c.maxFilenameLen = n } +} + +// StreamedFile exposes a file part directly from the multipart request body. +// +// Reads block until bytes arrive from the client. StreamedFile is not seekable +// and is not safe for concurrent use. Its form name, filename and MIME headers +// are available before the payload is consumed. The underlying [multipart.Part] +// remains private so callers cannot bypass Close and its error-preserving drain +// semantics; Header exposes the part metadata without exposing that lifecycle. +// +// Closing a StreamedFile drains only the unread remainder of that file part. +// Close may therefore block while the client is still uploading the current +// part. The owning [MultipartFormStream] may then advance to the next part. +type StreamedFile struct { + FieldName string + Filename string + Header textproto.MIMEHeader + part *multipart.Part + closeErr error +} + +// MultipartFileInfo describes a file part discovered by [MultipartFormStream]. +// +// The payload reader is intentionally omitted. File parts remain sequential and +// are consumed through [MultipartFormStream.NextFile]. Header is a snapshot of +// the client-supplied MIME headers and must be treated as untrusted input. +type MultipartFileInfo struct { + FieldName string + Filename string + Header textproto.MIMEHeader +} + +// Read reads file payload bytes directly from the request body. +func (f *StreamedFile) Read(p []byte) (int, error) { + if f == nil || f.part == nil { + return 0, io.ErrClosedPipe + } + + return f.part.Read(p) +} + +// Close discards the unread remainder of this file part. +// +// Close does not close the underlying HTTP request body and does not consume +// subsequent multipart parts. After Close returns successfully, the parent +// MultipartFormStream may advance to the next part. +// +// Any error encountered while discarding the unread payload is returned. +func (f *StreamedFile) Close() error { + if f == nil { + return nil + } + if f.part == nil { + return f.closeErr + } + + part := f.part + f.part = nil + // multipart.Part.Close drains with io.Copy but intentionally discards the + // resulting error, so drain explicitly to preserve error propagation. + _, f.closeErr = io.Copy(io.Discard, part) + + return f.closeErr +} + +// MultipartFormStream reads multipart/form-data sequentially without parsing +// the complete request body before exposing file payloads. +// +// [MultipartFormStream.NextFile] consumes ordinary form fields until it reaches +// the next file part. Fields are appended to request.PostForm and request.Form +// as they are encountered. Consequently, fields after a file become visible +// only after the caller consumes or closes that file and advances the stream. +// +// A stream and its returned files are not safe for concurrent use. There is at +// most one active file part. Calling [MultipartFormStream.NextFile] closes and +// drains an unread active file before advancing, and may therefore block until +// the current part finishes arriving. No background goroutines are started. +// +// The caller owns the stream. Call [MultipartFormStream.Drain] to consume the +// remaining body, collect trailing fields and allow HTTP connection reuse when +// possible. Call [MultipartFormStream.Close] to stop multipart processing +// without explicitly draining the remaining parts. +// +// [MultipartFormStream.Fields] and [MultipartFormStream.Files] expose snapshots +// of the multipart fields and file metadata discovered so far. They never read +// ahead: fields or files after the active file become visible only after the +// stream advances. +type MultipartFormStream struct { + multipartFormStreamConfig + + request *http.Request + reader *multipart.Reader + current *StreamedFile + + fields url.Values + fileInfos []MultipartFileInfo + parts int + closed bool + done bool +} + +// NewMultipartFormStream creates a sequential multipart/form-data stream over +// r.Body. +// +// For POST, PUT and PATCH requests, the constructor accepts only +// multipart/form-data, validates that a non-empty boundary is present, but does +// not consume multipart parts. For other methods, it returns an empty stream +// whose NextFile method reports io.EOF without reading the request body. +// +// The constructor initializes request.Form and request.PostForm in the same way +// as [http.Request.ParseForm], then populates multipart values incrementally as +// [MultipartFormStream.NextFile] advances. +// +// For POST, PUT and PATCH requests, NewMultipartFormStream marks the request +// as handled by MultipartReader. Callers must not subsequently call +// [http.Request.ParseMultipartForm] or [BindForm] for the same request. +// +// File payloads are exposed directly from the request body and are not buffered +// in memory or temporary files. Ordinary form values are read into memory as +// they are encountered. Parts are processed in wire order. +// +// At most one StreamedFile may be active at a time. Calling +// [MultipartFormStream.NextFile] automatically closes and drains an unread +// current file before advancing. No background goroutines are started. +// +// MultipartFormStream is not safe for concurrent use. +// +// File names and MIME headers are supplied by the client and remain untrusted. +func NewMultipartFormStream(r *http.Request, opts ...MultipartFormStreamOption) (*MultipartFormStream, error) { + cfg := multipartFormStreamConfig{ + multipartFormLimits: multipartFormLimits{ + maxFilenameLen: DefaultMaxUploadFilenameLength, + }, + maxParts: defaultMultipartFormStreamMaxParts, + } + for _, opt := range opts { + opt(&cfg) + } + + if r == nil { + return nil, errors.NewParseError("body", "formData", "", stderrors.New("nil request")) + } + + if !supportsMultipartFormStream(r.Method) { + if err := r.ParseForm(); err != nil { + return nil, errors.NewParseError("body", "formData", "", err) + } + + return &MultipartFormStream{ + request: r, + multipartFormStreamConfig: cfg, + fields: make(url.Values), + done: true, + }, nil + } + + if r.Body == nil { + return nil, errors.NewParseError("body", "formData", "", stderrors.New("nil request body")) + } + + contentType := r.Header.Get(HeaderContentType) + mediaType, params, err := mime.ParseMediaType(contentType) + if err != nil { + return nil, errors.NewParseError(HeaderContentType, "header", contentType, err) + } + if mediaType != MultipartFormMime { + return nil, errors.NewParseError(HeaderContentType, "header", mediaType, http.ErrNotMultipart) + } + if params["boundary"] == "" { + return nil, errors.NewParseError(HeaderContentType, "header", contentType, http.ErrMissingBoundary) + } + if err = r.ParseForm(); err != nil { + return nil, errors.NewParseError("body", "formData", "", err) + } + + body := r.Body + if cfg.maxBody >= 0 { + maxBody := cfg.maxBody + if maxBody == 0 { + maxBody = DefaultMaxUploadBodySize + } + body = http.MaxBytesReader(nil, body, maxBody) + } + body = &contextReadCloser{ctx: r.Context(), ReadCloser: body} + r.Body = body + + reader, err := r.MultipartReader() + if err != nil { + return nil, errors.NewParseError("body", "formData", "", err) + } + + return &MultipartFormStream{ + request: r, + reader: reader, + multipartFormStreamConfig: cfg, + fields: make(url.Values), + }, nil +} + +// Fields returns a snapshot of ordinary multipart form fields discovered so far. +// +// URL query values are not included. Repeated multipart fields preserve their +// encounter order. Fields after the active file are not visible until that file +// is consumed or closed and the stream advances. Mutating the returned values +// does not affect the stream or the request. +func (s *MultipartFormStream) Fields() url.Values { + if s == nil { + return nil + } + + return cloneMultipartValues(s.fields) +} + +// Files returns snapshots of file metadata discovered so far in wire order. +// +// The currently active file is included as soon as NextFile returns it. Payload +// readers are not retained in the index. Mutating the returned slice or MIME +// headers does not affect the stream. +func (s *MultipartFormStream) Files() []MultipartFileInfo { + if s == nil { + return nil + } + + files := make([]MultipartFileInfo, len(s.fileInfos)) + for i, file := range s.fileInfos { + files[i] = MultipartFileInfo{ + FieldName: file.FieldName, + Filename: file.Filename, + Header: cloneMultipartMIMEHeader(file.Header), + } + } + + return files +} + +// NextFile advances through the multipart body and returns the next file part. +// Ordinary form fields encountered before that file are added to request.Form +// and request.PostForm. +// +// If the previously returned file is still open, NextFile closes and drains it +// before advancing. This may block while the client is still uploading that +// part. Any drain error is returned and the stream is aborted. +// +// NextFile returns io.EOF when no file parts remain. At that point all trailing +// ordinary fields have been collected. +func (s *MultipartFormStream) NextFile() (*StreamedFile, error) { + if err := s.prepareNextFile(); err != nil { + return nil, err + } + + return s.readNextFile() +} + +// Drain consumes the rest of the multipart body. +// +// Unread file payloads are discarded. Non-file form fields encountered while +// draining are collected in the request form values. +// +// Drain closes the underlying request body after reaching EOF. Subsequent calls +// to NextFile return io.EOF. Drain returns any multipart parsing, payload drain +// or request-body close error. +func (s *MultipartFormStream) Drain() error { + if s == nil || s.closed { + return nil + } + + for { + file, err := s.NextFile() + if stderrors.Is(err, io.EOF) { + return s.Close() + } + if err != nil { + return stderrors.Join(err, s.Close()) + } + if err = file.Close(); err != nil { + return stderrors.Join(err, s.Close()) + } + } +} + +// Close stops multipart processing and closes the underlying HTTP request body +// without explicitly draining the remaining multipart parts. +// +// The concrete request body may perform its own work during Close. In +// particular, a net/http server request body may discard a limited amount of +// unread data to allow connection reuse, so Close is not guaranteed to return +// immediately. Call Drain when trailing form fields must be collected. +func (s *MultipartFormStream) Close() error { + if s == nil || s.closed { + return nil + } + + s.closed = true + if s.current != nil { + s.current.part = nil + s.current = nil + } + + if s.request == nil || s.request.Body == nil { + return nil + } + + return s.request.Body.Close() +} + +func supportsMultipartFormStream(method string) bool { + switch method { + case http.MethodPost, http.MethodPut, http.MethodPatch: + return true + default: + return false + } +} + +func (s *MultipartFormStream) abort(err error) error { + return stderrors.Join(err, s.Close()) +} + +func (s *MultipartFormStream) closeCurrent() error { + if s.current == nil { + return nil + } + + err := s.current.Close() + s.current = nil + + return err +} + +func (s *MultipartFormStream) bindValue(part *multipart.Part, name string) error { + value, err := io.ReadAll(part) + if err != nil { + return err + } + + s.fields.Add(name, string(value)) + s.request.PostForm.Add(name, string(value)) + // Match net/http.ParseMultipartForm: query values already present in Form + // keep precedence over multipart body values, which are appended. + s.request.Form.Add(name, string(value)) + + return nil +} + +func discardPart(part *multipart.Part) error { + _, err := io.Copy(io.Discard, part) + + return err +} + +func cloneMultipartValues(values url.Values) url.Values { + cloned := make(url.Values, len(values)) + for name, entries := range values { + cloned[name] = append([]string(nil), entries...) + } + + return cloned +} + +func cloneMultipartMIMEHeader(header textproto.MIMEHeader) textproto.MIMEHeader { + cloned := make(textproto.MIMEHeader, len(header)) + for name, entries := range header { + cloned[name] = append([]string(nil), entries...) + } + + return cloned +} + +type contextReadCloser struct { + io.ReadCloser + + ctx context.Context //nolint:containedctx // Read has no context parameter, so the wrapper must retain it +} + +func (r *contextReadCloser) Read(p []byte) (int, error) { + if err := r.ctx.Err(); err != nil { + return 0, err + } + + return r.ReadCloser.Read(p) +} + +func (s *MultipartFormStream) prepareNextFile() error { + if s == nil { + return io.ErrClosedPipe + } + if s.done { + return io.EOF + } + if s.closed { + return io.ErrClosedPipe + } + if err := s.closeCurrent(); err != nil { + return s.abort(err) + } + + return nil +} + +func (s *MultipartFormStream) readNextFile() (*StreamedFile, error) { + for { + part, err := s.reader.NextPart() + if err != nil { + return nil, s.handleNextPartError(err) + } + + s.parts++ + if s.maxParts > 0 && s.parts > s.maxParts { + err := errors.NewParseError( + "body", + "formData", + "", + fmt.Errorf( + "multipart form contains %d parts, exceeds limit %d", + s.parts, + s.maxParts, + ), + ) + + return nil, s.abort(err) + } + + fieldName := part.FormName() + if fieldName == "" { + if err := discardPart(part); err != nil { + return nil, s.abort(err) + } + + continue + } + + filename := part.FileName() + if filename == "" { + if err := s.bindValue(part, fieldName); err != nil { + return nil, s.abort(err) + } + + continue + } + + return s.openFile(part, fieldName, filename) + } +} + +func (s *MultipartFormStream) handleNextPartError(err error) error { + if stderrors.Is(err, io.EOF) { + s.done = true + + return io.EOF + } + + return s.abort(err) +} + +func (s *MultipartFormStream) openFile( + part *multipart.Part, + fieldName string, + filename string, +) (*StreamedFile, error) { + fileCount := len(s.fileInfos) + 1 + if s.maxFiles > 0 && fileCount > s.maxFiles { + err := errors.NewParseError( + "body", + "formData", + "", + fmt.Errorf( + "multipart form contains %d file parts, exceeds limit %d", + fileCount, + s.maxFiles, + ), + ) + + return nil, s.abort(err) + } + + if err := ValidateFilenameLength( + fieldName, + "formData", + filename, + s.maxFilenameLen, + ); err != nil { + return nil, s.abort(err) + } + + file := &StreamedFile{ + FieldName: fieldName, + Filename: filename, + Header: part.Header, + part: part, + } + s.fileInfos = append(s.fileInfos, MultipartFileInfo{ + FieldName: fieldName, + Filename: filename, + Header: cloneMultipartMIMEHeader(part.Header), + }) + s.current = file + + return file, nil +} diff --git a/vendor/github.com/go-openapi/runtime/security/authenticator.go b/vendor/github.com/go-openapi/runtime/security/authenticator.go index 4c091018265..e521d95ef16 100644 --- a/vendor/github.com/go-openapi/runtime/security/authenticator.go +++ b/vendor/github.com/go-openapi/runtime/security/authenticator.go @@ -19,8 +19,8 @@ const ( accessTokenParam = "access_token" ) -// HttpAuthenticator is a function that authenticates a HTTP request. -func HttpAuthenticator(handler func(*http.Request) (bool, any, error)) runtime.Authenticator { //nolint:revive +// HTTPAuthenticator is a function that authenticates a HTTP request. +func HTTPAuthenticator(handler func(*http.Request) (bool, any, error)) runtime.Authenticator { return runtime.AuthenticatorFunc(func(params any) (bool, any, error) { if request, ok := params.(*http.Request); ok { return handler(request) @@ -32,7 +32,14 @@ func HttpAuthenticator(handler func(*http.Request) (bool, any, error)) runtime.A }) } -// ScopedAuthenticator is a function that authenticates a HTTP request against a list of valid scopes. +// HttpAuthenticator aliases [HTTPAuthenticator] for backward-compatibility. +// +// Deprecated: use [HTTPAuthenticator] instead. +func HttpAuthenticator(handler func(*http.Request) (bool, any, error)) runtime.Authenticator { //nolint:revive + return HTTPAuthenticator(handler) +} + +// ScopedAuthenticator is a function that authenticates an [http.Request] against a list of valid scopes. func ScopedAuthenticator(handler func(*ScopedAuthRequest) (bool, any, error)) runtime.Authenticator { return runtime.AuthenticatorFunc(func(params any) (bool, any, error) { if request, ok := params.(*ScopedAuthRequest); ok { @@ -42,22 +49,42 @@ func ScopedAuthenticator(handler func(*ScopedAuthRequest) (bool, any, error)) ru }) } -// UserPassAuthentication authentication function. +// UserPassAuthentication validates a basic-auth credential. +// +// Implementations comparing the password (or any derived secret) against a +// known value MUST use [crypto/subtle.ConstantTimeCompare]: the runtime +// extracts the credential from the request and delegates the comparison +// here, and does not enforce a constant-time posture on the caller's behalf. type UserPassAuthentication func(string, string) (any, error) -// UserPassAuthenticationCtx authentication function with [context.Context]. +// UserPassAuthenticationCtx is the [context.Context]-aware variant of +// [UserPassAuthentication]. The same constant-time-comparison guidance +// applies. type UserPassAuthenticationCtx func(context.Context, string, string) (context.Context, any, error) -// TokenAuthentication authentication function. +// TokenAuthentication validates an API-key token. +// +// Implementations comparing the token against a known value MUST use +// [crypto/subtle.ConstantTimeCompare]; the runtime delegates the comparison +// here and does not enforce a constant-time posture on the caller's behalf. type TokenAuthentication func(string) (any, error) -// TokenAuthenticationCtx authentication function with [context.Context]. +// TokenAuthenticationCtx is the [context.Context]-aware variant of +// [TokenAuthentication]. The same constant-time-comparison guidance +// applies. type TokenAuthenticationCtx func(context.Context, string) (context.Context, any, error) -// ScopedTokenAuthentication authentication function. +// ScopedTokenAuthentication validates a bearer/OAuth2 token along with the +// scopes required for the operation. +// +// Implementations comparing the token against a known value MUST use +// [crypto/subtle.ConstantTimeCompare]; the runtime delegates the comparison +// here and does not enforce a constant-time posture on the caller's behalf. type ScopedTokenAuthentication func(string, []string) (any, error) -// ScopedTokenAuthenticationCtx authentication function with [context.Context]. +// ScopedTokenAuthenticationCtx is the [context.Context]-aware variant of +// [ScopedTokenAuthentication]. The same constant-time-comparison guidance +// applies. type ScopedTokenAuthenticationCtx func(context.Context, string, []string) (context.Context, any, error) var DefaultRealmName = "API" @@ -199,7 +226,7 @@ func APIKeyAuthCtx(name, in string, authenticate TokenAuthenticationCtx) runtime }) } -// ScopedAuthRequest contains both a [http] request and the required scopes for a particular operation. +// ScopedAuthRequest contains both the [http.Request] and the required scopes for a particular operation. type ScopedAuthRequest struct { Request *http.Request RequiredScopes []string diff --git a/vendor/github.com/go-openapi/swag/jsonname/LICENSE b/vendor/github.com/go-openapi/runtime/server-middleware/LICENSE similarity index 100% rename from vendor/github.com/go-openapi/swag/jsonname/LICENSE rename to vendor/github.com/go-openapi/runtime/server-middleware/LICENSE diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/doc.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/doc.go new file mode 100644 index 00000000000..809296d5c4f --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/doc.go @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package docui provides standalone HTTP middlewares that serve OpenAPI +// documentation UIs (Swagger UI, ReDoc, RapiDoc) and the spec document +// itself. +// +// The package is stdlib-only and has no transitive dependency on any +// OpenAPI spec, loading or validation library, so it may be imported by +// any net/http application that simply wants to mount a documentation +// site. +package docui diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/options.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/options.go new file mode 100644 index 00000000000..c9e45f77946 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/options.go @@ -0,0 +1,253 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package docui + +import ( + "net/http" + "net/url" + "strings" +) + +const ( + // constants that are common to all UI-serving middlewares. + defaultDocsPath = "docs" + defaultDocsURL = "/swagger.json" + defaultDocsTitle = "API Documentation" + + contentTypeHeader = "Content-Type" + applicationJSON = "application/json" +) + +// UIMiddleware is a function returning a http middleware which accepts UI [Option]. +type UIMiddleware func(...Option) func(http.Handler) http.Handler + +// Option to tune your swagger documentation UI middleware. +// +// Options may be combined to alter the route at which the UI asset is served, +// the URL of the spec document, the source URL of the UI asset and the title of the UI page. +// +// The embedded js scriptlet served may be modified using [WithUITemplate]. +type Option func(*options) + +// SpecOption can be applied to the [ServeSpec] middleware. +type SpecOption func(*specOptions) + +// SwaggerUIOptions define a group of extra options specific to the SwaggerUI component. +type SwaggerUIOptions struct { + // OAuth2CallbackURL sets the URL called after OAuth2 login + OAuth2CallbackURL string + + // Defines the URL of the swagger UI assets with presets. + // + // Default: https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js + SwaggerPresetURL string + + // Defines style sheet URL. + // + // Default: https://unpkg.com/swagger-ui-dist/swagger-ui.css + SwaggerStylesURL string + + // Define the favicons URLs. + // + // Defaults: + // + // - 16x16: https://unpkg.com/swagger-ui-dist/favicon-16x16.png + // - 32x32: https://unpkg.com/swagger-ui-dist/favicon-32x32.png + Favicon32 string + Favicon16 string +} + +func (o *SwaggerUIOptions) applySwaggerUIDefaults() { + if o.SwaggerPresetURL == "" { + o.SwaggerPresetURL = swaggerPresetLatest + } + if o.SwaggerStylesURL == "" { + o.SwaggerStylesURL = swaggerStylesLatest + } + if o.Favicon16 == "" || o.Favicon32 == "" { + o.Favicon16 = swaggerFavicon16Latest + o.Favicon32 = swaggerFavicon32Latest + } +} + +type ( + options struct { + SwaggerUIOptions + + // BasePath for the UI, defaults to: / + BasePath string + + // Path combines with BasePath to construct the path to the UI, defaults to: "docs". + Path string + + // SpecURL is the URL of the spec document. + SpecURL string + + // Title for the documentation site, default to: API documentation + Title string + + // Template specifies a custom template to serve the UI + Template string + + // AssetsURL points to the js asset that generates the documentation page. + AssetsURL string + } + + specOptions struct { + Path string + Document string + } +) + +//////////////////////////////////////////////////////////// +// Common UI options +//////////////////////////////////////////////////////////// + +// WithUIBasePath sets the base path from where to serve the UI assets. +// +// Default: "/" +func WithUIBasePath(base string) Option { + return func(o *options) { + if !strings.HasPrefix(base, "/") { + base = "/" + base + } + o.BasePath = base + } +} + +// WithUIPath sets the path from where to serve the UI assets (i.e. /{basepath}/{path}). +// +// Default: "docs" +func WithUIPath(pth string) Option { + return func(o *options) { + o.Path = pth + } +} + +// WithUITitle sets the title of the UI. +// +// Default: "API documentation" +func WithUITitle(title string) Option { + return func(o *options) { + o.Title = title + } +} + +// WithUIAssetsURL sets the URL from where to fetch the js assets. +// +// Defaults: +// +// - for Redoc: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js +// - for RapiDoc, this defaults to: https://unpkg.com/rapidoc/dist/rapidoc-min.js +// - for SwaggerUI: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js +func WithUIAssetsURL(assets string) Option { + return func(o *options) { + o.AssetsURL = assets + } +} + +// WithUITemplate allows to set a custom template for the UI. +// +// This allows the caller to fully customize the rendered UI, using the advanced options +// provided by any UI. +// +// The UI [middleware] will panic if the template does not parse or execute properly. +// +// Reference documentations to customize your js scriptlet: +// +// - for Redoc: https://github.com/Redocly/redoc/blob/main/docs/deployment/html.md +// - for RapiDoc: https://github.com/rapi-doc/RapiDoc +// - for SwaggerUI: https://github.com/swagger-api/swagger-ui +func WithUITemplate[StringOrBytes ~string | ~[]byte](tpl StringOrBytes) Option { + return func(o *options) { + o.Template = string(tpl) + } +} + +// WithSpecURL sets the URL of the spec document. +// +// Defaults to: /swagger.json +func WithSpecURL(u string) Option { + return func(o *options) { + o.SpecURL = u + } +} + +//////////////////////////////////////////////////////////// +// SwaggerUI UI options +//////////////////////////////////////////////////////////// + +func WithSwaggerUIOptions(opts SwaggerUIOptions) Option { + return func(o *options) { + o.SwaggerUIOptions = opts + } +} + +//////////////////////////////////////////////////////////// +// Spec options +//////////////////////////////////////////////////////////// + +// WithSpecPath sets the path of the spec document. +// +// This is "/swagger.json" by default. +func WithSpecPath(pth string) SpecOption { + return func(o *specOptions) { + if pth == "" { + return + } + + o.Path = pth + } +} + +// WithSpecPathFromOptions reuses the same SpecPath as the one specified in +// a set of UI [Option] (extract the path from the URL provided by [WithSpecURL]). +func WithSpecPathFromOptions(opts ...Option) SpecOption { + return func(o *specOptions) { + uiOpts := optionsWithDefaults(opts) + + // If the spec URL is provided, there is a non-default path to serve the spec. + // + // This makes sure that the UI middleware is aligned with the Spec middleware. + u, _ := url.Parse(uiOpts.SpecURL) + + if u.Path == "" { + return + } + + o.Path = u.Path + } +} + +func optionsWithDefaults(opts []Option, prepend ...Option) options { + o := options{ + BasePath: "/", + Path: defaultDocsPath, + SpecURL: defaultDocsURL, + Title: defaultDocsTitle, + } + + prepend = append(prepend, opts...) + for _, apply := range prepend { + apply(&o) + } + + return o +} + +func specOptionsWithDefaults(opts []SpecOption) specOptions { + o := specOptions{ + Path: defaultDocsURL, + } + + for _, apply := range opts { + apply(&o) + } + + if !strings.HasPrefix(o.Path, "/") { + o.Path = "/" + o.Path + } + + return o +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/rapidoc.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/rapidoc.go new file mode 100644 index 00000000000..c050331b4b0 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/rapidoc.go @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package docui + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "path" +) + +// UseRapiDoc creates a middleware to serve a documentation site for a swagger spec using [RapidDoc]. +// +// [RapiDoc]: https://github.com/rapi-doc/RapiDoc +func UseRapiDoc(opts ...Option) func(next http.Handler) http.Handler { + pth, assets := rapiDocSetup(opts) + return func(next http.Handler) http.Handler { + return serveUI(pth, assets, next) + } +} + +// RapiDoc creates a [http.Handler] to serve a documentation site for a swagger spec using [RapidDoc]. +// +// By default, the UI is served at route "/docs" +// +// This allows for altering the spec before starting the [http] listener. +// +// [RapiDoc]: https://github.com/rapi-doc/RapiDoc +func RapiDoc(next http.Handler, opts ...Option) http.Handler { + pth, assets := rapiDocSetup(opts) + + return serveUI(pth, assets, next) +} + +func rapiDocSetup(opts []Option) (pth string, assets []byte) { + o := optionsWithDefaults(opts, + // defaults for rapiDoc + WithUITemplate(rapidocTemplate), + WithUIAssetsURL(rapidocLatest), + ) + pth = path.Join(o.BasePath, o.Path) + tmpl := template.Must(template.New("rapidoc").Parse(o.Template)) + buf := bytes.NewBuffer(nil) + if err := tmpl.Execute(buf, o); err != nil { + panic(fmt.Errorf("cannot execute template: %w", err)) + } + + return pth, buf.Bytes() +} + +const ( + rapidocLatest = "https://unpkg.com/rapidoc/dist/rapidoc-min.js" + rapidocTemplate = ` + + + {{ .Title }} + + + + + + + +` +) diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/redoc.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/redoc.go new file mode 100644 index 00000000000..31054a2476e --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/redoc.go @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package docui + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "path" +) + +// UseRedoc creates a middleware to serve a documentation site for a swagger spec using [Redoc]. +// +// [Redoc]: https://redocly.com/docs/redoc +func UseRedoc(opts ...Option) func(next http.Handler) http.Handler { + pth, assets := redocSetup(opts) + + return func(next http.Handler) http.Handler { + return serveUI(pth, assets, next) + } +} + +// Redoc creates a [http.Handler] to serve a documentation site for a swagger spec using [Redoc]. +// +// By default, the UI is served at route "/docs" +// +// This allows for altering the spec before starting the [http] listener. +// +// [Redoc]: https://redocly.com/docs/redoc +func Redoc(next http.Handler, opts ...Option) http.Handler { + pth, assets := redocSetup(opts) + + return serveUI(pth, assets, next) +} + +func redocSetup(opts []Option) (pth string, assets []byte) { + o := optionsWithDefaults(opts, + // defaults for redoc + WithUITemplate(redocTemplate), + WithUIAssetsURL(redocLatest), + ) + + pth = path.Join(o.BasePath, o.Path) + tmpl := template.Must(template.New("redoc").Parse(o.Template)) + buf := bytes.NewBuffer(nil) + if err := tmpl.Execute(buf, o); err != nil { + panic(fmt.Errorf("cannot execute template: %w", err)) + } + + return pth, buf.Bytes() +} + +const ( + redocLatest = "https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js" // "https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js" + redocTemplate = ` + + + {{ .Title }} + + + + + + + + + + + + + +` +) diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/render.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/render.go new file mode 100644 index 00000000000..1fb744fd005 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/render.go @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package docui + +import ( + "fmt" + "net/http" + "path" +) + +// serveUI creates a [http.Handler] that serves a templated asset as text/html. +func serveUI(pth string, assets []byte, next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + if path.Clean(r.URL.Path) == pth { + rw.Header().Set(contentTypeHeader, "text/html; charset=utf-8") + rw.WriteHeader(http.StatusOK) + _, _ = rw.Write(assets) + + return + } + + if next != nil { + next.ServeHTTP(rw, r) + + return + } + + rw.Header().Set(contentTypeHeader, "text/plain") + rw.WriteHeader(http.StatusNotFound) + _, _ = fmt.Fprintf(rw, "%q not found", pth) + }) +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/spec.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/spec.go new file mode 100644 index 00000000000..59780199d5b --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/spec.go @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package docui + +import ( + "net/http" + "path" +) + +// UseSpec creates a middleware to serve a swagger spec as a JSON document. +func UseSpec(spec []byte, opts ...SpecOption) func(next http.Handler) http.Handler { + o := specOptionsWithDefaults(opts) + + return func(next http.Handler) http.Handler { + return handleSpec(o.Path, spec, next) + } +} + +// ServeSpec creates a [http.Handler] to serve a swagger spec as a JSON document. +// +// This allows for altering the spec before starting the [http] listener. +// +// Additional [SpecOption] can be used to change the path and the name of the document (defaults to "/swagger.json"). +func ServeSpec(spec []byte, next http.Handler, opts ...SpecOption) http.Handler { + o := specOptionsWithDefaults(opts) + + return handleSpec(o.Path, spec, next) +} + +func handleSpec(pth string, spec []byte, next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + if path.Clean(r.URL.Path) == pth { + rw.Header().Set(contentTypeHeader, applicationJSON) + rw.WriteHeader(http.StatusOK) + _, _ = rw.Write(spec) + + return + } + + if next != nil { + next.ServeHTTP(rw, r) + + return + } + + rw.Header().Set(contentTypeHeader, applicationJSON) + rw.WriteHeader(http.StatusNotFound) + }) +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/docui/swaggerui.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/swaggerui.go new file mode 100644 index 00000000000..db0aa05e6ab --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/swaggerui.go @@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package docui + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "path" +) + +// UseSwaggerUI creates a middleware to serve a documentation site for a swagger spec using [SwaggerUI]. +// +// [SwaggerUI]: https://swagger.io/tools/swagger-ui +func UseSwaggerUI(opts ...Option) func(next http.Handler) http.Handler { + pth, assets := swaggeruiSetup(opts) + + return func(next http.Handler) http.Handler { + return serveUI(pth, assets, next) + } +} + +// SwaggerUI creates a [http.Handler] to serve a documentation site for a swagger spec using [SwaggerUI]. +// +// By default, the UI is served at route "/docs" +// +// This allows for altering the spec before starting the [http] listener. +// +// [SwaggerUI]: https://swagger.io/tools/swagger-ui +func SwaggerUI(next http.Handler, opts ...Option) http.Handler { + pth, assets := swaggeruiSetup(opts) + + return serveUI(pth, assets, next) +} + +func swaggeruiSetup(opts []Option) (pth string, assets []byte) { + o := optionsWithDefaults(opts, + // defaults for SwaggerUI + WithUITemplate(swaggeruiTemplate), + WithUIAssetsURL(swaggerLatest), + ) + o.applySwaggerUIDefaults() + if o.OAuth2CallbackURL == "" { + o.OAuth2CallbackURL = path.Join(o.BasePath, o.Path, "oauth2-callback") + } + + pth = path.Join(o.BasePath, o.Path) + tmpl := template.Must(template.New("swaggerui").Parse(o.Template)) + buf := bytes.NewBuffer(nil) + if err := tmpl.Execute(buf, o); err != nil { + panic(fmt.Errorf("cannot execute template: %w", err)) + } + + return pth, buf.Bytes() +} + +const ( + swaggerLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" + swaggerPresetLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js" + swaggerStylesLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui.css" + swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png" + swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png" + swaggeruiTemplate = ` + + + + + {{ .Title }} + + {{- if .SwaggerStylesURL }} + + {{- end }} + {{- if .Favicon32 }} + + {{- end }} + {{- if .Favicon16 }} + + {{- end }} + + + + +
+ + + {{- if .SwaggerPresetURL }} + + {{- end }} + + + +` +) diff --git a/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go b/vendor/github.com/go-openapi/runtime/server-middleware/docui/swaggerui_oauth2.go similarity index 70% rename from vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go rename to vendor/github.com/go-openapi/runtime/server-middleware/docui/swaggerui_oauth2.go index 879bdbaadea..a38e408f153 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go +++ b/vendor/github.com/go-openapi/runtime/server-middleware/docui/swaggerui_oauth2.go @@ -1,30 +1,56 @@ // SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers // SPDX-License-Identifier: Apache-2.0 -package middleware +package docui import ( "bytes" "fmt" "net/http" + "path" "text/template" ) -func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler { - opts.EnsureDefaultsOauth2() +// UseSwaggerUIOAuth2Callback creates a middleware that serves a callback URL to complete +// a OAuth2 token handshake. +func UseSwaggerUIOAuth2Callback(opts ...Option) func(next http.Handler) http.Handler { + pth, assets := swaggeruiOAuth2Setup(opts) - pth := opts.OAuthCallbackURL - tmpl := template.Must(template.New("swaggeroauth").Parse(opts.Template)) - assets := bytes.NewBuffer(nil) - if err := tmpl.Execute(assets, opts); err != nil { + return func(next http.Handler) http.Handler { + return serveUI(pth, assets, next) + } +} + +// SwaggerUIOAuth2Callback creates a [http.Handler] that serves a callback URL to complete +// a OAuth2 token handshake. +func SwaggerUIOAuth2Callback(next http.Handler, opts ...Option) http.Handler { + pth, assets := swaggeruiOAuth2Setup(opts) + + return serveUI(pth, assets, next) +} + +func swaggeruiOAuth2Setup(opts []Option) (pth string, assets []byte) { + o := optionsWithDefaults(opts, + // defaults for SwaggerUI OAuth2 callback endpoint + WithUITemplate(swaggerOAuth2Template), + WithUIAssetsURL(swaggerLatest), + ) + o.applySwaggerUIDefaults() + if o.OAuth2CallbackURL == "" { + o.OAuth2CallbackURL = path.Join(o.BasePath, o.Path, "oauth2-callback") + } + + pth = o.OAuth2CallbackURL + tmpl := template.Must(template.New("swaggeroauth2").Parse(o.Template)) + buf := bytes.NewBuffer(nil) + if err := tmpl.Execute(buf, o); err != nil { panic(fmt.Errorf("cannot execute template: %w", err)) } - return serveUI(pth, assets.Bytes(), next) + return pth, buf.Bytes() } -const ( - swaggerOAuthTemplate = ` +const swaggerOAuth2Template = ` @@ -105,4 +131,3 @@ const ( ` -) diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/doc.go b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/doc.go new file mode 100644 index 00000000000..6f8aa313523 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/doc.go @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package mediatype provides a typed value for media types +// defined by RFC 7231 and RFC 2045. +// +// The matching/selection primitives used by both server-side +// validation and Accept-header negotiation. +// +// The package is stdlib-only. +// +// # The matching rule +// +// [MediaType.Matches] is asymmetric. The receiver acts as the "bound" +// (an allowed entry on the server side, or a candidate offer when +// matching against an Accept entry); the argument is the constraint +// (the actual incoming request, or the Accept entry being satisfied). +// +// - bare type/subtype must agree, with wildcard handling on either +// side ("*/*" matches anything; "type/*" matches any subtype); +// - if the receiver carries no parameters, any constraint is +// accepted regardless of its parameters; +// - otherwise every (key,value) pair on the constraint must be +// present on the receiver, with case-insensitive value +// comparison. The receiver may carry additional parameters the +// constraint does not list. +// +// q-values are NOT considered by [MediaType.Matches] — they are the +// negotiator's concern, handled inside [Set.BestMatch]. +package mediatype diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/lookup.go b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/lookup.go new file mode 100644 index 00000000000..598b60aca35 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/lookup.go @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mediatype + +// Lookup finds the entry in m matching mediaType, with alias-aware +// fallback. It is the canonical seam for codec-map lookups in both +// the client and server runtimes — placing the fallback policy here +// keeps alias definitions (and any future lookup tolerances) in one +// place. +// +// Lookup tries the following, in order, returning the first hit: +// +// 1. mediaType verbatim (fast path for callers that already pass a +// canonical, parameter-free string and store map keys in the +// same form). +// 2. An alias-aware walk against the parsed "type/subtype" form: +// a direct map hit on the parsed key, on its alias canonical +// if any, and finally an O(len(m)) scan returning any map +// entry whose key alias-canonicalizes to the same target. +// Catches both "map keyed by canonical, query uses alias" and +// "map keyed by one alias, query uses another alias of the +// same canonical". +// 3. When [AllowSuffix] is passed in opts: the same alias-aware +// walk against the RFC 6839 structured-syntax suffix base. +// Catches the "spec/traffic divergence" case (request for +// application/vnd.api+json finds a JSON consumer registered +// under application/json). Query-side suffix fold only — no +// map-side suffix folding. +// +// Lookup does NOT fall back to "*/*". Callers that want wildcard +// behavior (the historical resolveConsumer pattern in the client +// runtime) chain that themselves after a Lookup miss — keeping +// wildcard semantics explicit at each call site. +// +// Map keys are expected in canonical "type/subtype" form (no +// parameters). The runtime's default Consumers / Producers maps +// follow this convention. +// +// Returns (zero, false) when: +// +// - m is empty; +// - mediaType fails to parse and is not present verbatim; +// - none of the active steps hits. +// +// The malformed-vs-not-found distinction is intentionally elided: +// codec-lookup callers treat both as the same "no codec" error path. +func Lookup[T any](m map[string]T, mediaType string, opts ...MatchOption) (T, bool) { + var zero T + if len(m) == 0 { + return zero, false + } + o := applyMatchOptions(opts) + // Fast path: raw key (preserves any caller behaviour that stored + // non-canonical strings as map keys, and skips parsing in the + // common already-canonical case). + if v, ok := m[mediaType]; ok { + return v, true + } + mt, err := Parse(mediaType) + if err != nil { + return zero, false + } + key := mt.Type + "/" + mt.Subtype + if v, ok := findByCanonical(m, key); ok { + return v, true + } + if o.allowSuffix && mt.Suffix != "" { + base := mt.Base() + if baseKey := base.Type + "/" + base.Subtype; baseKey != key { + if v, ok := findByCanonical(m, baseKey); ok { + return v, true + } + } + } + return zero, false +} + +// findByCanonical returns the first entry in m whose key +// alias-canonicalizes to the same value as target. +// +// Tries direct hits before the O(len(m)) walk: +// +// 1. m[target] — map keyed by the same string. +// 2. m[aliases[target]] — map keyed by the canonical when target +// is an alias. +// 3. Walk m: return any entry where canonical(k) == canonical(target). +// Catches the "map keyed by an alias different from the query +// side" case (e.g. registered under text/yaml, queried as +// application/x-yaml — both canonicalize to application/yaml). +// +// Map size is single-digit for the runtime's codec maps, so the +// walk is negligible. +func findByCanonical[T any](m map[string]T, target string) (T, bool) { + if v, ok := m[target]; ok { + return v, true + } + canonTarget := target + if canon, ok := aliases[target]; ok { + canonTarget = canon + if v, ok := m[canonTarget]; ok { + return v, true + } + } + for k, v := range m { + kCanon := k + if c, ok := aliases[k]; ok { + kCanon = c + } + if kCanon == canonTarget { + return v, true + } + } + var zero T + return zero, false +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/match.go b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/match.go new file mode 100644 index 00000000000..6a16d0b6f2e --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/match.go @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mediatype + +// MatchFirst reports whether actual matches any entry in allowed, +// using [MediaType.Match] — the param-aware RFC 7231 rule plus the +// alias bridge from the package-internal alias table. +// +// The scan is multi-pass and tier-ordered: the first pass returns +// the first allowed entry that matches under [MatchExact] (RFC 7231 +// semantics); the second pass looks for a [MatchAlias] match; when +// [AllowSuffix] is in opts a third pass looks for a [MatchSuffix] +// match. This preserves the "stronger tier wins" ordering from +// [Set.BestMatch] while keeping the "first match wins" semantics +// within each tier. +// +// Return values: +// +// - (matched, true, nil) — the first allowed entry that +// matches, with exact matches preferred over alias matches. +// - (zero, false, nil) — actual is well-formed but no +// allowed entry accepts it. Maps to an HTTP 415 outcome. +// - (zero, false, err) — actual fails to parse. err +// wraps [ErrMalformed], so callers can use [errors.Is] to +// distinguish this case. Maps to an HTTP 400 outcome. +// +// Allowed entries that themselves fail to parse are skipped (they +// cannot match any well-formed actual), and no error is surfaced +// for them. +// +// An empty allowed list returns (zero, false, nil). MatchFirst is +// the primitive; callers decide what no-constraints means in their +// context. +func MatchFirst(allowed []string, actual string, opts ...MatchOption) (MediaType, bool, error) { + if len(allowed) == 0 { + return MediaType{}, false, nil + } + actualMT, err := Parse(actual) + if err != nil { + return MediaType{}, false, err + } + o := applyMatchOptions(opts) + // Tier-ordered passes over the allowed list. The list is + // typically short (an operation's Consumes set), so re-parsing + // each entry on every pass is cheaper than caching parses across + // passes. + tiers := []MatchKind{MatchExact, MatchAlias} + if o.allowSuffix { + tiers = append(tiers, MatchSuffix) + } + for _, want := range tiers { + for _, a := range allowed { + allowedMT, perr := Parse(a) + if perr != nil { + continue + } + if allowedMT.Match(actualMT) == want { + return allowedMT, true, nil + } + } + } + + return MediaType{}, false, nil +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/mediatype.go b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/mediatype.go new file mode 100644 index 00000000000..2138b82669f --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/mediatype.go @@ -0,0 +1,379 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mediatype + +import ( + "fmt" + "mime" + "strconv" + "strings" +) + +const wildcard = "*" + +// Internal constants for the suffixBase table and any future +// in-package references to the well-known base media types. +const ( + typeApplication = "application" + subtypeJSON = "json" + subtypeXML = "xml" + subtypeYAML = "yaml" + + mtYAML = typeApplication + "/" + subtypeYAML +) + +// Specificity scores returned by [MediaType.Specificity], ordered from +// least to most specific. +const ( + SpecificityAny = iota // "*/*" + SpecificityType // "type/*" + SpecificityExact // "type/subtype" (no params) + SpecificityExactWithParams // "type/subtype;k=v" +) + +// MatchKind classifies the strength of a match between two media +// types. Larger values represent stronger matches and win in +// negotiation tie-breaks. +// +// MatchExact covers direct subtype or wildcard agreement under RFC +// 7231 rules; MatchAlias is returned when the strict comparison +// fails but the two values agree after canonicalization through the +// internal alias table (see [MediaType.Canonical]); MatchSuffix is +// returned only when both alias and exact comparisons fail but the +// two values agree after folding the RFC 6839 structured-syntax +// suffix (see [MediaType.Base]). +// +// MatchSuffix matches are off by default at the negotiation / +// lookup callers — they count only when [AllowSuffix] is passed to +// [Set.BestMatch], [MatchFirst], or [Lookup]. The opt-in is the +// single user-visible knob; [MediaType.Match] itself always returns +// the strongest tier that succeeds. +type MatchKind int + +// MatchKind values. Returned by [MediaType.Match]. +const ( + MatchNone MatchKind = iota // no match + MatchSuffix // matched via the RFC 6839 suffix base + MatchAlias // matched via the alias table + MatchExact // matched directly (RFC 7231 semantics) +) + +// MatchOption configures the matching tolerances used by +// [Set.BestMatch], [MatchFirst], and [Lookup]. The zero behaviour +// is strict: only [MatchAlias] and [MatchExact] count. +type MatchOption func(*matchOptions) + +type matchOptions struct { + allowSuffix bool +} + +func applyMatchOptions(opts []MatchOption) matchOptions { + var o matchOptions + for _, opt := range opts { + opt(&o) + } + return o +} + +// AllowSuffix returns a [MatchOption] that lets the caller count +// [MatchSuffix] results as valid matches. Use this to opt into +// RFC 6839 structured-syntax suffix tolerance for situations where +// the client/server traffic does not strictly abide by the spec +// (typical example: server returning application/problem+json +// against operations that only declare application/json in +// produces). +func AllowSuffix() MatchOption { + return func(o *matchOptions) { + o.allowSuffix = true + } +} + +type mediaTypeError string + +func (e mediaTypeError) Error() string { + return string(e) +} + +// ErrMalformed is the sentinel returned (wrapped) by [Parse] when its input +// cannot be parsed as an RFC 7231 media type. +// +// Callers can test for it with [errors.Is] to distinguish a client-side +// malformed Content-Type header (an HTTP 400 outcome) from a well-formed +// value that simply matches no allowed entry (an HTTP 415 outcome). +const ErrMalformed mediaTypeError = "mediatype: malformed" + +// MediaType is a parsed RFC 7231 media type with optional parameters and +// an optional q-value (used by Accept negotiation). +// +// Type, Subtype and the keys of Params are lowercased. Parameter values +// are preserved verbatim; comparisons are case-insensitive (matching the +// pre-v0.30 behaviour and the common convention for charset, version, etc.). +// +// Suffix exposes the RFC 6839 structured syntax suffix (the token after +// the final '+' in Subtype) as a parallel hint. Subtype itself retains +// the full wire value, so existing callers comparing Subtype against a +// string see no change. +type MediaType struct { + Type string + Subtype string + Suffix string + Params map[string]string + Q float64 +} + +// suffixBase maps a known RFC 6839 / RFC 9512 structured syntax +// suffix (without the leading '+', lowercased) to its base media +// type. It is the authoritative table consulted by [MediaType.Base]. +// +// The table is intentionally small: only suffixes whose base type +// has a codec in the default runtime maps are listed. CBOR, zip, +// BER, DER, FastInfoset and WBXML are registered by IANA but have +// no default codec in this runtime; adding them is gated on having +// something to do with them. +// +// Package-internal by design: the external API is [MediaType.Base]. +// If users ever need to extend the table, a Register-style function +// is the right answer, not an exported mutable map. +var suffixBase = map[string]MediaType{ + subtypeJSON: {Type: typeApplication, Subtype: subtypeJSON}, + subtypeXML: {Type: typeApplication, Subtype: subtypeXML}, + subtypeYAML: {Type: typeApplication, Subtype: subtypeYAML}, +} + +// aliases maps a deprecated or legacy media-type name to its +// canonical registered equivalent. Keys are the lowercased +// "type/subtype" form with no parameters; values are the canonical +// "type/subtype" form, also without parameters. +// +// Entries are limited to media types whose authoritative RFC +// explicitly names the alias. The seed entries cite RFC 9512 §2.1, +// which enumerates "Deprecated alias names for this type: +// application/x-yaml, text/yaml, and text/x-yaml" as part of the +// IANA registration template for application/yaml. +// +// Pull requests adding entries need an analogous citation in the +// commit message; entries without authoritative backing belong in +// caller-side canonicalization, not here. +// +// Package-internal by design: the external API is +// [MediaType.Canonical] and [MediaType.Match]. If users ever need +// to register their own aliases, a Register-style function is the +// right answer, not an exported mutable map. +var aliases = map[string]string{ + "application/x-yaml": mtYAML, // RFC 9512 §2.1 + "text/yaml": mtYAML, // RFC 9512 §2.1 + "text/x-yaml": mtYAML, // RFC 9512 §2.1 +} + +// Parse parses a single media type. The input may carry parameters and a +// q-value; the q-value is extracted into [MediaType.Q] and removed from +// [MediaType.Params]. +// +// An empty input returns an error. +func Parse(s string) (MediaType, error) { + s = strings.TrimSpace(s) + if s == "" { + return MediaType{}, fmt.Errorf("%w: empty value", ErrMalformed) + } + full, params, err := mime.ParseMediaType(s) + if err != nil { + return MediaType{}, fmt.Errorf("%w: %w", ErrMalformed, err) + } + slash := strings.IndexByte(full, '/') + if slash <= 0 || slash == len(full)-1 { + return MediaType{}, fmt.Errorf("%w: %q has no subtype", ErrMalformed, s) + } + mt := MediaType{ + Type: full[:slash], + Subtype: full[slash+1:], + Q: 1.0, + } + // RFC 6839: structured syntax suffix is the trailing '+'-delimited + // token of the subtype. Only the last '+' counts ("foo+bar+json" → + // suffix "json"). A trailing '+' with nothing after it is not a + // valid suffix and is ignored. mime.ParseMediaType has already + // lowercased the subtype, so no further ToLower is needed. + if plus := strings.LastIndexByte(mt.Subtype, '+'); plus >= 0 && plus < len(mt.Subtype)-1 { + mt.Suffix = mt.Subtype[plus+1:] + } + if q, ok := params["q"]; ok { + if qf, perr := strconv.ParseFloat(q, 64); perr == nil { + if qf < 0 { + qf = 0 + } + if qf > 1 { + qf = 1 + } + mt.Q = qf + } + delete(params, "q") + } + if len(params) > 0 { + mt.Params = params + } + + return mt, nil +} + +// String renders the canonical "type/subtype;k=v;k=v" form. Parameters are +// emitted in lexicographic key order (the standard library guarantees this) +// so the result is stable. The q-value is NOT emitted — it is meta, not +// part of the media type identity. +func (m MediaType) String() string { + if m.Type == "" && m.Subtype == "" { + return "" + } + + return mime.FormatMediaType(m.Type+"/"+m.Subtype, m.Params) +} + +// Matches reports whether the receiver accepts other, per the package +// documentation: the receiver is the bound, other is the constraint. +func (m MediaType) Matches(other MediaType) bool { + if !typeAgrees(m.Type, other.Type) { + return false + } + if !subtypeAgrees(m.Type, m.Subtype, other.Type, other.Subtype) { + return false + } + if len(m.Params) == 0 { + return true + } + for k, v := range other.Params { + sv, ok := m.Params[k] + if !ok || !strings.EqualFold(sv, v) { + return false + } + } + + return true +} + +// Specificity returns a numeric score for ordering matches. Higher is more +// specific. The returned value is one of [SpecificityAny], +// [SpecificityType], [SpecificityExact] or [SpecificityExactWithParams]. +func (m MediaType) Specificity() int { + if m.Type == wildcard && m.Subtype == wildcard { + return SpecificityAny + } + if m.Subtype == wildcard { + return SpecificityType + } + if len(m.Params) == 0 { + return SpecificityExact + } + + return SpecificityExactWithParams +} + +// typeAgrees reports whether two top-level types match, allowing "*" on +// either side. A type of "*" without a "*" subtype is rejected per RFC +// 7231 §5.3.2 ("*/sub" is not valid), but Parse never produces such a +// shape — it goes through mime.ParseMediaType. +func typeAgrees(a, b string) bool { + return a == wildcard || b == wildcard || a == b +} + +// subtypeAgrees handles the "type/*" wildcard: the bare type must match +// (a "*/*" pair has already been accepted by typeAgrees above). +func subtypeAgrees(at, asub, bt, bsub string) bool { + if at == wildcard || bt == wildcard { + // at least one side is "*/*" or "*/sub". With typeAgrees having + // returned true, we accept. + return true + } + if asub == wildcard || bsub == wildcard { + return true + } + + return asub == bsub +} + +// StripParams returns a copy of m with no parameters. Q is preserved +// because it drives negotiation ordering, not media-type identity. +// +// Useful for the legacy "ignore parameters" negotiation mode. +func (m MediaType) StripParams() MediaType { + return MediaType{Type: m.Type, Subtype: m.Subtype, Suffix: m.Suffix, Q: m.Q} +} + +// Base returns the base media type implied by the RFC 6839 structured +// syntax suffix, or m unchanged when: +// +// - Suffix is empty; +// - Suffix is not present in the package-internal suffix→base table. +// +// The returned value represents the structural base only: it carries +// no parameters and no q-value. Use it to find a codec for the +// underlying wire format — for example, "application/vnd.api+json" +// resolves to "application/json". +// +// Base does not mutate the receiver. +func (m MediaType) Base() MediaType { + if m.Suffix == "" { + return m + } + base, ok := suffixBase[m.Suffix] + if !ok { + return m + } + return base +} + +// Canonical returns m rewritten to its canonical media type via +// the package-internal alias table, or m unchanged when +// (Type, Subtype) is not a known alias. Params and Q are preserved on the returned value; Suffix +// is recomputed from the canonical Subtype (none of the current +// entries carry a suffix, but the contract is forward-safe). +// +// Canonical does not mutate the receiver. +func (m MediaType) Canonical() MediaType { + key := m.Type + "/" + m.Subtype + canon, ok := aliases[key] + if !ok { + return m + } + slash := strings.IndexByte(canon, '/') + out := m + out.Type = canon[:slash] + out.Subtype = canon[slash+1:] + out.Suffix = "" + if plus := strings.LastIndexByte(out.Subtype, '+'); plus >= 0 && plus < len(out.Subtype)-1 { + out.Suffix = out.Subtype[plus+1:] + } + return out +} + +// Match reports how m matches other, classifying the result by +// [MatchKind]. Used by negotiation to rank candidate offers: +// stronger tiers win when both apply. +// +// Returns, strongest first: +// +// - MatchExact when m.Matches(other) is true under the strict +// RFC 7231 rules (including wildcards and the param subset +// rule). +// - MatchAlias when m.Canonical().Matches(other.Canonical()) +// is true but the strict comparison failed. +// - MatchSuffix when m.Base().Canonical().Matches( +// other.Base().Canonical()) is true but the alias comparison +// failed (RFC 6839 structured-syntax suffix fold). +// - MatchNone otherwise. +// +// The asymmetric "bound vs constraint" rule of [MediaType.Matches] +// is preserved at every tier. Match itself is always lenient — the +// opt-in to count MatchSuffix lives one level up at [Set.BestMatch], +// [MatchFirst], and [Lookup] via [AllowSuffix]. +func (m MediaType) Match(other MediaType) MatchKind { + if m.Matches(other) { + return MatchExact + } + if m.Canonical().Matches(other.Canonical()) { + return MatchAlias + } + if m.Base().Canonical().Matches(other.Base().Canonical()) { + return MatchSuffix + } + return MatchNone +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/set.go b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/set.go new file mode 100644 index 00000000000..70f62a18d41 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/mediatype/set.go @@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package mediatype + +import ( + "strings" +) + +// Set is a list of media types — typically the parsed value of an Accept +// header, or a list of server-side offers. +type Set []MediaType + +// ParseAccept parses a comma-separated list of media types, as found in +// the Accept, Accept-Charset (etc.) HTTP headers. Malformed entries are +// skipped silently — be liberal in what you accept. +// +// An empty input returns nil. +func ParseAccept(s string) Set { + parts := splitTopLevel(s) + if len(parts) == 0 { + return nil + } + out := make(Set, 0, len(parts)) + for _, p := range parts { + mt, err := Parse(p) + if err != nil { + continue + } + out = append(out, mt) + } + + return out +} + +// BestMatch picks the offer most acceptable to the receiver's Accept +// entries. Selection follows RFC 7231 §5.3.2 plus tier-aware +// ranking: +// +// - highest q-value wins; +// - ties on q broken by the highest [MediaType.Specificity] of the +// matching Accept entry; +// - ties on specificity broken by [MatchKind] (MatchExact beats +// MatchAlias beats MatchSuffix); +// - ties on match kind broken by earliest position in offered. +// +// Accept entries with q=0 are treated as exclusions and never match. +// MatchSuffix results are only counted when [AllowSuffix] is passed. +// Returns ok=false if no offer matched any non-zero-q entry. +func (s Set) BestMatch(offered Set, opts ...MatchOption) (best MediaType, ok bool) { + if len(s) == 0 || len(offered) == 0 { + return MediaType{}, false + } + o := applyMatchOptions(opts) + bestQ := -1.0 + bestSpec := -1 + bestKind := MatchNone + bestIdx := -1 + for i, offer := range offered { + for _, entry := range s { + if entry.Q == 0 { + continue + } + kind := offer.Match(entry) + if kind == MatchNone { + continue + } + if kind == MatchSuffix && !o.allowSuffix { + continue + } + spec := entry.Specificity() + switch { + case entry.Q > bestQ: + best, ok = offer, true + bestQ = entry.Q + bestSpec = spec + bestKind = kind + bestIdx = i + case entry.Q < bestQ: + // not better + case spec > bestSpec: + best, ok = offer, true + bestSpec = spec + bestKind = kind + bestIdx = i + case spec < bestSpec: + // not better + case kind > bestKind: + best, ok = offer, true + bestKind = kind + bestIdx = i + case kind < bestKind: + // not better + case bestIdx < 0 || i < bestIdx: + best, ok = offer, true + bestIdx = i + } + } + } + + return best, ok +} + +// splitTopLevel splits s on top-level commas, respecting double-quoted +// strings (RFC 7230 §3.2.6 — quoted-string). +func splitTopLevel(s string) []string { + if strings.IndexByte(s, ',') < 0 { + if t := strings.TrimSpace(s); t != "" { + return []string{t} + } + return nil + } + var out []string + start := 0 + inQuote := false + escape := false + for i := range len(s) { + c := s[i] + switch { + case escape: + escape = false + case inQuote && c == '\\': + escape = true + case c == '"': + inQuote = !inQuote + case c == ',' && !inQuote: + if t := strings.TrimSpace(s[start:i]); t != "" { + out = append(out, t) + } + start = i + 1 + } + } + if t := strings.TrimSpace(s[start:]); t != "" { + out = append(out, t) + } + + return out +} diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/doc.go b/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/doc.go new file mode 100644 index 00000000000..a9f278c31b1 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/doc.go @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package negotiate provides server-side HTTP content negotiation +// helpers — selecting the response Content-Type from an Accept header +// and the response Content-Encoding from an Accept-Encoding header. +// +// The package is stdlib-only (modulo the typed [mediatype.MediaType] +// values it consumes). +// +// The exported [ContentType] honours MIME-type parameters by default; +// use [WithIgnoreParameters] to restore the pre-v0.30 looser match. +package negotiate diff --git a/vendor/github.com/go-openapi/runtime/middleware/header/header.go b/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/header/header.go similarity index 100% rename from vendor/github.com/go-openapi/runtime/middleware/header/header.go rename to vendor/github.com/go-openapi/runtime/server-middleware/negotiate/header/header.go diff --git a/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/negotiate.go b/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/negotiate.go new file mode 100644 index 00000000000..c36ad5adaea --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/server-middleware/negotiate/negotiate.go @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package negotiate + +import ( + "net/http" + "strings" + + "github.com/go-openapi/runtime/server-middleware/mediatype" + "github.com/go-openapi/runtime/server-middleware/negotiate/header" +) + +// Option configures [ContentType] behaviour. +type Option func(*options) + +type options struct { + ignoreParameters bool + matchSuffix bool +} + +func optionsWithDefaults(opts []Option) options { + var o options + for _, apply := range opts { + apply(&o) + } + + return o +} + +// WithIgnoreParameters returns an [Option] that strips MIME-type +// parameters from both Accept entries and offers before matching, restoring +// the behaviour the runtime had before v0.30. +// +// New code should leave parameters honoured (the default). This option +// exists for applications that depend on the looser pre-v0.30 match — +// most often because their producers and Accept clients use mismatched +// charset or version params that they treat as informational. +// +// Example — per-call opt-out: +// +// chosen := negotiate.ContentType(r, offers, "", +// negotiate.WithIgnoreParameters(true), +// ) +// +// Example — server-wide opt-out (via [middleware.Context]): +// +// ctx := middleware.NewContext(spec, api, nil).SetIgnoreParameters(true) +func WithIgnoreParameters(ignore bool) Option { + return func(o *options) { + o.ignoreParameters = ignore + } +} + +// WithMatchSuffix returns an [Option] that extends content +// negotiation to tolerate RFC 6839 structured-syntax suffix media +// types. When enabled, an Accept entry of "application/json" +// matches an offer of "application/vnd.api+json" and vice versa, +// for the suffixes recognised by the runtime (+json, +xml, +yaml). +// +// Default: strict (false). Use only when interoperating with +// clients or servers that do not strictly abide by the spec — for +// example, servers returning application/problem+json error +// responses against operations that only declare application/json +// in produces. +// +// Suffix matches always lose to exact and alias matches when those +// are on offer; see [mediatype.MatchKind] for the tier ordering. +// +// Example — per-call opt-in: +// +// chosen := negotiate.ContentType(r, offers, "", +// negotiate.WithMatchSuffix(true), +// ) +// +// Example — server-wide opt-in (via [middleware.Context]): +// +// ctx := middleware.NewContext(spec, api, nil).SetMatchSuffix(true) +func WithMatchSuffix(enable bool) Option { + return func(o *options) { + o.matchSuffix = enable + } +} + +// ContentEncoding returns the best offered content encoding for the +// request's Accept-Encoding header. If two offers match with equal +// weight then the offer earlier in the list is preferred. If no offers +// are acceptable, then "" is returned. +// +// Encoding tokens have no parameters, so this function is unaffected by +// the v0.30 parameter-honouring change to [ContentType]. +func ContentEncoding(r *http.Request, offers []string) string { + bestOffer := "identity" + bestQ := -1.0 + specs := header.ParseAccept(r.Header, "Accept-Encoding") + for _, offer := range offers { + for _, spec := range specs { + if spec.Q > bestQ && + (spec.Value == "*" || spec.Value == offer) { + bestQ = spec.Q + bestOffer = offer + } + } + } + if bestQ == 0 { + bestOffer = "" + } + + return bestOffer +} + +// ContentType returns the best offered content type for the request's +// Accept header. If two offers match with equal weight, then the more +// specific offer is preferred (text/* trumps */*; type/subtype trumps +// type/*). If two offers match with equal weight and specificity, then +// the offer earlier in the list is preferred. If no offers match, then +// defaultOffer is returned. +// +// As of v0.30 the matching rule honours MIME-type parameters: an Accept +// entry of "text/plain;charset=utf-8" matches an offer of bare +// "text/plain" (offer carries no constraint), but it does NOT match an +// offer of "text/plain;charset=ascii" (charset values disagree). Pass +// [WithIgnoreParameters](true) to restore the pre-v0.30 behaviour where +// parameters were stripped before matching — see [WithIgnoreParameters] +// for details and an example. +// +// When the Accept header is absent, the first offer is returned +// unchanged (param-stripping is irrelevant in that case). +func ContentType(r *http.Request, offers []string, defaultOffer string, opts ...Option) string { + if len(offers) == 0 { + return defaultOffer + } + o := optionsWithDefaults(opts) + + // Per RFC 7230 §3.2.2, multiple Accept headers are equivalent to a + // single comma-joined value. Join before parsing so we don't drop + // later entries. + acceptValues := r.Header.Values("Accept") + if len(acceptValues) == 0 { + return offers[0] + } + acceptSet := mediatype.ParseAccept(strings.Join(acceptValues, ", ")) + if len(acceptSet) == 0 { + return defaultOffer + } + + offerSet := make(mediatype.Set, 0, len(offers)) + rawByIdx := make([]string, 0, len(offers)) + for _, raw := range offers { + mt, err := mediatype.Parse(raw) + if err != nil { + continue + } + offerSet = append(offerSet, mt) + rawByIdx = append(rawByIdx, raw) + } + if len(offerSet) == 0 { + return defaultOffer + } + + if o.ignoreParameters { + acceptSet = stripSet(acceptSet) + offerSet = stripSet(offerSet) + } + + var matchOpts []mediatype.MatchOption + if o.matchSuffix { + matchOpts = append(matchOpts, mediatype.AllowSuffix()) + } + best, ok := acceptSet.BestMatch(offerSet, matchOpts...) + if !ok { + return defaultOffer + } + // Return the original raw offer string so callers receive the value + // they declared, with its parameters preserved. + for i, mt := range offerSet { + if mt.Type == best.Type && mt.Subtype == best.Subtype && sameParams(mt.Params, best.Params) { + return rawByIdx[i] + } + } + + return best.String() +} + +func stripSet(s mediatype.Set) mediatype.Set { + out := make(mediatype.Set, len(s)) + for i, m := range s { + out[i] = m.StripParams() + } + + return out +} + +func sameParams(a, b map[string]string) bool { + if len(a) != len(b) { + return false + } + for k, v := range a { + if b[k] != v { + return false + } + } + + return true +} diff --git a/vendor/github.com/go-openapi/runtime/statuses.go b/vendor/github.com/go-openapi/runtime/statuses.go index c0f3e6b4477..273d9c6ced3 100644 --- a/vendor/github.com/go-openapi/runtime/statuses.go +++ b/vendor/github.com/go-openapi/runtime/statuses.go @@ -60,7 +60,7 @@ var Statuses = map[int]string{ 444: "No Response", 449: "Retry With", 450: "Blocked by Windows Parental Controls", - 451: "Wrong Exchange Server", + 451: "Unavailable For Legal Reasons", 499: "Client Closed Request", 500: "Internal Server Error", 501: "Not Implemented", diff --git a/vendor/github.com/go-openapi/runtime/text.go b/vendor/github.com/go-openapi/runtime/text.go index 1252ac88c71..3764a87fe51 100644 --- a/vendor/github.com/go-openapi/runtime/text.go +++ b/vendor/github.com/go-openapi/runtime/text.go @@ -36,14 +36,14 @@ func TextConsumer() Consumer { if tu, ok := data.(encoding.TextUnmarshaler); ok { err := tu.UnmarshalText(b) if err != nil { - return fmt.Errorf("text consumer: %v", err) + return fmt.Errorf("text consumer: %w", err) } return nil } t := reflect.TypeOf(data) - if data != nil && t.Kind() == reflect.Ptr { + if data != nil && t.Kind() == reflect.Pointer { v := reflect.Indirect(reflect.ValueOf(data)) if t.Elem().Kind() == reflect.String { v.SetString(string(b)) @@ -70,7 +70,7 @@ func TextProducer() Producer { if tm, ok := data.(encoding.TextMarshaler); ok { txt, err := tm.MarshalText() if err != nil { - return fmt.Errorf("text producer: %v", err) + return fmt.Errorf("text producer: %w", err) } _, err = writer.Write(txt) return err diff --git a/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go b/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go index ca71edbb1ba..b7fab88906c 100644 --- a/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go +++ b/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go @@ -6,8 +6,9 @@ package yamlpc import ( "io" - "github.com/go-openapi/runtime" yaml "go.yaml.in/yaml/v3" + + "github.com/go-openapi/runtime" ) // YAMLConsumer creates a consumer for [yaml] data. diff --git a/vendor/github.com/go-openapi/strfmt/.gitignore b/vendor/github.com/go-openapi/strfmt/.gitignore index bbdffea78a0..20c4e0fa048 100644 --- a/vendor/github.com/go-openapi/strfmt/.gitignore +++ b/vendor/github.com/go-openapi/strfmt/.gitignore @@ -4,3 +4,4 @@ .env .mcp.json go.work.sum +.worktrees diff --git a/vendor/github.com/go-openapi/strfmt/.golangci.yml b/vendor/github.com/go-openapi/strfmt/.golangci.yml index 8a3b3bff7c4..31480c7138a 100644 --- a/vendor/github.com/go-openapi/strfmt/.golangci.yml +++ b/vendor/github.com/go-openapi/strfmt/.golangci.yml @@ -6,6 +6,8 @@ linters: - depguard - funlen - gomoddirectives + - gomodguard + - gomodguard_v2 - godox - exhaustruct - nlreturn diff --git a/vendor/github.com/go-openapi/strfmt/CONTRIBUTORS.md b/vendor/github.com/go-openapi/strfmt/CONTRIBUTORS.md index 4aa4fcb54fc..fa17ff3111c 100644 --- a/vendor/github.com/go-openapi/strfmt/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/strfmt/CONTRIBUTORS.md @@ -4,12 +4,12 @@ | Total Contributors | Total Contributions | | --- | --- | -| 40 | 239 | +| 41 | 243 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | | @casualjim | 88 | | -| @fredbi | 71 | | +| @fredbi | 74 | | | @youyuanwu | 13 | | | @jlambatl | 9 | | | @GlenDC | 5 | | @@ -26,6 +26,7 @@ | @bg451 | 2 | | | @aleksandr-vin | 2 | | | @ujjwalsh | 1 | | +| @patchwright | 1 | | | @kenjones-cisco | 1 | | | @jwalter1-quest | 1 | | | @ccoVeille | 1 | | diff --git a/vendor/github.com/go-openapi/strfmt/README.md b/vendor/github.com/go-openapi/strfmt/README.md index 4afef43733d..15ee0e5826d 100644 --- a/vendor/github.com/go-openapi/strfmt/README.md +++ b/vendor/github.com/go-openapi/strfmt/README.md @@ -67,7 +67,7 @@ It also provides convenient extensions to go-openapi users. - [x] go-openapi custom format extensions - bsonobjectid (BSON objectID) - creditcard - - duration (e.g. "3 weeks", "1ms") + - duration (e.g. "3 weeks", "1ms") (aka "duration-human") - hexcolor (e.g. "#FFFFFF") - isbn, isbn10, isbn13 - mac (e.g "01:02:03:04:05:06") @@ -76,11 +76,26 @@ It also provides convenient extensions to go-openapi users. - uuid, uuid3, uuid4, uuid5, uuid7 - cidr (e.g. "192.0.2.1/24", "2001:db8:a0b:12f0::1/32") - ulid (e.g. "00000PP9HGSBSSDZ1JTEXBJ0PW", [spec](https://github.com/ulid/spec)) +- [x] JSON-schema draft 2020 formats + - duration-iso8601 B(e.g. "P2W") > NOTE: as the name stands for, this package is intended to support string formatting only. > It does not provide validation for numerical values with swagger format extension for JSON types "number" or > "integer" (e.g. float, double, int32...). +## Durations + +We have 2 very different definitions of the "duration" format: the "human-readable" duration that used to be just "duration", +and the new "duration-iso8601". There is no "dual" parser that accepts both formats: types are specialized. + +To clarify the situation, a new alias for the duration format is introduced "duration-human" (e.g. "1 ms"), as opposed to +"duration-iso8601". + +The `Default` format registry wires "duration-human" as the default mapping for "duration" +(preexisting behavior, no breaking change - aligned with Swagger 2.0 which did not define "duration"). + +A new `JSONSchema2020` registry wires "duration-iso8601" as the default mapping for "duration". + ### Type conversion All types defined here are stringers and may be converted to strings with `.String()`. @@ -104,6 +119,7 @@ List of defined types: - Date - DateTime - Duration +- DurationISO8601 and `ISODuration[P ISODurationPolicy]` (for optional behavior) - Email - HexColor - Hostname diff --git a/vendor/github.com/go-openapi/strfmt/bson.go b/vendor/github.com/go-openapi/strfmt/bson.go index 16a83f64086..b0c05d83bcc 100644 --- a/vendor/github.com/go-openapi/strfmt/bson.go +++ b/vendor/github.com/go-openapi/strfmt/bson.go @@ -10,11 +10,6 @@ import ( "fmt" ) -func init() { //nolint:gochecknoinits // registers bsonobjectid format in the default registry - var id ObjectId - Default.Add("bsonobjectid", &id, IsBSONObjectID) -} - // IsBSONObjectID returns true when the string is a valid BSON [ObjectId]. func IsBSONObjectID(str string) bool { _, err := objectIDFromHex(str) diff --git a/vendor/github.com/go-openapi/strfmt/country.go b/vendor/github.com/go-openapi/strfmt/country.go new file mode 100644 index 00000000000..39aeb3d7861 --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/country.go @@ -0,0 +1,173 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package strfmt + +import ( + "database/sql/driver" + "encoding/json" + "fmt" + + "github.com/go-openapi/strfmt/internal/countries" +) + +// Country represents an ISO 3166 country alpha-3 or alpha-2 code as a string format. +// +// swagger:strfmt country. +type Country struct { + countries.Country + + l int +} + +const ( + alpha2Len = 2 + alpha3Len = 3 +) + +// IsCountry checks if a string is a valid ISO 3166 country format. +func IsCountry(str string) bool { + _, err := ParseCountry(str) + + return err == nil +} + +// ParseCountry parses a string that represents a valid [Country]. +func ParseCountry(str string) (Country, error) { + l := len(str) + switch l { + case alpha3Len: + c, ok := countries.CountriesISO3[str] + if !ok { + return Country{}, fmt.Errorf("unrecognized strfmt.Country %q: %w", str, ErrFormat) + } + + return Country{Country: c, l: alpha3Len}, nil + case alpha2Len: + c, ok := countries.CountriesISO2[str] + if !ok { + return Country{}, fmt.Errorf("unrecognized strfmt.Country %q: %w", str, ErrFormat) + } + + return Country{Country: c, l: alpha2Len}, nil + default: + return Country{}, fmt.Errorf("invalid length for strfmt.Country in: %q: %w", str, ErrFormat) + } +} + +// MarshalText returns this instance into text. +func (u Country) MarshalText() ([]byte, error) { + return []byte(u.String()), nil +} + +// UnmarshalText hydrates this instance from text. +func (u *Country) UnmarshalText(data []byte) error { // validation is performed later on + c, err := ParseCountry(string(data)) + if err != nil { + return err + } + + *u = c + + return nil +} + +// Scan read a value from a database driver. +func (u *Country) Scan(raw any) error { + switch v := raw.(type) { + case []byte: + c, err := ParseCountry(string(v)) + if err != nil { + return err + } + *u = c + case string: + c, err := ParseCountry(v) + if err != nil { + return err + } + *u = c + default: + return fmt.Errorf("cannot sql.Scan() strfmt.Country from: %#v: %w", v, ErrFormat) + } + + return nil +} + +// Value converts a value to a database driver value. +func (u Country) Value() (driver.Value, error) { + return driver.Value(u.String()), nil +} + +func (u Country) String() string { + switch u.l { + case alpha3Len: + return u.ISOAlpha3 + case alpha2Len: + return u.ISOAlpha2 + default: + return "" + } +} + +// MarshalJSON returns the [Country] as JSON. +func (u Country) MarshalJSON() ([]byte, error) { + return json.Marshal(u.String()) +} + +// UnmarshalJSON sets the [Country] from JSON. +func (u *Country) UnmarshalJSON(data []byte) error { + if string(data) == jsonNull { + return nil + } + var ustr string + if err := json.Unmarshal(data, &ustr); err != nil { + return err + } + + c, err := ParseCountry(ustr) + if err != nil { + return err + } + + *u = c + + return nil +} + +// DeepCopyInto copies the receiver and writes its value into out. +func (u *Country) DeepCopyInto(out *Country) { + *out = *u +} + +// DeepCopy copies the receiver into a new [Country]. +func (u *Country) DeepCopy() *Country { + if u == nil { + return nil + } + + out := new(Country) + u.DeepCopyInto(out) + + return out +} + +// GobEncode implements the gob.GobEncoder interface. +func (u Country) GobEncode() ([]byte, error) { + return u.MarshalText() +} + +// GobDecode implements the gob.GobDecoder interface. +func (u *Country) GobDecode(data []byte) error { + return u.UnmarshalText(data) +} + +// MarshalBinary implements the encoding.[encoding.BinaryMarshaler] interface. +func (u Country) MarshalBinary() ([]byte, error) { + return u.MarshalText() +} + +// UnmarshalBinary implements the encoding.[encoding.BinaryUnmarshaler] interface. +func (u *Country) UnmarshalBinary(data []byte) error { + return u.UnmarshalText(data) +} diff --git a/vendor/github.com/go-openapi/strfmt/currency.go b/vendor/github.com/go-openapi/strfmt/currency.go new file mode 100644 index 00000000000..7af115663f2 --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/currency.go @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package strfmt + +import ( + "database/sql/driver" + "encoding/json" + "fmt" + + "golang.org/x/text/currency" +) + +// Currency represents an ISO 4217 currency alpha-3 code as a string format. +// +// # Implementation +// +// golang.org/x/text/currency +// +// swagger:strfmt currency. +type Currency struct { + currency.Unit +} + +// IsCurrency checks if a string is a valid currency format. +func IsCurrency(str string) bool { + _, err := ParseCurrency(str) + + return err == nil +} + +// ParseCurrency parses a string that represents a valid [Currency]. +func ParseCurrency(str string) (Currency, error) { + cur, err := currency.ParseISO(str) + + return Currency{Unit: cur}, err +} + +// MarshalText returns this instance into text. +func (u Currency) MarshalText() ([]byte, error) { + return []byte(u.Unit.String()), nil +} + +// UnmarshalText hydrates this instance from text. +func (u *Currency) UnmarshalText(data []byte) error { // validation is performed later on + cur, err := ParseCurrency(string(data)) + if err != nil { + return err + } + *u = cur + + return nil +} + +// Scan read a value from a database driver. +func (u *Currency) Scan(raw any) error { + switch v := raw.(type) { + case []byte: + cur, err := ParseCurrency(string(v)) + if err != nil { + return err + } + *u = cur + case string: + cur, err := ParseCurrency(v) + if err != nil { + return err + } + *u = cur + default: + return fmt.Errorf("cannot sql.Scan() strfmt.Currency from: %#v: %w", v, ErrFormat) + } + + return nil +} + +// Value converts a value to a database driver value. +func (u Currency) Value() (driver.Value, error) { + return driver.Value(u.String()), nil +} + +func (u Currency) String() string { + return u.Unit.String() +} + +// MarshalJSON returns the [Currency] as JSON. +func (u Currency) MarshalJSON() ([]byte, error) { + return json.Marshal(u.String()) +} + +// UnmarshalJSON sets the [Currency] from JSON. +func (u *Currency) UnmarshalJSON(data []byte) error { + if string(data) == jsonNull { + return nil + } + var ustr string + if err := json.Unmarshal(data, &ustr); err != nil { + return err + } + + cur, err := ParseCurrency(ustr) + if err != nil { + return err + } + + *u = cur + + return nil +} + +// DeepCopyInto copies the receiver and writes its value into out. +func (u *Currency) DeepCopyInto(out *Currency) { + *out = *u +} + +// DeepCopy copies the receiver into a new [Currency]. +func (u *Currency) DeepCopy() *Currency { + if u == nil { + return nil + } + + out := new(Currency) + u.DeepCopyInto(out) + + return out +} + +// GobEncode implements the gob.GobEncoder interface. +func (u Currency) GobEncode() ([]byte, error) { + return u.MarshalText() +} + +// GobDecode implements the gob.GobDecoder interface. +func (u *Currency) GobDecode(data []byte) error { + return u.UnmarshalText(data) +} + +// MarshalBinary implements the encoding.[encoding.BinaryMarshaler] interface. +func (u Currency) MarshalBinary() ([]byte, error) { + return u.MarshalText() +} + +// UnmarshalBinary implements the encoding.[encoding.BinaryUnmarshaler] interface. +func (u *Currency) UnmarshalBinary(data []byte) error { + return u.UnmarshalText(data) +} diff --git a/vendor/github.com/go-openapi/strfmt/date.go b/vendor/github.com/go-openapi/strfmt/date.go index 59ee1f11216..6d0e8a01ac8 100644 --- a/vendor/github.com/go-openapi/strfmt/date.go +++ b/vendor/github.com/go-openapi/strfmt/date.go @@ -10,11 +10,6 @@ import ( "time" ) -func init() { //nolint:gochecknoinits // registers date format in the default registry - d := Date{} - Default.Add("date", &d, IsDate) -} - // IsDate returns true when the string is a valid date. func IsDate(str string) bool { _, err := time.Parse(RFC3339FullDate, str) diff --git a/vendor/github.com/go-openapi/strfmt/default.go b/vendor/github.com/go-openapi/strfmt/default.go index 725cc0e1a60..bcc57e6fad3 100644 --- a/vendor/github.com/go-openapi/strfmt/default.go +++ b/vendor/github.com/go-openapi/strfmt/default.go @@ -32,22 +32,22 @@ const ( ) const ( - // UUIDPattern Regex for [UUID] that allows uppercase + // UUIDPattern Regex for [UUID] that allows uppercase. // // Deprecated: [strfmt] no longer uses regular expressions to validate UUIDs. UUIDPattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$)|(^[0-9a-f]{32}$)` - // UUID3Pattern Regex for [UUID3] that allows uppercase + // UUID3Pattern Regex for [UUID3] that allows uppercase. // // Deprecated: [strfmt] no longer uses regular expressions to validate UUIDs. UUID3Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$)|(^[0-9a-f]{12}3[0-9a-f]{3}?[0-9a-f]{16}$)` - // UUID4Pattern Regex for [UUID4] that allows uppercase + // UUID4Pattern Regex for [UUID4] that allows uppercase. // // Deprecated: [strfmt] no longer uses regular expressions to validate UUIDs. UUID4Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$)|(^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$)` - // UUID5Pattern Regex for [UUID]5 that allows uppercase + // UUID5Pattern Regex for [UUID]5 that allows uppercase. // // Deprecated: [strfmt] no longer uses regular expressions to validate UUIDs. UUID5Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$)|(^[0-9a-f]{12}5[0-9a-f]{3}[89ab][0-9a-f]{15}$)` @@ -88,8 +88,8 @@ var ( // IsHostname returns true when the string is a valid hostname. // -// It follows the rules detailed at https://url.spec.whatwg.org/#concept-host-parser -// and implemented by most modern web browsers. +// It follows the rules detailed at https://url.spec.whatwg.org/#concept-host-parser and implemented by most modern web +// browsers. // // It supports IDNA rules regarding internationalized names with unicode. // @@ -142,13 +142,13 @@ func IsHostname(str string) bool { return true } -// domainEndsAsNumber determines if a domain name ends with a decimal, octal or hex digit, -// accounting for a possible trailing dot (the last part being empty in that case). +// domainEndsAsNumber determines if a domain name ends with a decimal, octal or hex digit, accounting for a possible +// trailing dot (the last part being empty in that case). // // It returns the last non-trailing dot part and if that part consists only of (dec/hex/oct) digits. func domainEndsAsNumber(parts []string) (lastPart string, lastIndex int, ok bool) { - // NOTE: using ParseUint(x, 0, 32) is not an option, as the IPv4 format supported why WHATWG - // doesn't support notations such as "0b1001" (binary digits) or "0o666" (alternate notation for octal digits). + // NOTE: using ParseUint(x, 0, 32) is not an option, as the IPv4 format supported why WHATWG doesn't support notations + // such as "0b1001" (binary digits) or "0o666" (alternate notation for octal digits). lastIndex = len(parts) - 1 lastPart = parts[lastIndex] if len(lastPart) == 0 { @@ -233,8 +233,9 @@ func isValidIPv6(str string) bool { // "0o07.2.3.4" func isValidIPv4(parts []string) bool { // NOTE: using ParseUint(x, 0, 32) is not an option, even though it would simplify this code a lot. - // The IPv4 format supported why WHATWG doesn't support notations such as "0b1001" (binary digits) - // or "0o666" (alternate notation for octal digits). + // + // The IPv4 format supported why WHATWG doesn't support notations such as "0b1001" (binary digits) or "0o666" + // (alternate notation for octal digits). const ( maxPartsInIPv4 = 4 maxDigitsInPart = 11 // max size of a 4-bytes hex or octal digit @@ -376,101 +377,22 @@ func IsEmail(str string) bool { return e == nil && addr.Address != "" } -func init() { //nolint:gochecknoinits // registers all default string formats in the registry - // register formats in the default registry: - // - byte - // - creditcard - // - email - // - hexcolor - // - hostname - // - ipv4 - // - ipv6 - // - cidr - // - isbn - // - isbn10 - // - isbn13 - // - mac - // - password - // - rgbcolor - // - ssn - // - uri - // - uuid - // - uuid3 - // - uuid4 - // - uuid5 - // - uuid7 - u := URI("") - Default.Add("uri", &u, isRequestURI) - - eml := Email("") - Default.Add("email", &eml, IsEmail) - - hn := Hostname("") - Default.Add("hostname", &hn, IsHostname) - - ip4 := IPv4("") - Default.Add("ipv4", &ip4, isIPv4) - - ip6 := IPv6("") - Default.Add("ipv6", &ip6, isIPv6) - - cidr := CIDR("") - Default.Add("cidr", &cidr, isCIDR) - - mac := MAC("") - Default.Add("mac", &mac, isMAC) - - uid := UUID("") - Default.Add("uuid", &uid, IsUUID) - - uid3 := UUID3("") - Default.Add("uuid3", &uid3, IsUUID3) - - uid4 := UUID4("") - Default.Add("uuid4", &uid4, IsUUID4) - - uid5 := UUID5("") - Default.Add("uuid5", &uid5, IsUUID5) - - uid7 := UUID7("") - Default.Add("uuid7", &uid7, IsUUID7) - - isbn := ISBN("") - Default.Add("isbn", &isbn, func(str string) bool { return isISBN10(str) || isISBN13(str) }) - - isbn10 := ISBN10("") - Default.Add("isbn10", &isbn10, isISBN10) - - isbn13 := ISBN13("") - Default.Add("isbn13", &isbn13, isISBN13) - - cc := CreditCard("") - Default.Add("creditcard", &cc, isCreditCard) - - ssn := SSN("") - Default.Add("ssn", &ssn, isSSN) - - hc := HexColor("") - Default.Add("hexcolor", &hc, isHexcolor) - - rc := RGBColor("") - Default.Add("rgbcolor", &rc, isRGBcolor) - - b64 := Base64([]byte(nil)) - Default.Add("byte", &b64, isBase64) - - pw := Password("") - Default.Add("password", &pw, func(_ string) bool { return true }) -} +// base64Encoding is the canonical alphabet for the [Base64] format. +// +// OpenAPI `format: byte` means standard base64 (RFC 4648 §4, the `+/` alphabet), not base64url. +// This is the single seam every [Base64] path encodes and decodes through, so a future URL-safe variant only swaps the +// encoding here. +// See go-openapi/strfmt#87. +var base64Encoding = base64.StdEncoding //nolint:gochecknoglobals // canonical alphabet seam for the Base64 format -// Base64 represents a base64 encoded string, using URLEncoding alphabet. +// Base64 represents a base64 encoded string, using the standard RFC 4648 alphabet. // // swagger:strfmt byte. type Base64 []byte // MarshalText turns this instance into text. func (b Base64) MarshalText() ([]byte, error) { - enc := base64.URLEncoding + enc := base64Encoding src := []byte(b) buf := make([]byte, enc.EncodedLen(len(src))) enc.Encode(buf, src) @@ -479,7 +401,7 @@ func (b Base64) MarshalText() ([]byte, error) { // UnmarshalText hydrates this instance from text. func (b *Base64) UnmarshalText(data []byte) error { // validation is performed later on - enc := base64.URLEncoding + enc := base64Encoding dbuf := make([]byte, enc.DecodedLen(len(data))) n, err := enc.Decode(dbuf, data) @@ -495,14 +417,14 @@ func (b *Base64) UnmarshalText(data []byte) error { // validation is performed l func (b *Base64) Scan(raw any) error { switch v := raw.(type) { case []byte: - dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(v))) - n, err := base64.StdEncoding.Decode(dbuf, v) + dbuf := make([]byte, base64Encoding.DecodedLen(len(v))) + n, err := base64Encoding.Decode(dbuf, v) if err != nil { return err } *b = dbuf[:n] case string: - vv, err := base64.StdEncoding.DecodeString(v) + vv, err := base64Encoding.DecodeString(v) if err != nil { return err } @@ -520,7 +442,7 @@ func (b Base64) Value() (driver.Value, error) { } func (b Base64) String() string { - return base64.StdEncoding.EncodeToString([]byte(b)) + return base64Encoding.EncodeToString([]byte(b)) } // MarshalJSON returns the Base64 as JSON. @@ -534,7 +456,7 @@ func (b *Base64) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &b64str); err != nil { return err } - vb, err := base64.StdEncoding.DecodeString(b64str) + vb, err := base64Encoding.DecodeString(b64str) if err != nil { return err } @@ -1040,7 +962,7 @@ func (u *MAC) DeepCopy() *MAC { return out } -// UUID represents a [uuid] string format +// UUID represents a [uuid] string format. // // swagger:strfmt uuid. type UUID string @@ -1905,6 +1827,7 @@ func (r *RGBColor) DeepCopy() *RGBColor { } // Password represents a password. +// // This has no validations and is mainly used as a marker for UI components. // // swagger:strfmt password. @@ -1978,11 +1901,10 @@ func (r *Password) DeepCopy() *Password { } func isRequestURI(rawurl string) bool { - // url.ParseRequestURI assumes the input contains no "#fragment" - // (RFC 3986 §3.5). A URI with a fragment and an empty path, such as - // "https://host#@frag", is therefore misread as userinfo and rejected - // as "invalid userinfo". Strip the fragment first so the absolute - // request URI validates, matching url.Parse's RFC 3986 handling. + // url.ParseRequestURI assumes the input contains no "#fragment" (RFC 3986 §3.5). + // A URI with a fragment and an empty path, such as "https://host#@frag", is therefore misread as userinfo and rejected + // as "invalid userinfo". + // Strip the fragment first so the absolute request URI validates, matching url.Parse's RFC 3986 handling. if i := strings.IndexByte(rawurl, '#'); i >= 0 { rawurl = rawurl[:i] } @@ -2009,19 +1931,20 @@ func isCIDR(str string) bool { } // isMAC checks if a string is valid MAC address. +// // Possible MAC formats: -// 01:23:45:67:89:ab -// 01:23:45:67:89:ab:cd:ef -// 01-23-45-67-89-ab -// 01-23-45-67-89-ab-cd-ef -// 0123.4567.89ab -// 0123.4567.89ab.cdef. +// - 01:23:45:67:89:ab +// - 01:23:45:67:89:ab:cd:ef +// - 01-23-45-67-89-ab +// - 01-23-45-67-89-ab-cd-ef +// - 0123.4567.89ab 0123.4567.89ab.cdef func isMAC(str string) bool { _, err := net.ParseMAC(str) return err == nil } // isISBN checks if the string is an ISBN (version 10 or 13). +// // If version value is not equal to 10 or 13, it will be checks both variants. func isISBN(str string, version int) bool { sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "") @@ -2120,7 +2043,7 @@ func isRGBcolor(str string) bool { // isBase64 checks if a string is base64 encoded. func isBase64(str string) bool { - _, err := base64.StdEncoding.DecodeString(str) + _, err := base64Encoding.DecodeString(str) return err == nil } diff --git a/vendor/github.com/go-openapi/strfmt/duration.go b/vendor/github.com/go-openapi/strfmt/duration.go index f2ab7ff8348..fc4de0d14c2 100644 --- a/vendor/github.com/go-openapi/strfmt/duration.go +++ b/vendor/github.com/go-openapi/strfmt/duration.go @@ -12,11 +12,6 @@ import ( "unicode" ) -func init() { //nolint:gochecknoinits // registers duration format in the default registry - d := Duration(0) - Default.Add("duration", &d, IsDuration) -} - const ( hoursInDay = 24 daysInWeek = 7 @@ -174,6 +169,9 @@ func ParseDuration(s string) (time.Duration, error) { scale float64 = 1 // value = v + f/scale ) s = strings.TrimLeftFunc(s, unicode.IsSpace) + if s == "" { + break + } // The next character must be 0-9.] if s[0] != '.' && ('0' > s[0] || s[0] > '9') { diff --git a/vendor/github.com/go-openapi/strfmt/duration_iso8601.go b/vendor/github.com/go-openapi/strfmt/duration_iso8601.go new file mode 100644 index 00000000000..9fded035ae2 --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/duration_iso8601.go @@ -0,0 +1,583 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package strfmt + +import ( + "database/sql/driver" + "encoding/json" + "fmt" + "math" + "strconv" + "strings" + "time" +) + +// ISO 8601 duration unit lengths, expressed in nanoseconds. +// +// Calendar units are collapsed to fixed lengths (a year is 365 days, a month is 30 days): a [time.Duration] cannot +// carry calendar context, so this conversion is inherently lossy and not calendar-correct. +// It matches the historical behaviour of ISO duration libraries in this space. +const ( + isoSecond = uint64(time.Second) + isoMinute = uint64(time.Minute) + isoHour = uint64(time.Hour) + isoDay = 24 * isoHour + isoWeek = 7 * isoDay + isoMonth = 30 * isoDay + isoYear = 365 * isoDay + + // maxDurationMagnitude is 1<<63: the magnitude of [math.MinInt64], and one more than [math.MaxInt64]. + // + // A parsed magnitude may reach exactly this value only for a negative duration (yielding [math.MinInt64]). + maxDurationMagnitude = uint64(1) << 63 +) + +// Base-10 parsing / formatting constants (decimalBase lives in default.go). +const ( + // decimalAccMax bounds a uint64 accumulator so that acc*decimalBase + 9 cannot overflow. + decimalAccMax = (math.MaxUint64 - (decimalBase - 1)) / decimalBase + // nanoDigits is the number of fractional digits in one whole second (nanosecond precision). + nanoDigits = 9 +) + +// ISODuration is an ISO 8601 / RFC 3339 duration (e.g. "P1Y2M3DT4H5M6S", "P2W"). +// +// The type parameter P selects the parsing policy at compile time (see [ISODurationPolicy]). +// Every instantiation is a distinct type that round-trips through JSON, text, SQL and BSON. +// Use the [DurationISO8601] alias for the strict, spec-compliant default. +// +// Like [time.Duration], it stores a nanosecond count; the largest representable duration is approximately 290 years. +// Calendar units are collapsed to fixed lengths (year = 365 days, month = 30 days), which is lossy by nature. +// +// This generic type carries no swagger:strfmt annotation: go-swagger binds a concrete format name to the +// [DurationISO8601] alias, not to a generic declaration. +type ISODuration[P ISODurationPolicy] time.Duration + +// DurationISO8601 is the strict, spec-compliant ISO 8601 duration: the JSON Schema draft 2020 "duration" format +// (RFC 3339 Appendix A). +// +// It binds to the explicit, unambiguous "duration-iso8601" handle. Plain "duration" is a context-dependent +// default resolved by the registry ([Default] → human, [JSONSchema2020Registry] → ISO), not by this static type. +// +// swagger:strfmt duration-iso8601. +type DurationISO8601 = ISODuration[DurationStrict] + +// ParseISO8601Duration parses an ISO 8601 / RFC 3339 duration string. +// +// With no options it enforces the strict RFC 3339 Appendix A grammar. +// Options relax individual rules for programmatic callers. +func ParseISO8601Duration(s string, opts ...ISODurationOption) (time.Duration, error) { + cfg := DurationStrict{}.isoDurationConfig() + for _, o := range opts { + o(&cfg) + } + return parseISO8601Duration(s, cfg) +} + +// --- Format / encoding methods --- + +// String renders the duration in canonical ISO 8601 form. +// +// Unlike [ISODuration.MarshalText], String is a best-effort display form: it always renders the true value (lossless), +// even under a strict policy that could not serialize it (e.g. a sign or sub-second precision). +func (d ISODuration[P]) String() string { return isoFormat(time.Duration(d)) } + +// MarshalText implements [encoding.TextMarshaler], applying the policy P: a strict policy errors on a value it cannot +// represent (see [isoEmit]). +func (d ISODuration[P]) MarshalText() ([]byte, error) { + var p P + s, err := isoEmit(time.Duration(d), p.isoDurationConfig()) + if err != nil { + return nil, err + } + return []byte(s), nil +} + +// UnmarshalText implements [encoding.TextUnmarshaler], applying the policy P. +func (d *ISODuration[P]) UnmarshalText(text []byte) error { + var p P + dd, err := parseISO8601Duration(string(text), p.isoDurationConfig()) + if err != nil { + return err + } + *d = ISODuration[P](dd) + return nil +} + +// MarshalJSON returns the duration as a JSON string, applying the policy P. +func (d ISODuration[P]) MarshalJSON() ([]byte, error) { + var p P + s, err := isoEmit(time.Duration(d), p.isoDurationConfig()) + if err != nil { + return nil, err + } + return json.Marshal(s) +} + +// UnmarshalJSON sets the duration from a JSON string, applying the policy P. +func (d *ISODuration[P]) UnmarshalJSON(data []byte) error { + if string(data) == jsonNull { + return nil + } + var str string + if err := json.Unmarshal(data, &str); err != nil { + return err + } + var p P + dd, err := parseISO8601Duration(str, p.isoDurationConfig()) + if err != nil { + return err + } + *d = ISODuration[P](dd) + return nil +} + +// Scan reads a duration (nanoseconds) from a database driver value. +func (d *ISODuration[P]) Scan(raw any) error { + switch v := raw.(type) { + case int64: + *d = ISODuration[P](v) + case float64: + *d = ISODuration[P](int64(v)) + case nil: + *d = ISODuration[P](0) + default: + return fmt.Errorf("cannot sql.Scan() strfmt.ISODuration from: %#v: %w", v, ErrFormat) + } + return nil +} + +// Value writes the duration as a nanosecond count. +func (d ISODuration[P]) Value() (driver.Value, error) { + return driver.Value(int64(d)), nil +} + +// Equal reports whether two durations are equal. +func (d ISODuration[P]) Equal(other ISODuration[P]) bool { return d == other } + +// DeepCopyInto copies the receiver into out. +func (d *ISODuration[P]) DeepCopyInto(out *ISODuration[P]) { *out = *d } + +// DeepCopy copies the receiver into a new value. +func (d *ISODuration[P]) DeepCopy() *ISODuration[P] { + if d == nil { + return nil + } + out := new(ISODuration[P]) + d.DeepCopyInto(out) + return out +} + +// IsDurationISO8601 returns true if the string is a valid strict ISO 8601 duration. +func IsDurationISO8601(s string) bool { + _, err := parseISO8601Duration(s, DurationStrict{}.isoDurationConfig()) + return err == nil +} + +func isoDurationError(input, msg string) error { + return fmt.Errorf("invalid ISO 8601 duration %q: %s: %w", input, msg, ErrFormat) +} + +// section positions used to enforce component ordering (strictly increasing). +// +//nolint:gochecknoglobals,mnd // immutable ordinal lookup tables; the integers are sequence positions, not magic constants +var ( + isoDatePos = map[byte]int{'Y': 1, 'M': 2, 'W': 3, 'D': 4} + isoTimePos = map[byte]int{'H': 1, 'M': 2, 'S': 3} +) + +// isoDateSlot maps the year/month/day designators to contiguous slots for the strict anchoring (gap) check. +// +// 'W' is deliberately excluded: in strict mode it is exclusive, so it never coexists with Y/M/D. +func isoDateSlot(des byte) (int, bool) { + switch des { + case 'Y': + return 0, true + case 'M': + return 1, true + case 'D': + return 2, true //nolint:mnd // contiguous slot index (Y=0, M=1, D=2), not a magic constant + default: + return 0, false + } +} + +//nolint:gocognit,gocyclo,cyclop // a single-pass grammar scanner; the branches mirror the ABNF. +func parseISO8601Duration(input string, cfg isoDurationConfig) (time.Duration, error) { + s := input + if cfg.allowSpace { + s = strings.TrimSpace(s) + } + + neg := false + if cfg.allowSign && s != "" && (s[0] == '+' || s[0] == '-') { + neg = s[0] == '-' + s = s[1:] + } + + if s == "" || s[0] != 'P' { + return 0, isoDurationError(input, `must start with "P"`) + } + s = s[1:] + if s == "" { + return 0, isoDurationError(input, "no components after P") + } + + var ( + total uint64 + inTime bool + seenAny bool + weekSeen bool + fractionUsed bool + lastDatePos int + lastTimePos int + datePresent [3]bool // Y, M, D — for the anchoring (gap) check + timePresent [3]bool // H, M, S + ) + + for s != "" { + c := s[0] + + if c == 'T' { + if inTime { + return 0, isoDurationError(input, `duplicate "T" separator`) + } + if weekSeen && !cfg.weekCombinable { + return 0, isoDurationError(input, `"W" cannot be combined with other components`) + } + inTime = true + s = s[1:] + if s == "" { + return 0, isoDurationError(input, `no components after "T"`) + } + continue + } + + // A fraction, if any, must be on the least significant component: nothing may follow it. + if fractionUsed { + return 0, isoDurationError(input, "a fraction is only allowed on the least significant component") + } + + // Scan the integer part (ASCII digits only). + i := 0 + for i < len(s) && s[i] >= '0' && s[i] <= '9' { + i++ + } + if i == 0 { + return 0, isoDurationError(input, fmt.Sprintf("expected a digit, got %q", s[0])) + } + intPart := s[:i] + + // Optional decimal fraction. + var fracPart string + hasFrac := false + if i < len(s) && (s[i] == '.' || s[i] == ',') { + if !cfg.allowFraction { + return 0, isoDurationError(input, "decimal fraction is not allowed") + } + hasFrac = true + j := i + 1 + for j < len(s) && s[j] >= '0' && s[j] <= '9' { + j++ + } + fracPart = s[i+1 : j] + i = j + } + + if i >= len(s) { + return 0, isoDurationError(input, "value without a unit designator") + } + des := s[i] + s = s[i+1:] + + unit, err := isoResolveUnit(input, des, inTime, cfg, + &lastDatePos, &lastTimePos, &weekSeen, seenAny, &datePresent, &timePresent) + if err != nil { + return 0, err + } + seenAny = true + if hasFrac { + fractionUsed = true + } + + val, err := isoScaleValue(input, intPart, fracPart, unit) + if err != nil { + return 0, err + } + + // Accumulate with the stdlib overflow discipline: the magnitude may reach 1<<63 only for a negative duration. + if total > maxDurationMagnitude-val { + return 0, isoDurationError(input, "value out of range") + } + total += val + } + + if inTime && !timePresent[0] && !timePresent[1] && !timePresent[2] { + return 0, isoDurationError(input, `no components after "T"`) + } + if !seenAny { + return 0, isoDurationError(input, "no components") + } + + // Strict anchoring: the present Y/M/D and H/M/S components must each form a contiguous run (e.g. P1Y2D and PT1H2S are + // rejected). + if !cfg.relaxAnchoring { + if err := isoCheckContiguous(input, datePresent, "date"); err != nil { + return 0, err + } + if err := isoCheckContiguous(input, timePresent, "time"); err != nil { + return 0, err + } + } + + if total > maxDurationMagnitude-1 { + if neg && total == maxDurationMagnitude { + return math.MinInt64, nil + } + return 0, isoDurationError(input, "value out of range") + } + if neg { + return -time.Duration(total), nil + } + return time.Duration(total), nil +} + +// isoResolveUnit validates a designator in context (section, ordering, week +// exclusivity) and returns its unit length in nanoseconds. +func isoResolveUnit( + input string, des byte, inTime bool, cfg isoDurationConfig, + lastDatePos, lastTimePos *int, weekSeen *bool, seenAny bool, + datePresent, timePresent *[3]bool, +) (uint64, error) { + if inTime { + pos, ok := isoTimePos[des] + if !ok { + return 0, isoDurationError(input, fmt.Sprintf("%q is not a valid time-section designator", des)) + } + if pos <= *lastTimePos { + return 0, isoDurationError(input, fmt.Sprintf("designator %q is out of order", des)) + } + *lastTimePos = pos + timePresent[pos-1] = true + switch des { + case 'H': + return isoHour, nil + case 'M': + return isoMinute, nil + default: // 'S' + return isoSecond, nil + } + } + + pos, ok := isoDatePos[des] + if !ok { + return 0, isoDurationError(input, fmt.Sprintf("%q is not a valid date-section designator", des)) + } + if pos <= *lastDatePos { + return 0, isoDurationError(input, fmt.Sprintf("designator %q is out of order", des)) + } + + if des == 'W' { + if !cfg.weekCombinable && seenAny { + return 0, isoDurationError(input, `"W" cannot be combined with other components`) + } + *lastDatePos = pos + *weekSeen = true + return isoWeek, nil + } + + if *weekSeen && !cfg.weekCombinable { + return 0, isoDurationError(input, `"W" cannot be combined with other components`) + } + *lastDatePos = pos + if slot, ok := isoDateSlot(des); ok { + datePresent[slot] = true + } + switch des { + case 'Y': + return isoYear, nil + case 'M': + return isoMonth, nil + default: // 'D' + return isoDay, nil + } +} + +// isoCheckContiguous rejects gaps in a section's component chain. +func isoCheckContiguous(input string, present [3]bool, section string) error { + first, last := -1, -1 + for i, p := range present { + if p { + if first < 0 { + first = i + } + last = i + } + } + if first < 0 { + return nil + } + for i := first; i <= last; i++ { + if !present[i] { + return isoDurationError(input, "non-contiguous "+section+" components (a gap in the unit chain)") + } + } + return nil +} + +// isoScaleValue converts an integer (and optional fractional) component to nanoseconds, checking every overflow +// boundary. +func isoScaleValue(input, intPart, fracPart string, unit uint64) (uint64, error) { + v, ok := isoParseUint(intPart) + if !ok { + return 0, isoDurationError(input, "value out of range") + } + // Bound v*unit to the duration magnitude *before* multiplying, so the later fractional addition cannot wrap a uint64. + if v > maxDurationMagnitude/unit { + return 0, isoDurationError(input, "value out of range") + } + val := v * unit + + if fracPart != "" { + f, scale := isoParseFraction(fracPart) + if f > 0 { + // float64 is accurate enough for a sub-unit fraction (matches the standard library technique); the magnitude stays + // below the uint64 ceiling because val <= 1<<63 and the addend is < unit. + val += uint64(float64(f) * (float64(unit) / float64(scale))) + if val > maxDurationMagnitude { + return 0, isoDurationError(input, "value out of range") + } + } + } + + return val, nil +} + +// isoParseUint parses digits into a uint64, reporting overflow. +func isoParseUint(s string) (uint64, bool) { + var v uint64 + for i := range len(s) { + if v > decimalAccMax { + return 0, false + } + v = v*decimalBase + uint64(s[i]-'0') + } + + return v, true +} + +// isoParseFraction parses fractional digits into (value, scale=10^len), capping precision at 18 digits so the value +// stays exact in the subsequent float maths. +func isoParseFraction(s string) (uint64, uint64) { + const maxFracDigits = 18 + if len(s) > maxFracDigits { + s = s[:maxFracDigits] + } + var f, scale uint64 = 0, 1 + for i := range len(s) { + f = f*decimalBase + uint64(s[i]-'0') + scale *= decimalBase + } + + return f, scale +} + +// isoFormat renders a duration in canonical ISO 8601 form (P[n]DT[n]H[n]M[n]S). +// +// Intermediate zero time components are emitted when needed to keep the output contiguous (e.g. 1h5s → "PT1H0M5S"), +// so the structure is always syntactically valid ISO 8601. Years, months and weeks are not reconstructed (a +// [time.Duration] does not carry calendar context); a fractional second is emitted losslessly, and a negative duration +// is prefixed with "-". +func isoFormat(d time.Duration) string { + if d == 0 { + return "PT0S" + } + neg := d < 0 + var u uint64 + if neg { + u = uint64(-d) + } else { + u = uint64(d) + } + + days := u / isoDay + u %= isoDay + hours := u / isoHour + u %= isoHour + minutes := u / isoMinute + u %= isoMinute + seconds := u / isoSecond + frac := u % isoSecond + + var b strings.Builder + if neg { + b.WriteByte('-') + } + + b.WriteByte('P') + if days > 0 { + b.WriteString(strconv.FormatUint(days, decimalBase)) + b.WriteByte('D') + } + isoWriteTimeSection(&b, hours, minutes, seconds, frac) + + return b.String() +} + +// isoWriteTimeSection appends the "T…" part of a canonical ISO 8601 duration, emitting a zero-minute filler when it +// must bridge hours and seconds so the output stays contiguous (e.g. 1h5s → "T1H0M5S"). +func isoWriteTimeSection(b *strings.Builder, hours, minutes, seconds, frac uint64) { + hasH := hours > 0 + hasM := minutes > 0 + hasS := seconds > 0 || frac > 0 + if !hasH && !hasM && !hasS { + return + } + + b.WriteByte('T') + if hasH { + b.WriteString(strconv.FormatUint(hours, decimalBase)) + b.WriteByte('H') + } + + // Emit minutes if non-zero, or as a zero filler bridging hours and seconds. + if hasM || (hasH && hasS) { + b.WriteString(strconv.FormatUint(minutes, decimalBase)) + b.WriteByte('M') + } + + if hasS { + b.WriteString(strconv.FormatUint(seconds, decimalBase)) + if frac > 0 { + b.WriteByte('.') + b.WriteString(isoFormatFraction(frac)) + } + b.WriteByte('S') + } +} + +// isoEmit renders d under the given policy. +// +// A policy that forbids a feature the value requires (a sign, or sub-second precision) cannot represent it, and returns +// an error rather than emitting output a matching parser would reject. +func isoEmit(d time.Duration, cfg isoDurationConfig) (string, error) { + if !cfg.allowSign && d < 0 { + return "", fmt.Errorf("a negative duration cannot be represented under this ISO 8601 policy: %w", ErrFormat) + } + + if !cfg.allowFraction && d%time.Second != 0 { + return "", fmt.Errorf("sub-second precision cannot be represented under this ISO 8601 policy: %w", ErrFormat) + } + + return isoFormat(d), nil +} + +// isoFormatFraction renders a nanosecond remainder (0..1e9) as its 9-digit fractional part with trailing zeros trimmed. +func isoFormatFraction(frac uint64) string { + s := strconv.FormatUint(frac, decimalBase) + if len(s) < nanoDigits { + s = strings.Repeat("0", nanoDigits-len(s)) + s + } + return strings.TrimRight(s, "0") +} diff --git a/vendor/github.com/go-openapi/strfmt/duration_iso8601_options.go b/vendor/github.com/go-openapi/strfmt/duration_iso8601_options.go new file mode 100644 index 00000000000..4f90a5c5a5a --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/duration_iso8601_options.go @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package strfmt + +// ISODurationPolicy is a compile-time policy selecting the parsing behaviour of an [ISODuration]. +// +// It is a phantom type parameter: a zero-size value whose single method yields the parser configuration. +// See [DurationStrict] and [DurationLenient]. +type ISODurationPolicy interface { + isoDurationConfig() isoDurationConfig +} + +// isoDurationConfig holds the leniency knobs of the ISO 8601 duration parser. +// +// The zero value is the strict RFC 3339 Appendix A grammar (the JSON Schema "duration" format): every field false. +type isoDurationConfig struct { + allowFraction bool // accept a decimal fraction on the least significant component + allowSign bool // accept a leading '+' or '-' + allowSpace bool // tolerate surrounding whitespace + weekCombinable bool // allow the 'W' designator to combine with other components + relaxAnchoring bool // allow gaps in the component chain (e.g. P1Y2D, PT1H2S) +} + +// DurationStrict is the strict RFC 3339 Appendix A policy. +// +// This is the grammar that the JSON Schema "duration" format is defined against (draft 2020): +// no fraction, no sign, no whitespace, strict ordering and anchoring, and an exclusive 'W' designator. +type DurationStrict struct{} + +func (DurationStrict) isoDurationConfig() isoDurationConfig { return isoDurationConfig{} } + +// DurationLenient relaxes every strictness knob. +// +// It accepts a decimal fraction on the least significant component, a leading sign, surrounding whitespace, +// component chains with gaps (e.g. P1Y2D), and a 'W' designator combined with other components. +// +// It remains ordered (P2D1Y is still rejected). +type DurationLenient struct{} + +func (DurationLenient) isoDurationConfig() isoDurationConfig { + return isoDurationConfig{ + allowFraction: true, + allowSign: true, + allowSpace: true, + weekCombinable: true, + relaxAnchoring: true, + } +} + +// ISODurationOption relaxes the strict parser on the explicit [ParseISO8601Duration] path, for programmatic callers. +// +// It has no effect on the registry / struct-field decode path, which is governed by the type's policy. +type ISODurationOption func(*isoDurationConfig) + +// WithISOFractions accepts a decimal fraction on the least significant component. +func WithISOFractions() ISODurationOption { + return func(c *isoDurationConfig) { c.allowFraction = true } +} + +// WithISOSign accepts a leading '+' or '-'. +func WithISOSign() ISODurationOption { return func(c *isoDurationConfig) { c.allowSign = true } } + +// WithISOSpace tolerates surrounding whitespace. +func WithISOSpace() ISODurationOption { return func(c *isoDurationConfig) { c.allowSpace = true } } + +// WithISOWeekCombinable allows the 'W' designator to combine with other components. +func WithISOWeekCombinable() ISODurationOption { + return func(c *isoDurationConfig) { c.weekCombinable = true } +} + +// WithISORelaxedAnchoring allows gaps in the component chain (e.g. P1Y2D, PT1H2S). +func WithISORelaxedAnchoring() ISODurationOption { + return func(c *isoDurationConfig) { c.relaxAnchoring = true } +} + +// WithISOLenient relaxes every strictness knob (see [DurationLenient]). +func WithISOLenient() ISODurationOption { + return func(c *isoDurationConfig) { *c = DurationLenient{}.isoDurationConfig() } +} diff --git a/vendor/github.com/go-openapi/strfmt/format.go b/vendor/github.com/go-openapi/strfmt/format.go index e494dd7b83d..09c37542546 100644 --- a/vendor/github.com/go-openapi/strfmt/format.go +++ b/vendor/github.com/go-openapi/strfmt/format.go @@ -10,15 +10,11 @@ import ( "slices" "strings" "sync" - "time" "github.com/go-openapi/errors" "github.com/go-viper/mapstructure/v2" ) -// Default is the default formats registry. -var Default = NewSeededFormats(nil, nil) //nolint:gochecknoglobals // package-level default registry, by design - // Validator represents a validator for a string format. type Validator func(string) bool @@ -48,11 +44,28 @@ type knownFormat struct { } // NameNormalizer is a function that normalizes a format name. +// +// The default duration format corresponds to "duration-human". type NameNormalizer func(string) string +var dashReplacer = strings.NewReplacer("-", "") //nolint:gochecknoglobals // it's okay to use a global private replacer + // DefaultNameNormalizer removes all dashes. func DefaultNameNormalizer(name string) string { - return strings.ReplaceAll(name, "-", "") + if name == "duration" { + name = "duration-human" + } + + return dashReplacer.Replace(name) +} + +// JSONSchema2020Normalizer is like [NameNormalizer] but adopts "duration-iso8601" as the default "duration" format. +func JSONSchema2020Normalizer(name string) string { + if name == "duration" { + name = "duration-iso8601" + } + + return dashReplacer.Replace(name) } type defaultFormats struct { @@ -63,6 +76,11 @@ type defaultFormats struct { } // MapStructureHookFunc is a decode hook function for mapstructure. +// +// A registered format is decoded by delegating to the destination type's own +// [encoding.TextUnmarshaler], so the mapstructure path is identical to the JSON +// and [defaultFormats.Parse] paths. New formats are picked up automatically as +// soon as they are registered — no per-type wiring here. func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { //nolint:ireturn // returns interface required by mapstructure return func(from reflect.Type, to reflect.Type, obj any) (any, error) { if from.Kind() != reflect.String { @@ -74,85 +92,25 @@ func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { // } for _, v := range f.data { - tpe, _ := f.GetType(v.Name) - if to == tpe { - return decodeFormatFromString(v.Name, data) + if to != v.Type { + continue } - } - return data, nil - } -} -// decodeFormatFromString decodes a string into the appropriate format type by name. -func decodeFormatFromString(name, data string) (any, error) { //nolint:gocyclo,cyclop // flat switch over format names, no real complexity - switch name { - case "date": - d, err := time.ParseInLocation(RFC3339FullDate, data, DefaultTimeLocation) - if err != nil { - return nil, err - } - return Date(d), nil - case "datetime": - if len(data) == 0 { - return nil, fmt.Errorf("empty string is an invalid datetime format: %w", ErrFormat) - } - return ParseDateTime(data) - case "duration": - dur, err := ParseDuration(data) - if err != nil { - return nil, err - } - return Duration(dur), nil - case "uri": - return URI(data), nil - case "email": - return Email(data), nil - case "uuid": - return UUID(data), nil - case "uuid3": - return UUID3(data), nil - case "uuid4": - return UUID4(data), nil - case "uuid5": - return UUID5(data), nil - case "uuid7": - return UUID7(data), nil - case "hostname": - return Hostname(data), nil - case "ipv4": - return IPv4(data), nil - case "ipv6": - return IPv6(data), nil - case "cidr": - return CIDR(data), nil - case "mac": - return MAC(data), nil - case "isbn": - return ISBN(data), nil - case "isbn10": - return ISBN10(data), nil - case "isbn13": - return ISBN13(data), nil - case "creditcard": - return CreditCard(data), nil - case "ssn": - return SSN(data), nil - case "hexcolor": - return HexColor(data), nil - case "rgbcolor": - return RGBColor(data), nil - case "byte": - return Base64(data), nil - case "password": - return Password(data), nil - case "ulid": - ulid, err := ParseULID(data) - if err != nil { - return nil, err + // reflect.New yields an addressable *T so the (pointer-receiver) + // TextUnmarshaler can hydrate it; we hand back the dereferenced + // value to match the destination field's (value) type. + nw := reflect.New(v.Type).Interface() + dec, isText := nw.(encoding.TextUnmarshaler) + if !isText { + return nil, errors.InvalidTypeName(v.Name) + } + if err := dec.UnmarshalText([]byte(data)); err != nil { + return nil, err + } + return reflect.ValueOf(nw).Elem().Interface(), nil } - return ulid, nil - default: - return nil, errors.InvalidTypeName(name) + + return data, nil } } diff --git a/vendor/github.com/go-openapi/strfmt/internal/countries/countries.go b/vendor/github.com/go-openapi/strfmt/internal/countries/countries.go new file mode 100644 index 00000000000..7f13c0cfe35 --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/internal/countries/countries.go @@ -0,0 +1,512 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Code generated by gen.go; DO NOT EDIT. + +package countries + +// CountriesISO3 indexes ISO3166 countries by their alpha-3 code. +var CountriesISO3 = map[string]Country{ + "ABW": {Name: "Aruba", ISOAlpha3: "ABW", ISOAlpha2: "AW", Code: "533"}, + "AFG": {Name: "Afghanistan", ISOAlpha3: "AFG", ISOAlpha2: "AF", Code: "004"}, + "AGO": {Name: "Angola", ISOAlpha3: "AGO", ISOAlpha2: "AO", Code: "024"}, + "AIA": {Name: "Anguilla", ISOAlpha3: "AIA", ISOAlpha2: "AI", Code: "660"}, + "ALA": {Name: "Åland Islands", ISOAlpha3: "ALA", ISOAlpha2: "AX", Code: "248"}, + "ALB": {Name: "Albania", ISOAlpha3: "ALB", ISOAlpha2: "AL", Code: "008"}, + "AND": {Name: "Andorra", ISOAlpha3: "AND", ISOAlpha2: "AD", Code: "020"}, + "ARE": {Name: "United Arab Emirates", ISOAlpha3: "ARE", ISOAlpha2: "AE", Code: "784"}, + "ARG": {Name: "Argentina", ISOAlpha3: "ARG", ISOAlpha2: "AR", Code: "032"}, + "ARM": {Name: "Armenia", ISOAlpha3: "ARM", ISOAlpha2: "AM", Code: "051"}, + "ASM": {Name: "American Samoa", ISOAlpha3: "ASM", ISOAlpha2: "AS", Code: "016"}, + "ATA": {Name: "Antarctica", ISOAlpha3: "ATA", ISOAlpha2: "AQ", Code: "010"}, + "ATF": {Name: "French Southern Territories", ISOAlpha3: "ATF", ISOAlpha2: "TF", Code: "260"}, + "ATG": {Name: "Antigua and Barbuda", ISOAlpha3: "ATG", ISOAlpha2: "AG", Code: "028"}, + "AUS": {Name: "Australia", ISOAlpha3: "AUS", ISOAlpha2: "AU", Code: "036"}, + "AUT": {Name: "Austria", ISOAlpha3: "AUT", ISOAlpha2: "AT", Code: "040"}, + "AZE": {Name: "Azerbaijan", ISOAlpha3: "AZE", ISOAlpha2: "AZ", Code: "031"}, + "BDI": {Name: "Burundi", ISOAlpha3: "BDI", ISOAlpha2: "BI", Code: "108"}, + "BEL": {Name: "Belgium", ISOAlpha3: "BEL", ISOAlpha2: "BE", Code: "056"}, + "BEN": {Name: "Benin", ISOAlpha3: "BEN", ISOAlpha2: "BJ", Code: "204"}, + "BES": {Name: "Bonaire, Sint Eustatius and Saba", ISOAlpha3: "BES", ISOAlpha2: "BQ", Code: "535"}, + "BFA": {Name: "Burkina Faso", ISOAlpha3: "BFA", ISOAlpha2: "BF", Code: "854"}, + "BGD": {Name: "Bangladesh", ISOAlpha3: "BGD", ISOAlpha2: "BD", Code: "050"}, + "BGR": {Name: "Bulgaria", ISOAlpha3: "BGR", ISOAlpha2: "BG", Code: "100"}, + "BHR": {Name: "Bahrain", ISOAlpha3: "BHR", ISOAlpha2: "BH", Code: "048"}, + "BHS": {Name: "Bahamas", ISOAlpha3: "BHS", ISOAlpha2: "BS", Code: "044"}, + "BIH": {Name: "Bosnia and Herzegovina", ISOAlpha3: "BIH", ISOAlpha2: "BA", Code: "070"}, + "BLM": {Name: "Saint Barthélemy", ISOAlpha3: "BLM", ISOAlpha2: "BL", Code: "652"}, + "BLR": {Name: "Belarus", ISOAlpha3: "BLR", ISOAlpha2: "BY", Code: "112"}, + "BLZ": {Name: "Belize", ISOAlpha3: "BLZ", ISOAlpha2: "BZ", Code: "084"}, + "BMU": {Name: "Bermuda", ISOAlpha3: "BMU", ISOAlpha2: "BM", Code: "060"}, + "BOL": {Name: "Bolivia (Plurinational State of)", ISOAlpha3: "BOL", ISOAlpha2: "BO", Code: "068"}, + "BRA": {Name: "Brazil", ISOAlpha3: "BRA", ISOAlpha2: "BR", Code: "076"}, + "BRB": {Name: "Barbados", ISOAlpha3: "BRB", ISOAlpha2: "BB", Code: "052"}, + "BRN": {Name: "Brunei Darussalam", ISOAlpha3: "BRN", ISOAlpha2: "BN", Code: "096"}, + "BTN": {Name: "Bhutan", ISOAlpha3: "BTN", ISOAlpha2: "BT", Code: "064"}, + "BVT": {Name: "Bouvet Island", ISOAlpha3: "BVT", ISOAlpha2: "BV", Code: "074"}, + "BWA": {Name: "Botswana", ISOAlpha3: "BWA", ISOAlpha2: "BW", Code: "072"}, + "CAF": {Name: "Central African Republic", ISOAlpha3: "CAF", ISOAlpha2: "CF", Code: "140"}, + "CAN": {Name: "Canada", ISOAlpha3: "CAN", ISOAlpha2: "CA", Code: "124"}, + "CCK": {Name: "Cocos (Keeling) Islands", ISOAlpha3: "CCK", ISOAlpha2: "CC", Code: "166"}, + "CHE": {Name: "Switzerland", ISOAlpha3: "CHE", ISOAlpha2: "CH", Code: "756"}, + "CHL": {Name: "Chile", ISOAlpha3: "CHL", ISOAlpha2: "CL", Code: "152"}, + "CHN": {Name: "China", ISOAlpha3: "CHN", ISOAlpha2: "CN", Code: "156"}, + "CIV": {Name: "Côte d'Ivoire", ISOAlpha3: "CIV", ISOAlpha2: "CI", Code: "384"}, + "CMR": {Name: "Cameroon", ISOAlpha3: "CMR", ISOAlpha2: "CM", Code: "120"}, + "COD": {Name: "Congo, Democratic Republic of the", ISOAlpha3: "COD", ISOAlpha2: "CD", Code: "180"}, + "COG": {Name: "Congo", ISOAlpha3: "COG", ISOAlpha2: "CG", Code: "178"}, + "COK": {Name: "Cook Islands", ISOAlpha3: "COK", ISOAlpha2: "CK", Code: "184"}, + "COL": {Name: "Colombia", ISOAlpha3: "COL", ISOAlpha2: "CO", Code: "170"}, + "COM": {Name: "Comoros", ISOAlpha3: "COM", ISOAlpha2: "KM", Code: "174"}, + "CPV": {Name: "Cabo Verde", ISOAlpha3: "CPV", ISOAlpha2: "CV", Code: "132"}, + "CRI": {Name: "Costa Rica", ISOAlpha3: "CRI", ISOAlpha2: "CR", Code: "188"}, + "CUB": {Name: "Cuba", ISOAlpha3: "CUB", ISOAlpha2: "CU", Code: "192"}, + "CUW": {Name: "Curaçao", ISOAlpha3: "CUW", ISOAlpha2: "CW", Code: "531"}, + "CXR": {Name: "Christmas Island", ISOAlpha3: "CXR", ISOAlpha2: "CX", Code: "162"}, + "CYM": {Name: "Cayman Islands", ISOAlpha3: "CYM", ISOAlpha2: "KY", Code: "136"}, + "CYP": {Name: "Cyprus", ISOAlpha3: "CYP", ISOAlpha2: "CY", Code: "196"}, + "CZE": {Name: "Czechia", ISOAlpha3: "CZE", ISOAlpha2: "CZ", Code: "203"}, + "DEU": {Name: "Germany", ISOAlpha3: "DEU", ISOAlpha2: "DE", Code: "276"}, + "DJI": {Name: "Djibouti", ISOAlpha3: "DJI", ISOAlpha2: "DJ", Code: "262"}, + "DMA": {Name: "Dominica", ISOAlpha3: "DMA", ISOAlpha2: "DM", Code: "212"}, + "DNK": {Name: "Denmark", ISOAlpha3: "DNK", ISOAlpha2: "DK", Code: "208"}, + "DOM": {Name: "Dominican Republic", ISOAlpha3: "DOM", ISOAlpha2: "DO", Code: "214"}, + "DZA": {Name: "Algeria", ISOAlpha3: "DZA", ISOAlpha2: "DZ", Code: "012"}, + "ECU": {Name: "Ecuador", ISOAlpha3: "ECU", ISOAlpha2: "EC", Code: "218"}, + "EGY": {Name: "Egypt", ISOAlpha3: "EGY", ISOAlpha2: "EG", Code: "818"}, + "ERI": {Name: "Eritrea", ISOAlpha3: "ERI", ISOAlpha2: "ER", Code: "232"}, + "ESH": {Name: "Western Sahara", ISOAlpha3: "ESH", ISOAlpha2: "EH", Code: "732"}, + "ESP": {Name: "Spain", ISOAlpha3: "ESP", ISOAlpha2: "ES", Code: "724"}, + "EST": {Name: "Estonia", ISOAlpha3: "EST", ISOAlpha2: "EE", Code: "233"}, + "ETH": {Name: "Ethiopia", ISOAlpha3: "ETH", ISOAlpha2: "ET", Code: "231"}, + "FIN": {Name: "Finland", ISOAlpha3: "FIN", ISOAlpha2: "FI", Code: "246"}, + "FJI": {Name: "Fiji", ISOAlpha3: "FJI", ISOAlpha2: "FJ", Code: "242"}, + "FLK": {Name: "Falkland Islands (Malvinas)", ISOAlpha3: "FLK", ISOAlpha2: "FK", Code: "238"}, + "FRA": {Name: "France", ISOAlpha3: "FRA", ISOAlpha2: "FR", Code: "250"}, + "FRO": {Name: "Faroe Islands", ISOAlpha3: "FRO", ISOAlpha2: "FO", Code: "234"}, + "FSM": {Name: "Micronesia (Federated States of)", ISOAlpha3: "FSM", ISOAlpha2: "FM", Code: "583"}, + "GAB": {Name: "Gabon", ISOAlpha3: "GAB", ISOAlpha2: "GA", Code: "266"}, + "GBR": {Name: "United Kingdom of Great Britain and Northern Ireland", ISOAlpha3: "GBR", ISOAlpha2: "GB", Code: "826"}, + "GEO": {Name: "Georgia", ISOAlpha3: "GEO", ISOAlpha2: "GE", Code: "268"}, + "GGY": {Name: "Guernsey", ISOAlpha3: "GGY", ISOAlpha2: "GG", Code: "831"}, + "GHA": {Name: "Ghana", ISOAlpha3: "GHA", ISOAlpha2: "GH", Code: "288"}, + "GIB": {Name: "Gibraltar", ISOAlpha3: "GIB", ISOAlpha2: "GI", Code: "292"}, + "GIN": {Name: "Guinea", ISOAlpha3: "GIN", ISOAlpha2: "GN", Code: "324"}, + "GLP": {Name: "Guadeloupe", ISOAlpha3: "GLP", ISOAlpha2: "GP", Code: "312"}, + "GMB": {Name: "Gambia", ISOAlpha3: "GMB", ISOAlpha2: "GM", Code: "270"}, + "GNB": {Name: "Guinea-Bissau", ISOAlpha3: "GNB", ISOAlpha2: "GW", Code: "624"}, + "GNQ": {Name: "Equatorial Guinea", ISOAlpha3: "GNQ", ISOAlpha2: "GQ", Code: "226"}, + "GRC": {Name: "Greece", ISOAlpha3: "GRC", ISOAlpha2: "GR", Code: "300"}, + "GRD": {Name: "Grenada", ISOAlpha3: "GRD", ISOAlpha2: "GD", Code: "308"}, + "GRL": {Name: "Greenland", ISOAlpha3: "GRL", ISOAlpha2: "GL", Code: "304"}, + "GTM": {Name: "Guatemala", ISOAlpha3: "GTM", ISOAlpha2: "GT", Code: "320"}, + "GUF": {Name: "French Guiana", ISOAlpha3: "GUF", ISOAlpha2: "GF", Code: "254"}, + "GUM": {Name: "Guam", ISOAlpha3: "GUM", ISOAlpha2: "GU", Code: "316"}, + "GUY": {Name: "Guyana", ISOAlpha3: "GUY", ISOAlpha2: "GY", Code: "328"}, + "HKG": {Name: "Hong Kong", ISOAlpha3: "HKG", ISOAlpha2: "HK", Code: "344"}, + "HMD": {Name: "Heard Island and McDonald Islands", ISOAlpha3: "HMD", ISOAlpha2: "HM", Code: "334"}, + "HND": {Name: "Honduras", ISOAlpha3: "HND", ISOAlpha2: "HN", Code: "340"}, + "HRV": {Name: "Croatia", ISOAlpha3: "HRV", ISOAlpha2: "HR", Code: "191"}, + "HTI": {Name: "Haiti", ISOAlpha3: "HTI", ISOAlpha2: "HT", Code: "332"}, + "HUN": {Name: "Hungary", ISOAlpha3: "HUN", ISOAlpha2: "HU", Code: "348"}, + "IDN": {Name: "Indonesia", ISOAlpha3: "IDN", ISOAlpha2: "ID", Code: "360"}, + "IMN": {Name: "Isle of Man", ISOAlpha3: "IMN", ISOAlpha2: "IM", Code: "833"}, + "IND": {Name: "India", ISOAlpha3: "IND", ISOAlpha2: "IN", Code: "356"}, + "IOT": {Name: "British Indian Ocean Territory", ISOAlpha3: "IOT", ISOAlpha2: "IO", Code: "086"}, + "IRL": {Name: "Ireland", ISOAlpha3: "IRL", ISOAlpha2: "IE", Code: "372"}, + "IRN": {Name: "Iran (Islamic Republic of)", ISOAlpha3: "IRN", ISOAlpha2: "IR", Code: "364"}, + "IRQ": {Name: "Iraq", ISOAlpha3: "IRQ", ISOAlpha2: "IQ", Code: "368"}, + "ISL": {Name: "Iceland", ISOAlpha3: "ISL", ISOAlpha2: "IS", Code: "352"}, + "ISR": {Name: "Israel", ISOAlpha3: "ISR", ISOAlpha2: "IL", Code: "376"}, + "ITA": {Name: "Italy", ISOAlpha3: "ITA", ISOAlpha2: "IT", Code: "380"}, + "JAM": {Name: "Jamaica", ISOAlpha3: "JAM", ISOAlpha2: "JM", Code: "388"}, + "JEY": {Name: "Jersey", ISOAlpha3: "JEY", ISOAlpha2: "JE", Code: "832"}, + "JOR": {Name: "Jordan", ISOAlpha3: "JOR", ISOAlpha2: "JO", Code: "400"}, + "JPN": {Name: "Japan", ISOAlpha3: "JPN", ISOAlpha2: "JP", Code: "392"}, + "KAZ": {Name: "Kazakhstan", ISOAlpha3: "KAZ", ISOAlpha2: "KZ", Code: "398"}, + "KEN": {Name: "Kenya", ISOAlpha3: "KEN", ISOAlpha2: "KE", Code: "404"}, + "KGZ": {Name: "Kyrgyzstan", ISOAlpha3: "KGZ", ISOAlpha2: "KG", Code: "417"}, + "KHM": {Name: "Cambodia", ISOAlpha3: "KHM", ISOAlpha2: "KH", Code: "116"}, + "KIR": {Name: "Kiribati", ISOAlpha3: "KIR", ISOAlpha2: "KI", Code: "296"}, + "KNA": {Name: "Saint Kitts and Nevis", ISOAlpha3: "KNA", ISOAlpha2: "KN", Code: "659"}, + "KOR": {Name: "Korea, Republic of", ISOAlpha3: "KOR", ISOAlpha2: "KR", Code: "410"}, + "KWT": {Name: "Kuwait", ISOAlpha3: "KWT", ISOAlpha2: "KW", Code: "414"}, + "LAO": {Name: "Lao People's Democratic Republic", ISOAlpha3: "LAO", ISOAlpha2: "LA", Code: "418"}, + "LBN": {Name: "Lebanon", ISOAlpha3: "LBN", ISOAlpha2: "LB", Code: "422"}, + "LBR": {Name: "Liberia", ISOAlpha3: "LBR", ISOAlpha2: "LR", Code: "430"}, + "LBY": {Name: "Libya", ISOAlpha3: "LBY", ISOAlpha2: "LY", Code: "434"}, + "LCA": {Name: "Saint Lucia", ISOAlpha3: "LCA", ISOAlpha2: "LC", Code: "662"}, + "LIE": {Name: "Liechtenstein", ISOAlpha3: "LIE", ISOAlpha2: "LI", Code: "438"}, + "LKA": {Name: "Sri Lanka", ISOAlpha3: "LKA", ISOAlpha2: "LK", Code: "144"}, + "LSO": {Name: "Lesotho", ISOAlpha3: "LSO", ISOAlpha2: "LS", Code: "426"}, + "LTU": {Name: "Lithuania", ISOAlpha3: "LTU", ISOAlpha2: "LT", Code: "440"}, + "LUX": {Name: "Luxembourg", ISOAlpha3: "LUX", ISOAlpha2: "LU", Code: "442"}, + "LVA": {Name: "Latvia", ISOAlpha3: "LVA", ISOAlpha2: "LV", Code: "428"}, + "MAC": {Name: "Macao", ISOAlpha3: "MAC", ISOAlpha2: "MO", Code: "446"}, + "MAF": {Name: "Saint Martin (French part)", ISOAlpha3: "MAF", ISOAlpha2: "MF", Code: "663"}, + "MAR": {Name: "Morocco", ISOAlpha3: "MAR", ISOAlpha2: "MA", Code: "504"}, + "MCO": {Name: "Monaco", ISOAlpha3: "MCO", ISOAlpha2: "MC", Code: "492"}, + "MDA": {Name: "Moldova, Republic of", ISOAlpha3: "MDA", ISOAlpha2: "MD", Code: "498"}, + "MDG": {Name: "Madagascar", ISOAlpha3: "MDG", ISOAlpha2: "MG", Code: "450"}, + "MDV": {Name: "Maldives", ISOAlpha3: "MDV", ISOAlpha2: "MV", Code: "462"}, + "MEX": {Name: "Mexico", ISOAlpha3: "MEX", ISOAlpha2: "MX", Code: "484"}, + "MHL": {Name: "Marshall Islands", ISOAlpha3: "MHL", ISOAlpha2: "MH", Code: "584"}, + "MKD": {Name: "North Macedonia", ISOAlpha3: "MKD", ISOAlpha2: "MK", Code: "807"}, + "MLI": {Name: "Mali", ISOAlpha3: "MLI", ISOAlpha2: "ML", Code: "466"}, + "MLT": {Name: "Malta", ISOAlpha3: "MLT", ISOAlpha2: "MT", Code: "470"}, + "MMR": {Name: "Myanmar", ISOAlpha3: "MMR", ISOAlpha2: "MM", Code: "104"}, + "MNE": {Name: "Montenegro", ISOAlpha3: "MNE", ISOAlpha2: "ME", Code: "499"}, + "MNG": {Name: "Mongolia", ISOAlpha3: "MNG", ISOAlpha2: "MN", Code: "496"}, + "MNP": {Name: "Northern Mariana Islands", ISOAlpha3: "MNP", ISOAlpha2: "MP", Code: "580"}, + "MOZ": {Name: "Mozambique", ISOAlpha3: "MOZ", ISOAlpha2: "MZ", Code: "508"}, + "MRT": {Name: "Mauritania", ISOAlpha3: "MRT", ISOAlpha2: "MR", Code: "478"}, + "MSR": {Name: "Montserrat", ISOAlpha3: "MSR", ISOAlpha2: "MS", Code: "500"}, + "MTQ": {Name: "Martinique", ISOAlpha3: "MTQ", ISOAlpha2: "MQ", Code: "474"}, + "MUS": {Name: "Mauritius", ISOAlpha3: "MUS", ISOAlpha2: "MU", Code: "480"}, + "MWI": {Name: "Malawi", ISOAlpha3: "MWI", ISOAlpha2: "MW", Code: "454"}, + "MYS": {Name: "Malaysia", ISOAlpha3: "MYS", ISOAlpha2: "MY", Code: "458"}, + "MYT": {Name: "Mayotte", ISOAlpha3: "MYT", ISOAlpha2: "YT", Code: "175"}, + "NAM": {Name: "Namibia", ISOAlpha3: "NAM", ISOAlpha2: "NA", Code: "516"}, + "NCL": {Name: "New Caledonia", ISOAlpha3: "NCL", ISOAlpha2: "NC", Code: "540"}, + "NER": {Name: "Niger", ISOAlpha3: "NER", ISOAlpha2: "NE", Code: "562"}, + "NFK": {Name: "Norfolk Island", ISOAlpha3: "NFK", ISOAlpha2: "NF", Code: "574"}, + "NGA": {Name: "Nigeria", ISOAlpha3: "NGA", ISOAlpha2: "NG", Code: "566"}, + "NIC": {Name: "Nicaragua", ISOAlpha3: "NIC", ISOAlpha2: "NI", Code: "558"}, + "NIU": {Name: "Niue", ISOAlpha3: "NIU", ISOAlpha2: "NU", Code: "570"}, + "NLD": {Name: "Netherlands", ISOAlpha3: "NLD", ISOAlpha2: "NL", Code: "528"}, + "NOR": {Name: "Norway", ISOAlpha3: "NOR", ISOAlpha2: "NO", Code: "578"}, + "NPL": {Name: "Nepal", ISOAlpha3: "NPL", ISOAlpha2: "NP", Code: "524"}, + "NRU": {Name: "Nauru", ISOAlpha3: "NRU", ISOAlpha2: "NR", Code: "520"}, + "NZL": {Name: "New Zealand", ISOAlpha3: "NZL", ISOAlpha2: "NZ", Code: "554"}, + "OMN": {Name: "Oman", ISOAlpha3: "OMN", ISOAlpha2: "OM", Code: "512"}, + "PAK": {Name: "Pakistan", ISOAlpha3: "PAK", ISOAlpha2: "PK", Code: "586"}, + "PAN": {Name: "Panama", ISOAlpha3: "PAN", ISOAlpha2: "PA", Code: "591"}, + "PCN": {Name: "Pitcairn", ISOAlpha3: "PCN", ISOAlpha2: "PN", Code: "612"}, + "PER": {Name: "Peru", ISOAlpha3: "PER", ISOAlpha2: "PE", Code: "604"}, + "PHL": {Name: "Philippines", ISOAlpha3: "PHL", ISOAlpha2: "PH", Code: "608"}, + "PLW": {Name: "Palau", ISOAlpha3: "PLW", ISOAlpha2: "PW", Code: "585"}, + "PNG": {Name: "Papua New Guinea", ISOAlpha3: "PNG", ISOAlpha2: "PG", Code: "598"}, + "POL": {Name: "Poland", ISOAlpha3: "POL", ISOAlpha2: "PL", Code: "616"}, + "PRI": {Name: "Puerto Rico", ISOAlpha3: "PRI", ISOAlpha2: "PR", Code: "630"}, + "PRK": {Name: "Korea (Democratic People's Republic of)", ISOAlpha3: "PRK", ISOAlpha2: "KP", Code: "408"}, + "PRT": {Name: "Portugal", ISOAlpha3: "PRT", ISOAlpha2: "PT", Code: "620"}, + "PRY": {Name: "Paraguay", ISOAlpha3: "PRY", ISOAlpha2: "PY", Code: "600"}, + "PSE": {Name: "Palestine, State of", ISOAlpha3: "PSE", ISOAlpha2: "PS", Code: "275"}, + "PYF": {Name: "French Polynesia", ISOAlpha3: "PYF", ISOAlpha2: "PF", Code: "258"}, + "QAT": {Name: "Qatar", ISOAlpha3: "QAT", ISOAlpha2: "QA", Code: "634"}, + "REU": {Name: "Réunion", ISOAlpha3: "REU", ISOAlpha2: "RE", Code: "638"}, + "ROU": {Name: "Romania", ISOAlpha3: "ROU", ISOAlpha2: "RO", Code: "642"}, + "RUS": {Name: "Russian Federation", ISOAlpha3: "RUS", ISOAlpha2: "RU", Code: "643"}, + "RWA": {Name: "Rwanda", ISOAlpha3: "RWA", ISOAlpha2: "RW", Code: "646"}, + "SAU": {Name: "Saudi Arabia", ISOAlpha3: "SAU", ISOAlpha2: "SA", Code: "682"}, + "SDN": {Name: "Sudan", ISOAlpha3: "SDN", ISOAlpha2: "SD", Code: "729"}, + "SEN": {Name: "Senegal", ISOAlpha3: "SEN", ISOAlpha2: "SN", Code: "686"}, + "SGP": {Name: "Singapore", ISOAlpha3: "SGP", ISOAlpha2: "SG", Code: "702"}, + "SGS": {Name: "South Georgia and the South Sandwich Islands", ISOAlpha3: "SGS", ISOAlpha2: "GS", Code: "239"}, + "SHN": {Name: "Saint Helena, Ascension and Tristan da Cunha", ISOAlpha3: "SHN", ISOAlpha2: "SH", Code: "654"}, + "SJM": {Name: "Svalbard and Jan Mayen", ISOAlpha3: "SJM", ISOAlpha2: "SJ", Code: "744"}, + "SLB": {Name: "Solomon Islands", ISOAlpha3: "SLB", ISOAlpha2: "SB", Code: "090"}, + "SLE": {Name: "Sierra Leone", ISOAlpha3: "SLE", ISOAlpha2: "SL", Code: "694"}, + "SLV": {Name: "El Salvador", ISOAlpha3: "SLV", ISOAlpha2: "SV", Code: "222"}, + "SMR": {Name: "San Marino", ISOAlpha3: "SMR", ISOAlpha2: "SM", Code: "674"}, + "SOM": {Name: "Somalia", ISOAlpha3: "SOM", ISOAlpha2: "SO", Code: "706"}, + "SPM": {Name: "Saint Pierre and Miquelon", ISOAlpha3: "SPM", ISOAlpha2: "PM", Code: "666"}, + "SRB": {Name: "Serbia", ISOAlpha3: "SRB", ISOAlpha2: "RS", Code: "688"}, + "SSD": {Name: "South Sudan", ISOAlpha3: "SSD", ISOAlpha2: "SS", Code: "728"}, + "STP": {Name: "Sao Tome and Principe", ISOAlpha3: "STP", ISOAlpha2: "ST", Code: "678"}, + "SUR": {Name: "Suriname", ISOAlpha3: "SUR", ISOAlpha2: "SR", Code: "740"}, + "SVK": {Name: "Slovakia", ISOAlpha3: "SVK", ISOAlpha2: "SK", Code: "703"}, + "SVN": {Name: "Slovenia", ISOAlpha3: "SVN", ISOAlpha2: "SI", Code: "705"}, + "SWE": {Name: "Sweden", ISOAlpha3: "SWE", ISOAlpha2: "SE", Code: "752"}, + "SWZ": {Name: "Eswatini", ISOAlpha3: "SWZ", ISOAlpha2: "SZ", Code: "748"}, + "SXM": {Name: "Sint Maarten (Dutch part)", ISOAlpha3: "SXM", ISOAlpha2: "SX", Code: "534"}, + "SYC": {Name: "Seychelles", ISOAlpha3: "SYC", ISOAlpha2: "SC", Code: "690"}, + "SYR": {Name: "Syrian Arab Republic", ISOAlpha3: "SYR", ISOAlpha2: "SY", Code: "760"}, + "TCA": {Name: "Turks and Caicos Islands", ISOAlpha3: "TCA", ISOAlpha2: "TC", Code: "796"}, + "TCD": {Name: "Chad", ISOAlpha3: "TCD", ISOAlpha2: "TD", Code: "148"}, + "TGO": {Name: "Togo", ISOAlpha3: "TGO", ISOAlpha2: "TG", Code: "768"}, + "THA": {Name: "Thailand", ISOAlpha3: "THA", ISOAlpha2: "TH", Code: "764"}, + "TJK": {Name: "Tajikistan", ISOAlpha3: "TJK", ISOAlpha2: "TJ", Code: "762"}, + "TKL": {Name: "Tokelau", ISOAlpha3: "TKL", ISOAlpha2: "TK", Code: "772"}, + "TKM": {Name: "Turkmenistan", ISOAlpha3: "TKM", ISOAlpha2: "TM", Code: "795"}, + "TLS": {Name: "Timor-Leste", ISOAlpha3: "TLS", ISOAlpha2: "TL", Code: "626"}, + "TON": {Name: "Tonga", ISOAlpha3: "TON", ISOAlpha2: "TO", Code: "776"}, + "TTO": {Name: "Trinidad and Tobago", ISOAlpha3: "TTO", ISOAlpha2: "TT", Code: "780"}, + "TUN": {Name: "Tunisia", ISOAlpha3: "TUN", ISOAlpha2: "TN", Code: "788"}, + "TUR": {Name: "Turkey", ISOAlpha3: "TUR", ISOAlpha2: "TR", Code: "792"}, + "TUV": {Name: "Tuvalu", ISOAlpha3: "TUV", ISOAlpha2: "TV", Code: "798"}, + "TWN": {Name: "Taiwan, Province of China", ISOAlpha3: "TWN", ISOAlpha2: "TW", Code: "158"}, + "TZA": {Name: "Tanzania, United Republic of", ISOAlpha3: "TZA", ISOAlpha2: "TZ", Code: "834"}, + "UGA": {Name: "Uganda", ISOAlpha3: "UGA", ISOAlpha2: "UG", Code: "800"}, + "UKR": {Name: "Ukraine", ISOAlpha3: "UKR", ISOAlpha2: "UA", Code: "804"}, + "UMI": {Name: "United States Minor Outlying Islands", ISOAlpha3: "UMI", ISOAlpha2: "UM", Code: "581"}, + "URY": {Name: "Uruguay", ISOAlpha3: "URY", ISOAlpha2: "UY", Code: "858"}, + "USA": {Name: "United States of America", ISOAlpha3: "USA", ISOAlpha2: "US", Code: "840"}, + "UZB": {Name: "Uzbekistan", ISOAlpha3: "UZB", ISOAlpha2: "UZ", Code: "860"}, + "VAT": {Name: "Holy See", ISOAlpha3: "VAT", ISOAlpha2: "VA", Code: "336"}, + "VCT": {Name: "Saint Vincent and the Grenadines", ISOAlpha3: "VCT", ISOAlpha2: "VC", Code: "670"}, + "VEN": {Name: "Venezuela (Bolivarian Republic of)", ISOAlpha3: "VEN", ISOAlpha2: "VE", Code: "862"}, + "VGB": {Name: "Virgin Islands (British)", ISOAlpha3: "VGB", ISOAlpha2: "VG", Code: "092"}, + "VIR": {Name: "Virgin Islands (U.S.)", ISOAlpha3: "VIR", ISOAlpha2: "VI", Code: "850"}, + "VNM": {Name: "Viet Nam", ISOAlpha3: "VNM", ISOAlpha2: "VN", Code: "704"}, + "VUT": {Name: "Vanuatu", ISOAlpha3: "VUT", ISOAlpha2: "VU", Code: "548"}, + "WLF": {Name: "Wallis and Futuna", ISOAlpha3: "WLF", ISOAlpha2: "WF", Code: "876"}, + "WSM": {Name: "Samoa", ISOAlpha3: "WSM", ISOAlpha2: "WS", Code: "882"}, + "YEM": {Name: "Yemen", ISOAlpha3: "YEM", ISOAlpha2: "YE", Code: "887"}, + "ZAF": {Name: "South Africa", ISOAlpha3: "ZAF", ISOAlpha2: "ZA", Code: "710"}, + "ZMB": {Name: "Zambia", ISOAlpha3: "ZMB", ISOAlpha2: "ZM", Code: "894"}, + "ZWE": {Name: "Zimbabwe", ISOAlpha3: "ZWE", ISOAlpha2: "ZW", Code: "716"}, +} + +// CountriesISO2 indexes ISO3166 countries by their alpha-2 code. +var CountriesISO2 = map[string]Country{ + "AD": {Name: "Andorra", ISOAlpha3: "AND", ISOAlpha2: "AD", Code: "020"}, + "AE": {Name: "United Arab Emirates", ISOAlpha3: "ARE", ISOAlpha2: "AE", Code: "784"}, + "AF": {Name: "Afghanistan", ISOAlpha3: "AFG", ISOAlpha2: "AF", Code: "004"}, + "AG": {Name: "Antigua and Barbuda", ISOAlpha3: "ATG", ISOAlpha2: "AG", Code: "028"}, + "AI": {Name: "Anguilla", ISOAlpha3: "AIA", ISOAlpha2: "AI", Code: "660"}, + "AL": {Name: "Albania", ISOAlpha3: "ALB", ISOAlpha2: "AL", Code: "008"}, + "AM": {Name: "Armenia", ISOAlpha3: "ARM", ISOAlpha2: "AM", Code: "051"}, + "AO": {Name: "Angola", ISOAlpha3: "AGO", ISOAlpha2: "AO", Code: "024"}, + "AQ": {Name: "Antarctica", ISOAlpha3: "ATA", ISOAlpha2: "AQ", Code: "010"}, + "AR": {Name: "Argentina", ISOAlpha3: "ARG", ISOAlpha2: "AR", Code: "032"}, + "AS": {Name: "American Samoa", ISOAlpha3: "ASM", ISOAlpha2: "AS", Code: "016"}, + "AT": {Name: "Austria", ISOAlpha3: "AUT", ISOAlpha2: "AT", Code: "040"}, + "AU": {Name: "Australia", ISOAlpha3: "AUS", ISOAlpha2: "AU", Code: "036"}, + "AW": {Name: "Aruba", ISOAlpha3: "ABW", ISOAlpha2: "AW", Code: "533"}, + "AX": {Name: "Åland Islands", ISOAlpha3: "ALA", ISOAlpha2: "AX", Code: "248"}, + "AZ": {Name: "Azerbaijan", ISOAlpha3: "AZE", ISOAlpha2: "AZ", Code: "031"}, + "BA": {Name: "Bosnia and Herzegovina", ISOAlpha3: "BIH", ISOAlpha2: "BA", Code: "070"}, + "BB": {Name: "Barbados", ISOAlpha3: "BRB", ISOAlpha2: "BB", Code: "052"}, + "BD": {Name: "Bangladesh", ISOAlpha3: "BGD", ISOAlpha2: "BD", Code: "050"}, + "BE": {Name: "Belgium", ISOAlpha3: "BEL", ISOAlpha2: "BE", Code: "056"}, + "BF": {Name: "Burkina Faso", ISOAlpha3: "BFA", ISOAlpha2: "BF", Code: "854"}, + "BG": {Name: "Bulgaria", ISOAlpha3: "BGR", ISOAlpha2: "BG", Code: "100"}, + "BH": {Name: "Bahrain", ISOAlpha3: "BHR", ISOAlpha2: "BH", Code: "048"}, + "BI": {Name: "Burundi", ISOAlpha3: "BDI", ISOAlpha2: "BI", Code: "108"}, + "BJ": {Name: "Benin", ISOAlpha3: "BEN", ISOAlpha2: "BJ", Code: "204"}, + "BL": {Name: "Saint Barthélemy", ISOAlpha3: "BLM", ISOAlpha2: "BL", Code: "652"}, + "BM": {Name: "Bermuda", ISOAlpha3: "BMU", ISOAlpha2: "BM", Code: "060"}, + "BN": {Name: "Brunei Darussalam", ISOAlpha3: "BRN", ISOAlpha2: "BN", Code: "096"}, + "BO": {Name: "Bolivia (Plurinational State of)", ISOAlpha3: "BOL", ISOAlpha2: "BO", Code: "068"}, + "BQ": {Name: "Bonaire, Sint Eustatius and Saba", ISOAlpha3: "BES", ISOAlpha2: "BQ", Code: "535"}, + "BR": {Name: "Brazil", ISOAlpha3: "BRA", ISOAlpha2: "BR", Code: "076"}, + "BS": {Name: "Bahamas", ISOAlpha3: "BHS", ISOAlpha2: "BS", Code: "044"}, + "BT": {Name: "Bhutan", ISOAlpha3: "BTN", ISOAlpha2: "BT", Code: "064"}, + "BV": {Name: "Bouvet Island", ISOAlpha3: "BVT", ISOAlpha2: "BV", Code: "074"}, + "BW": {Name: "Botswana", ISOAlpha3: "BWA", ISOAlpha2: "BW", Code: "072"}, + "BY": {Name: "Belarus", ISOAlpha3: "BLR", ISOAlpha2: "BY", Code: "112"}, + "BZ": {Name: "Belize", ISOAlpha3: "BLZ", ISOAlpha2: "BZ", Code: "084"}, + "CA": {Name: "Canada", ISOAlpha3: "CAN", ISOAlpha2: "CA", Code: "124"}, + "CC": {Name: "Cocos (Keeling) Islands", ISOAlpha3: "CCK", ISOAlpha2: "CC", Code: "166"}, + "CD": {Name: "Congo, Democratic Republic of the", ISOAlpha3: "COD", ISOAlpha2: "CD", Code: "180"}, + "CF": {Name: "Central African Republic", ISOAlpha3: "CAF", ISOAlpha2: "CF", Code: "140"}, + "CG": {Name: "Congo", ISOAlpha3: "COG", ISOAlpha2: "CG", Code: "178"}, + "CH": {Name: "Switzerland", ISOAlpha3: "CHE", ISOAlpha2: "CH", Code: "756"}, + "CI": {Name: "Côte d'Ivoire", ISOAlpha3: "CIV", ISOAlpha2: "CI", Code: "384"}, + "CK": {Name: "Cook Islands", ISOAlpha3: "COK", ISOAlpha2: "CK", Code: "184"}, + "CL": {Name: "Chile", ISOAlpha3: "CHL", ISOAlpha2: "CL", Code: "152"}, + "CM": {Name: "Cameroon", ISOAlpha3: "CMR", ISOAlpha2: "CM", Code: "120"}, + "CN": {Name: "China", ISOAlpha3: "CHN", ISOAlpha2: "CN", Code: "156"}, + "CO": {Name: "Colombia", ISOAlpha3: "COL", ISOAlpha2: "CO", Code: "170"}, + "CR": {Name: "Costa Rica", ISOAlpha3: "CRI", ISOAlpha2: "CR", Code: "188"}, + "CU": {Name: "Cuba", ISOAlpha3: "CUB", ISOAlpha2: "CU", Code: "192"}, + "CV": {Name: "Cabo Verde", ISOAlpha3: "CPV", ISOAlpha2: "CV", Code: "132"}, + "CW": {Name: "Curaçao", ISOAlpha3: "CUW", ISOAlpha2: "CW", Code: "531"}, + "CX": {Name: "Christmas Island", ISOAlpha3: "CXR", ISOAlpha2: "CX", Code: "162"}, + "CY": {Name: "Cyprus", ISOAlpha3: "CYP", ISOAlpha2: "CY", Code: "196"}, + "CZ": {Name: "Czechia", ISOAlpha3: "CZE", ISOAlpha2: "CZ", Code: "203"}, + "DE": {Name: "Germany", ISOAlpha3: "DEU", ISOAlpha2: "DE", Code: "276"}, + "DJ": {Name: "Djibouti", ISOAlpha3: "DJI", ISOAlpha2: "DJ", Code: "262"}, + "DK": {Name: "Denmark", ISOAlpha3: "DNK", ISOAlpha2: "DK", Code: "208"}, + "DM": {Name: "Dominica", ISOAlpha3: "DMA", ISOAlpha2: "DM", Code: "212"}, + "DO": {Name: "Dominican Republic", ISOAlpha3: "DOM", ISOAlpha2: "DO", Code: "214"}, + "DZ": {Name: "Algeria", ISOAlpha3: "DZA", ISOAlpha2: "DZ", Code: "012"}, + "EC": {Name: "Ecuador", ISOAlpha3: "ECU", ISOAlpha2: "EC", Code: "218"}, + "EE": {Name: "Estonia", ISOAlpha3: "EST", ISOAlpha2: "EE", Code: "233"}, + "EG": {Name: "Egypt", ISOAlpha3: "EGY", ISOAlpha2: "EG", Code: "818"}, + "EH": {Name: "Western Sahara", ISOAlpha3: "ESH", ISOAlpha2: "EH", Code: "732"}, + "ER": {Name: "Eritrea", ISOAlpha3: "ERI", ISOAlpha2: "ER", Code: "232"}, + "ES": {Name: "Spain", ISOAlpha3: "ESP", ISOAlpha2: "ES", Code: "724"}, + "ET": {Name: "Ethiopia", ISOAlpha3: "ETH", ISOAlpha2: "ET", Code: "231"}, + "FI": {Name: "Finland", ISOAlpha3: "FIN", ISOAlpha2: "FI", Code: "246"}, + "FJ": {Name: "Fiji", ISOAlpha3: "FJI", ISOAlpha2: "FJ", Code: "242"}, + "FK": {Name: "Falkland Islands (Malvinas)", ISOAlpha3: "FLK", ISOAlpha2: "FK", Code: "238"}, + "FM": {Name: "Micronesia (Federated States of)", ISOAlpha3: "FSM", ISOAlpha2: "FM", Code: "583"}, + "FO": {Name: "Faroe Islands", ISOAlpha3: "FRO", ISOAlpha2: "FO", Code: "234"}, + "FR": {Name: "France", ISOAlpha3: "FRA", ISOAlpha2: "FR", Code: "250"}, + "GA": {Name: "Gabon", ISOAlpha3: "GAB", ISOAlpha2: "GA", Code: "266"}, + "GB": {Name: "United Kingdom of Great Britain and Northern Ireland", ISOAlpha3: "GBR", ISOAlpha2: "GB", Code: "826"}, + "GD": {Name: "Grenada", ISOAlpha3: "GRD", ISOAlpha2: "GD", Code: "308"}, + "GE": {Name: "Georgia", ISOAlpha3: "GEO", ISOAlpha2: "GE", Code: "268"}, + "GF": {Name: "French Guiana", ISOAlpha3: "GUF", ISOAlpha2: "GF", Code: "254"}, + "GG": {Name: "Guernsey", ISOAlpha3: "GGY", ISOAlpha2: "GG", Code: "831"}, + "GH": {Name: "Ghana", ISOAlpha3: "GHA", ISOAlpha2: "GH", Code: "288"}, + "GI": {Name: "Gibraltar", ISOAlpha3: "GIB", ISOAlpha2: "GI", Code: "292"}, + "GL": {Name: "Greenland", ISOAlpha3: "GRL", ISOAlpha2: "GL", Code: "304"}, + "GM": {Name: "Gambia", ISOAlpha3: "GMB", ISOAlpha2: "GM", Code: "270"}, + "GN": {Name: "Guinea", ISOAlpha3: "GIN", ISOAlpha2: "GN", Code: "324"}, + "GP": {Name: "Guadeloupe", ISOAlpha3: "GLP", ISOAlpha2: "GP", Code: "312"}, + "GQ": {Name: "Equatorial Guinea", ISOAlpha3: "GNQ", ISOAlpha2: "GQ", Code: "226"}, + "GR": {Name: "Greece", ISOAlpha3: "GRC", ISOAlpha2: "GR", Code: "300"}, + "GS": {Name: "South Georgia and the South Sandwich Islands", ISOAlpha3: "SGS", ISOAlpha2: "GS", Code: "239"}, + "GT": {Name: "Guatemala", ISOAlpha3: "GTM", ISOAlpha2: "GT", Code: "320"}, + "GU": {Name: "Guam", ISOAlpha3: "GUM", ISOAlpha2: "GU", Code: "316"}, + "GW": {Name: "Guinea-Bissau", ISOAlpha3: "GNB", ISOAlpha2: "GW", Code: "624"}, + "GY": {Name: "Guyana", ISOAlpha3: "GUY", ISOAlpha2: "GY", Code: "328"}, + "HK": {Name: "Hong Kong", ISOAlpha3: "HKG", ISOAlpha2: "HK", Code: "344"}, + "HM": {Name: "Heard Island and McDonald Islands", ISOAlpha3: "HMD", ISOAlpha2: "HM", Code: "334"}, + "HN": {Name: "Honduras", ISOAlpha3: "HND", ISOAlpha2: "HN", Code: "340"}, + "HR": {Name: "Croatia", ISOAlpha3: "HRV", ISOAlpha2: "HR", Code: "191"}, + "HT": {Name: "Haiti", ISOAlpha3: "HTI", ISOAlpha2: "HT", Code: "332"}, + "HU": {Name: "Hungary", ISOAlpha3: "HUN", ISOAlpha2: "HU", Code: "348"}, + "ID": {Name: "Indonesia", ISOAlpha3: "IDN", ISOAlpha2: "ID", Code: "360"}, + "IE": {Name: "Ireland", ISOAlpha3: "IRL", ISOAlpha2: "IE", Code: "372"}, + "IL": {Name: "Israel", ISOAlpha3: "ISR", ISOAlpha2: "IL", Code: "376"}, + "IM": {Name: "Isle of Man", ISOAlpha3: "IMN", ISOAlpha2: "IM", Code: "833"}, + "IN": {Name: "India", ISOAlpha3: "IND", ISOAlpha2: "IN", Code: "356"}, + "IO": {Name: "British Indian Ocean Territory", ISOAlpha3: "IOT", ISOAlpha2: "IO", Code: "086"}, + "IQ": {Name: "Iraq", ISOAlpha3: "IRQ", ISOAlpha2: "IQ", Code: "368"}, + "IR": {Name: "Iran (Islamic Republic of)", ISOAlpha3: "IRN", ISOAlpha2: "IR", Code: "364"}, + "IS": {Name: "Iceland", ISOAlpha3: "ISL", ISOAlpha2: "IS", Code: "352"}, + "IT": {Name: "Italy", ISOAlpha3: "ITA", ISOAlpha2: "IT", Code: "380"}, + "JE": {Name: "Jersey", ISOAlpha3: "JEY", ISOAlpha2: "JE", Code: "832"}, + "JM": {Name: "Jamaica", ISOAlpha3: "JAM", ISOAlpha2: "JM", Code: "388"}, + "JO": {Name: "Jordan", ISOAlpha3: "JOR", ISOAlpha2: "JO", Code: "400"}, + "JP": {Name: "Japan", ISOAlpha3: "JPN", ISOAlpha2: "JP", Code: "392"}, + "KE": {Name: "Kenya", ISOAlpha3: "KEN", ISOAlpha2: "KE", Code: "404"}, + "KG": {Name: "Kyrgyzstan", ISOAlpha3: "KGZ", ISOAlpha2: "KG", Code: "417"}, + "KH": {Name: "Cambodia", ISOAlpha3: "KHM", ISOAlpha2: "KH", Code: "116"}, + "KI": {Name: "Kiribati", ISOAlpha3: "KIR", ISOAlpha2: "KI", Code: "296"}, + "KM": {Name: "Comoros", ISOAlpha3: "COM", ISOAlpha2: "KM", Code: "174"}, + "KN": {Name: "Saint Kitts and Nevis", ISOAlpha3: "KNA", ISOAlpha2: "KN", Code: "659"}, + "KP": {Name: "Korea (Democratic People's Republic of)", ISOAlpha3: "PRK", ISOAlpha2: "KP", Code: "408"}, + "KR": {Name: "Korea, Republic of", ISOAlpha3: "KOR", ISOAlpha2: "KR", Code: "410"}, + "KW": {Name: "Kuwait", ISOAlpha3: "KWT", ISOAlpha2: "KW", Code: "414"}, + "KY": {Name: "Cayman Islands", ISOAlpha3: "CYM", ISOAlpha2: "KY", Code: "136"}, + "KZ": {Name: "Kazakhstan", ISOAlpha3: "KAZ", ISOAlpha2: "KZ", Code: "398"}, + "LA": {Name: "Lao People's Democratic Republic", ISOAlpha3: "LAO", ISOAlpha2: "LA", Code: "418"}, + "LB": {Name: "Lebanon", ISOAlpha3: "LBN", ISOAlpha2: "LB", Code: "422"}, + "LC": {Name: "Saint Lucia", ISOAlpha3: "LCA", ISOAlpha2: "LC", Code: "662"}, + "LI": {Name: "Liechtenstein", ISOAlpha3: "LIE", ISOAlpha2: "LI", Code: "438"}, + "LK": {Name: "Sri Lanka", ISOAlpha3: "LKA", ISOAlpha2: "LK", Code: "144"}, + "LR": {Name: "Liberia", ISOAlpha3: "LBR", ISOAlpha2: "LR", Code: "430"}, + "LS": {Name: "Lesotho", ISOAlpha3: "LSO", ISOAlpha2: "LS", Code: "426"}, + "LT": {Name: "Lithuania", ISOAlpha3: "LTU", ISOAlpha2: "LT", Code: "440"}, + "LU": {Name: "Luxembourg", ISOAlpha3: "LUX", ISOAlpha2: "LU", Code: "442"}, + "LV": {Name: "Latvia", ISOAlpha3: "LVA", ISOAlpha2: "LV", Code: "428"}, + "LY": {Name: "Libya", ISOAlpha3: "LBY", ISOAlpha2: "LY", Code: "434"}, + "MA": {Name: "Morocco", ISOAlpha3: "MAR", ISOAlpha2: "MA", Code: "504"}, + "MC": {Name: "Monaco", ISOAlpha3: "MCO", ISOAlpha2: "MC", Code: "492"}, + "MD": {Name: "Moldova, Republic of", ISOAlpha3: "MDA", ISOAlpha2: "MD", Code: "498"}, + "ME": {Name: "Montenegro", ISOAlpha3: "MNE", ISOAlpha2: "ME", Code: "499"}, + "MF": {Name: "Saint Martin (French part)", ISOAlpha3: "MAF", ISOAlpha2: "MF", Code: "663"}, + "MG": {Name: "Madagascar", ISOAlpha3: "MDG", ISOAlpha2: "MG", Code: "450"}, + "MH": {Name: "Marshall Islands", ISOAlpha3: "MHL", ISOAlpha2: "MH", Code: "584"}, + "MK": {Name: "North Macedonia", ISOAlpha3: "MKD", ISOAlpha2: "MK", Code: "807"}, + "ML": {Name: "Mali", ISOAlpha3: "MLI", ISOAlpha2: "ML", Code: "466"}, + "MM": {Name: "Myanmar", ISOAlpha3: "MMR", ISOAlpha2: "MM", Code: "104"}, + "MN": {Name: "Mongolia", ISOAlpha3: "MNG", ISOAlpha2: "MN", Code: "496"}, + "MO": {Name: "Macao", ISOAlpha3: "MAC", ISOAlpha2: "MO", Code: "446"}, + "MP": {Name: "Northern Mariana Islands", ISOAlpha3: "MNP", ISOAlpha2: "MP", Code: "580"}, + "MQ": {Name: "Martinique", ISOAlpha3: "MTQ", ISOAlpha2: "MQ", Code: "474"}, + "MR": {Name: "Mauritania", ISOAlpha3: "MRT", ISOAlpha2: "MR", Code: "478"}, + "MS": {Name: "Montserrat", ISOAlpha3: "MSR", ISOAlpha2: "MS", Code: "500"}, + "MT": {Name: "Malta", ISOAlpha3: "MLT", ISOAlpha2: "MT", Code: "470"}, + "MU": {Name: "Mauritius", ISOAlpha3: "MUS", ISOAlpha2: "MU", Code: "480"}, + "MV": {Name: "Maldives", ISOAlpha3: "MDV", ISOAlpha2: "MV", Code: "462"}, + "MW": {Name: "Malawi", ISOAlpha3: "MWI", ISOAlpha2: "MW", Code: "454"}, + "MX": {Name: "Mexico", ISOAlpha3: "MEX", ISOAlpha2: "MX", Code: "484"}, + "MY": {Name: "Malaysia", ISOAlpha3: "MYS", ISOAlpha2: "MY", Code: "458"}, + "MZ": {Name: "Mozambique", ISOAlpha3: "MOZ", ISOAlpha2: "MZ", Code: "508"}, + "NA": {Name: "Namibia", ISOAlpha3: "NAM", ISOAlpha2: "NA", Code: "516"}, + "NC": {Name: "New Caledonia", ISOAlpha3: "NCL", ISOAlpha2: "NC", Code: "540"}, + "NE": {Name: "Niger", ISOAlpha3: "NER", ISOAlpha2: "NE", Code: "562"}, + "NF": {Name: "Norfolk Island", ISOAlpha3: "NFK", ISOAlpha2: "NF", Code: "574"}, + "NG": {Name: "Nigeria", ISOAlpha3: "NGA", ISOAlpha2: "NG", Code: "566"}, + "NI": {Name: "Nicaragua", ISOAlpha3: "NIC", ISOAlpha2: "NI", Code: "558"}, + "NL": {Name: "Netherlands", ISOAlpha3: "NLD", ISOAlpha2: "NL", Code: "528"}, + "NO": {Name: "Norway", ISOAlpha3: "NOR", ISOAlpha2: "NO", Code: "578"}, + "NP": {Name: "Nepal", ISOAlpha3: "NPL", ISOAlpha2: "NP", Code: "524"}, + "NR": {Name: "Nauru", ISOAlpha3: "NRU", ISOAlpha2: "NR", Code: "520"}, + "NU": {Name: "Niue", ISOAlpha3: "NIU", ISOAlpha2: "NU", Code: "570"}, + "NZ": {Name: "New Zealand", ISOAlpha3: "NZL", ISOAlpha2: "NZ", Code: "554"}, + "OM": {Name: "Oman", ISOAlpha3: "OMN", ISOAlpha2: "OM", Code: "512"}, + "PA": {Name: "Panama", ISOAlpha3: "PAN", ISOAlpha2: "PA", Code: "591"}, + "PE": {Name: "Peru", ISOAlpha3: "PER", ISOAlpha2: "PE", Code: "604"}, + "PF": {Name: "French Polynesia", ISOAlpha3: "PYF", ISOAlpha2: "PF", Code: "258"}, + "PG": {Name: "Papua New Guinea", ISOAlpha3: "PNG", ISOAlpha2: "PG", Code: "598"}, + "PH": {Name: "Philippines", ISOAlpha3: "PHL", ISOAlpha2: "PH", Code: "608"}, + "PK": {Name: "Pakistan", ISOAlpha3: "PAK", ISOAlpha2: "PK", Code: "586"}, + "PL": {Name: "Poland", ISOAlpha3: "POL", ISOAlpha2: "PL", Code: "616"}, + "PM": {Name: "Saint Pierre and Miquelon", ISOAlpha3: "SPM", ISOAlpha2: "PM", Code: "666"}, + "PN": {Name: "Pitcairn", ISOAlpha3: "PCN", ISOAlpha2: "PN", Code: "612"}, + "PR": {Name: "Puerto Rico", ISOAlpha3: "PRI", ISOAlpha2: "PR", Code: "630"}, + "PS": {Name: "Palestine, State of", ISOAlpha3: "PSE", ISOAlpha2: "PS", Code: "275"}, + "PT": {Name: "Portugal", ISOAlpha3: "PRT", ISOAlpha2: "PT", Code: "620"}, + "PW": {Name: "Palau", ISOAlpha3: "PLW", ISOAlpha2: "PW", Code: "585"}, + "PY": {Name: "Paraguay", ISOAlpha3: "PRY", ISOAlpha2: "PY", Code: "600"}, + "QA": {Name: "Qatar", ISOAlpha3: "QAT", ISOAlpha2: "QA", Code: "634"}, + "RE": {Name: "Réunion", ISOAlpha3: "REU", ISOAlpha2: "RE", Code: "638"}, + "RO": {Name: "Romania", ISOAlpha3: "ROU", ISOAlpha2: "RO", Code: "642"}, + "RS": {Name: "Serbia", ISOAlpha3: "SRB", ISOAlpha2: "RS", Code: "688"}, + "RU": {Name: "Russian Federation", ISOAlpha3: "RUS", ISOAlpha2: "RU", Code: "643"}, + "RW": {Name: "Rwanda", ISOAlpha3: "RWA", ISOAlpha2: "RW", Code: "646"}, + "SA": {Name: "Saudi Arabia", ISOAlpha3: "SAU", ISOAlpha2: "SA", Code: "682"}, + "SB": {Name: "Solomon Islands", ISOAlpha3: "SLB", ISOAlpha2: "SB", Code: "090"}, + "SC": {Name: "Seychelles", ISOAlpha3: "SYC", ISOAlpha2: "SC", Code: "690"}, + "SD": {Name: "Sudan", ISOAlpha3: "SDN", ISOAlpha2: "SD", Code: "729"}, + "SE": {Name: "Sweden", ISOAlpha3: "SWE", ISOAlpha2: "SE", Code: "752"}, + "SG": {Name: "Singapore", ISOAlpha3: "SGP", ISOAlpha2: "SG", Code: "702"}, + "SH": {Name: "Saint Helena, Ascension and Tristan da Cunha", ISOAlpha3: "SHN", ISOAlpha2: "SH", Code: "654"}, + "SI": {Name: "Slovenia", ISOAlpha3: "SVN", ISOAlpha2: "SI", Code: "705"}, + "SJ": {Name: "Svalbard and Jan Mayen", ISOAlpha3: "SJM", ISOAlpha2: "SJ", Code: "744"}, + "SK": {Name: "Slovakia", ISOAlpha3: "SVK", ISOAlpha2: "SK", Code: "703"}, + "SL": {Name: "Sierra Leone", ISOAlpha3: "SLE", ISOAlpha2: "SL", Code: "694"}, + "SM": {Name: "San Marino", ISOAlpha3: "SMR", ISOAlpha2: "SM", Code: "674"}, + "SN": {Name: "Senegal", ISOAlpha3: "SEN", ISOAlpha2: "SN", Code: "686"}, + "SO": {Name: "Somalia", ISOAlpha3: "SOM", ISOAlpha2: "SO", Code: "706"}, + "SR": {Name: "Suriname", ISOAlpha3: "SUR", ISOAlpha2: "SR", Code: "740"}, + "SS": {Name: "South Sudan", ISOAlpha3: "SSD", ISOAlpha2: "SS", Code: "728"}, + "ST": {Name: "Sao Tome and Principe", ISOAlpha3: "STP", ISOAlpha2: "ST", Code: "678"}, + "SV": {Name: "El Salvador", ISOAlpha3: "SLV", ISOAlpha2: "SV", Code: "222"}, + "SX": {Name: "Sint Maarten (Dutch part)", ISOAlpha3: "SXM", ISOAlpha2: "SX", Code: "534"}, + "SY": {Name: "Syrian Arab Republic", ISOAlpha3: "SYR", ISOAlpha2: "SY", Code: "760"}, + "SZ": {Name: "Eswatini", ISOAlpha3: "SWZ", ISOAlpha2: "SZ", Code: "748"}, + "TC": {Name: "Turks and Caicos Islands", ISOAlpha3: "TCA", ISOAlpha2: "TC", Code: "796"}, + "TD": {Name: "Chad", ISOAlpha3: "TCD", ISOAlpha2: "TD", Code: "148"}, + "TF": {Name: "French Southern Territories", ISOAlpha3: "ATF", ISOAlpha2: "TF", Code: "260"}, + "TG": {Name: "Togo", ISOAlpha3: "TGO", ISOAlpha2: "TG", Code: "768"}, + "TH": {Name: "Thailand", ISOAlpha3: "THA", ISOAlpha2: "TH", Code: "764"}, + "TJ": {Name: "Tajikistan", ISOAlpha3: "TJK", ISOAlpha2: "TJ", Code: "762"}, + "TK": {Name: "Tokelau", ISOAlpha3: "TKL", ISOAlpha2: "TK", Code: "772"}, + "TL": {Name: "Timor-Leste", ISOAlpha3: "TLS", ISOAlpha2: "TL", Code: "626"}, + "TM": {Name: "Turkmenistan", ISOAlpha3: "TKM", ISOAlpha2: "TM", Code: "795"}, + "TN": {Name: "Tunisia", ISOAlpha3: "TUN", ISOAlpha2: "TN", Code: "788"}, + "TO": {Name: "Tonga", ISOAlpha3: "TON", ISOAlpha2: "TO", Code: "776"}, + "TR": {Name: "Turkey", ISOAlpha3: "TUR", ISOAlpha2: "TR", Code: "792"}, + "TT": {Name: "Trinidad and Tobago", ISOAlpha3: "TTO", ISOAlpha2: "TT", Code: "780"}, + "TV": {Name: "Tuvalu", ISOAlpha3: "TUV", ISOAlpha2: "TV", Code: "798"}, + "TW": {Name: "Taiwan, Province of China", ISOAlpha3: "TWN", ISOAlpha2: "TW", Code: "158"}, + "TZ": {Name: "Tanzania, United Republic of", ISOAlpha3: "TZA", ISOAlpha2: "TZ", Code: "834"}, + "UA": {Name: "Ukraine", ISOAlpha3: "UKR", ISOAlpha2: "UA", Code: "804"}, + "UG": {Name: "Uganda", ISOAlpha3: "UGA", ISOAlpha2: "UG", Code: "800"}, + "UM": {Name: "United States Minor Outlying Islands", ISOAlpha3: "UMI", ISOAlpha2: "UM", Code: "581"}, + "US": {Name: "United States of America", ISOAlpha3: "USA", ISOAlpha2: "US", Code: "840"}, + "UY": {Name: "Uruguay", ISOAlpha3: "URY", ISOAlpha2: "UY", Code: "858"}, + "UZ": {Name: "Uzbekistan", ISOAlpha3: "UZB", ISOAlpha2: "UZ", Code: "860"}, + "VA": {Name: "Holy See", ISOAlpha3: "VAT", ISOAlpha2: "VA", Code: "336"}, + "VC": {Name: "Saint Vincent and the Grenadines", ISOAlpha3: "VCT", ISOAlpha2: "VC", Code: "670"}, + "VE": {Name: "Venezuela (Bolivarian Republic of)", ISOAlpha3: "VEN", ISOAlpha2: "VE", Code: "862"}, + "VG": {Name: "Virgin Islands (British)", ISOAlpha3: "VGB", ISOAlpha2: "VG", Code: "092"}, + "VI": {Name: "Virgin Islands (U.S.)", ISOAlpha3: "VIR", ISOAlpha2: "VI", Code: "850"}, + "VN": {Name: "Viet Nam", ISOAlpha3: "VNM", ISOAlpha2: "VN", Code: "704"}, + "VU": {Name: "Vanuatu", ISOAlpha3: "VUT", ISOAlpha2: "VU", Code: "548"}, + "WF": {Name: "Wallis and Futuna", ISOAlpha3: "WLF", ISOAlpha2: "WF", Code: "876"}, + "WS": {Name: "Samoa", ISOAlpha3: "WSM", ISOAlpha2: "WS", Code: "882"}, + "YE": {Name: "Yemen", ISOAlpha3: "YEM", ISOAlpha2: "YE", Code: "887"}, + "YT": {Name: "Mayotte", ISOAlpha3: "MYT", ISOAlpha2: "YT", Code: "175"}, + "ZA": {Name: "South Africa", ISOAlpha3: "ZAF", ISOAlpha2: "ZA", Code: "710"}, + "ZM": {Name: "Zambia", ISOAlpha3: "ZMB", ISOAlpha2: "ZM", Code: "894"}, + "ZW": {Name: "Zimbabwe", ISOAlpha3: "ZWE", ISOAlpha2: "ZW", Code: "716"}, +} diff --git a/vendor/github.com/go-openapi/strfmt/internal/countries/country.go b/vendor/github.com/go-openapi/strfmt/internal/countries/country.go new file mode 100644 index 00000000000..774051430eb --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/internal/countries/country.go @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +//go:generate go run gen.go -- countries.go +package countries + +// Country identifies a country with its english name, and ISO3166 codes. +// +//nolint:tagliatelle // JSON tags mirror the iso3166.json source keys (alpha-3, alpha-2, country-code); renaming them breaks the embedded-JSON unmarshal. +type Country struct { + Name string `json:"name"` + ISOAlpha3 string `json:"alpha-3"` + ISOAlpha2 string `json:"alpha-2"` + Code string `json:"country-code"` +} diff --git a/vendor/github.com/go-openapi/strfmt/internal/countries/iso3166.json b/vendor/github.com/go-openapi/strfmt/internal/countries/iso3166.json new file mode 100644 index 00000000000..b2c0b5c5017 --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/internal/countries/iso3166.json @@ -0,0 +1,251 @@ +[ +{"name":"Afghanistan","alpha-2":"AF","alpha-3":"AFG","country-code":"004","iso_3166-2":"ISO 3166-2:AF","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Åland Islands","alpha-2":"AX","alpha-3":"ALA","country-code":"248","iso_3166-2":"ISO 3166-2:AX","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Albania","alpha-2":"AL","alpha-3":"ALB","country-code":"008","iso_3166-2":"ISO 3166-2:AL","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Algeria","alpha-2":"DZ","alpha-3":"DZA","country-code":"012","iso_3166-2":"ISO 3166-2:DZ","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"American Samoa","alpha-2":"AS","alpha-3":"ASM","country-code":"016","iso_3166-2":"ISO 3166-2:AS","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Andorra","alpha-2":"AD","alpha-3":"AND","country-code":"020","iso_3166-2":"ISO 3166-2:AD","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Angola","alpha-2":"AO","alpha-3":"AGO","country-code":"024","iso_3166-2":"ISO 3166-2:AO","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Anguilla","alpha-2":"AI","alpha-3":"AIA","country-code":"660","iso_3166-2":"ISO 3166-2:AI","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Antarctica","alpha-2":"AQ","alpha-3":"ATA","country-code":"010","iso_3166-2":"ISO 3166-2:AQ","region":"","sub-region":"","intermediate-region":"","region-code":"","sub-region-code":"","intermediate-region-code":""}, +{"name":"Antigua and Barbuda","alpha-2":"AG","alpha-3":"ATG","country-code":"028","iso_3166-2":"ISO 3166-2:AG","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Argentina","alpha-2":"AR","alpha-3":"ARG","country-code":"032","iso_3166-2":"ISO 3166-2:AR","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Armenia","alpha-2":"AM","alpha-3":"ARM","country-code":"051","iso_3166-2":"ISO 3166-2:AM","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Aruba","alpha-2":"AW","alpha-3":"ABW","country-code":"533","iso_3166-2":"ISO 3166-2:AW","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Australia","alpha-2":"AU","alpha-3":"AUS","country-code":"036","iso_3166-2":"ISO 3166-2:AU","region":"Oceania","sub-region":"Australia and New Zealand","intermediate-region":"","region-code":"009","sub-region-code":"053","intermediate-region-code":""}, +{"name":"Austria","alpha-2":"AT","alpha-3":"AUT","country-code":"040","iso_3166-2":"ISO 3166-2:AT","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Azerbaijan","alpha-2":"AZ","alpha-3":"AZE","country-code":"031","iso_3166-2":"ISO 3166-2:AZ","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Bahamas","alpha-2":"BS","alpha-3":"BHS","country-code":"044","iso_3166-2":"ISO 3166-2:BS","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Bahrain","alpha-2":"BH","alpha-3":"BHR","country-code":"048","iso_3166-2":"ISO 3166-2:BH","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Bangladesh","alpha-2":"BD","alpha-3":"BGD","country-code":"050","iso_3166-2":"ISO 3166-2:BD","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Barbados","alpha-2":"BB","alpha-3":"BRB","country-code":"052","iso_3166-2":"ISO 3166-2:BB","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Belarus","alpha-2":"BY","alpha-3":"BLR","country-code":"112","iso_3166-2":"ISO 3166-2:BY","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Belgium","alpha-2":"BE","alpha-3":"BEL","country-code":"056","iso_3166-2":"ISO 3166-2:BE","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Belize","alpha-2":"BZ","alpha-3":"BLZ","country-code":"084","iso_3166-2":"ISO 3166-2:BZ","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Benin","alpha-2":"BJ","alpha-3":"BEN","country-code":"204","iso_3166-2":"ISO 3166-2:BJ","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Bermuda","alpha-2":"BM","alpha-3":"BMU","country-code":"060","iso_3166-2":"ISO 3166-2:BM","region":"Americas","sub-region":"Northern America","intermediate-region":"","region-code":"019","sub-region-code":"021","intermediate-region-code":""}, +{"name":"Bhutan","alpha-2":"BT","alpha-3":"BTN","country-code":"064","iso_3166-2":"ISO 3166-2:BT","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Bolivia (Plurinational State of)","alpha-2":"BO","alpha-3":"BOL","country-code":"068","iso_3166-2":"ISO 3166-2:BO","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Bonaire, Sint Eustatius and Saba","alpha-2":"BQ","alpha-3":"BES","country-code":"535","iso_3166-2":"ISO 3166-2:BQ","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Bosnia and Herzegovina","alpha-2":"BA","alpha-3":"BIH","country-code":"070","iso_3166-2":"ISO 3166-2:BA","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Botswana","alpha-2":"BW","alpha-3":"BWA","country-code":"072","iso_3166-2":"ISO 3166-2:BW","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Southern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"018"}, +{"name":"Bouvet Island","alpha-2":"BV","alpha-3":"BVT","country-code":"074","iso_3166-2":"ISO 3166-2:BV","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Brazil","alpha-2":"BR","alpha-3":"BRA","country-code":"076","iso_3166-2":"ISO 3166-2:BR","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"British Indian Ocean Territory","alpha-2":"IO","alpha-3":"IOT","country-code":"086","iso_3166-2":"ISO 3166-2:IO","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Brunei Darussalam","alpha-2":"BN","alpha-3":"BRN","country-code":"096","iso_3166-2":"ISO 3166-2:BN","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Bulgaria","alpha-2":"BG","alpha-3":"BGR","country-code":"100","iso_3166-2":"ISO 3166-2:BG","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Burkina Faso","alpha-2":"BF","alpha-3":"BFA","country-code":"854","iso_3166-2":"ISO 3166-2:BF","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Burundi","alpha-2":"BI","alpha-3":"BDI","country-code":"108","iso_3166-2":"ISO 3166-2:BI","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Cabo Verde","alpha-2":"CV","alpha-3":"CPV","country-code":"132","iso_3166-2":"ISO 3166-2:CV","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Cambodia","alpha-2":"KH","alpha-3":"KHM","country-code":"116","iso_3166-2":"ISO 3166-2:KH","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Cameroon","alpha-2":"CM","alpha-3":"CMR","country-code":"120","iso_3166-2":"ISO 3166-2:CM","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Canada","alpha-2":"CA","alpha-3":"CAN","country-code":"124","iso_3166-2":"ISO 3166-2:CA","region":"Americas","sub-region":"Northern America","intermediate-region":"","region-code":"019","sub-region-code":"021","intermediate-region-code":""}, +{"name":"Cayman Islands","alpha-2":"KY","alpha-3":"CYM","country-code":"136","iso_3166-2":"ISO 3166-2:KY","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Central African Republic","alpha-2":"CF","alpha-3":"CAF","country-code":"140","iso_3166-2":"ISO 3166-2:CF","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Chad","alpha-2":"TD","alpha-3":"TCD","country-code":"148","iso_3166-2":"ISO 3166-2:TD","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Chile","alpha-2":"CL","alpha-3":"CHL","country-code":"152","iso_3166-2":"ISO 3166-2:CL","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"China","alpha-2":"CN","alpha-3":"CHN","country-code":"156","iso_3166-2":"ISO 3166-2:CN","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Christmas Island","alpha-2":"CX","alpha-3":"CXR","country-code":"162","iso_3166-2":"ISO 3166-2:CX","region":"Oceania","sub-region":"Australia and New Zealand","intermediate-region":"","region-code":"009","sub-region-code":"053","intermediate-region-code":""}, +{"name":"Cocos (Keeling) Islands","alpha-2":"CC","alpha-3":"CCK","country-code":"166","iso_3166-2":"ISO 3166-2:CC","region":"Oceania","sub-region":"Australia and New Zealand","intermediate-region":"","region-code":"009","sub-region-code":"053","intermediate-region-code":""}, +{"name":"Colombia","alpha-2":"CO","alpha-3":"COL","country-code":"170","iso_3166-2":"ISO 3166-2:CO","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Comoros","alpha-2":"KM","alpha-3":"COM","country-code":"174","iso_3166-2":"ISO 3166-2:KM","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Congo","alpha-2":"CG","alpha-3":"COG","country-code":"178","iso_3166-2":"ISO 3166-2:CG","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Congo, Democratic Republic of the","alpha-2":"CD","alpha-3":"COD","country-code":"180","iso_3166-2":"ISO 3166-2:CD","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Cook Islands","alpha-2":"CK","alpha-3":"COK","country-code":"184","iso_3166-2":"ISO 3166-2:CK","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Costa Rica","alpha-2":"CR","alpha-3":"CRI","country-code":"188","iso_3166-2":"ISO 3166-2:CR","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Côte d'Ivoire","alpha-2":"CI","alpha-3":"CIV","country-code":"384","iso_3166-2":"ISO 3166-2:CI","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Croatia","alpha-2":"HR","alpha-3":"HRV","country-code":"191","iso_3166-2":"ISO 3166-2:HR","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Cuba","alpha-2":"CU","alpha-3":"CUB","country-code":"192","iso_3166-2":"ISO 3166-2:CU","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Curaçao","alpha-2":"CW","alpha-3":"CUW","country-code":"531","iso_3166-2":"ISO 3166-2:CW","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Cyprus","alpha-2":"CY","alpha-3":"CYP","country-code":"196","iso_3166-2":"ISO 3166-2:CY","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Czechia","alpha-2":"CZ","alpha-3":"CZE","country-code":"203","iso_3166-2":"ISO 3166-2:CZ","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Denmark","alpha-2":"DK","alpha-3":"DNK","country-code":"208","iso_3166-2":"ISO 3166-2:DK","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Djibouti","alpha-2":"DJ","alpha-3":"DJI","country-code":"262","iso_3166-2":"ISO 3166-2:DJ","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Dominica","alpha-2":"DM","alpha-3":"DMA","country-code":"212","iso_3166-2":"ISO 3166-2:DM","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Dominican Republic","alpha-2":"DO","alpha-3":"DOM","country-code":"214","iso_3166-2":"ISO 3166-2:DO","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Ecuador","alpha-2":"EC","alpha-3":"ECU","country-code":"218","iso_3166-2":"ISO 3166-2:EC","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Egypt","alpha-2":"EG","alpha-3":"EGY","country-code":"818","iso_3166-2":"ISO 3166-2:EG","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"El Salvador","alpha-2":"SV","alpha-3":"SLV","country-code":"222","iso_3166-2":"ISO 3166-2:SV","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Equatorial Guinea","alpha-2":"GQ","alpha-3":"GNQ","country-code":"226","iso_3166-2":"ISO 3166-2:GQ","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Eritrea","alpha-2":"ER","alpha-3":"ERI","country-code":"232","iso_3166-2":"ISO 3166-2:ER","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Estonia","alpha-2":"EE","alpha-3":"EST","country-code":"233","iso_3166-2":"ISO 3166-2:EE","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Eswatini","alpha-2":"SZ","alpha-3":"SWZ","country-code":"748","iso_3166-2":"ISO 3166-2:SZ","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Southern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"018"}, +{"name":"Ethiopia","alpha-2":"ET","alpha-3":"ETH","country-code":"231","iso_3166-2":"ISO 3166-2:ET","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Falkland Islands (Malvinas)","alpha-2":"FK","alpha-3":"FLK","country-code":"238","iso_3166-2":"ISO 3166-2:FK","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Faroe Islands","alpha-2":"FO","alpha-3":"FRO","country-code":"234","iso_3166-2":"ISO 3166-2:FO","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Fiji","alpha-2":"FJ","alpha-3":"FJI","country-code":"242","iso_3166-2":"ISO 3166-2:FJ","region":"Oceania","sub-region":"Melanesia","intermediate-region":"","region-code":"009","sub-region-code":"054","intermediate-region-code":""}, +{"name":"Finland","alpha-2":"FI","alpha-3":"FIN","country-code":"246","iso_3166-2":"ISO 3166-2:FI","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"France","alpha-2":"FR","alpha-3":"FRA","country-code":"250","iso_3166-2":"ISO 3166-2:FR","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"French Guiana","alpha-2":"GF","alpha-3":"GUF","country-code":"254","iso_3166-2":"ISO 3166-2:GF","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"French Polynesia","alpha-2":"PF","alpha-3":"PYF","country-code":"258","iso_3166-2":"ISO 3166-2:PF","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"French Southern Territories","alpha-2":"TF","alpha-3":"ATF","country-code":"260","iso_3166-2":"ISO 3166-2:TF","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Gabon","alpha-2":"GA","alpha-3":"GAB","country-code":"266","iso_3166-2":"ISO 3166-2:GA","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Gambia","alpha-2":"GM","alpha-3":"GMB","country-code":"270","iso_3166-2":"ISO 3166-2:GM","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Georgia","alpha-2":"GE","alpha-3":"GEO","country-code":"268","iso_3166-2":"ISO 3166-2:GE","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Germany","alpha-2":"DE","alpha-3":"DEU","country-code":"276","iso_3166-2":"ISO 3166-2:DE","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Ghana","alpha-2":"GH","alpha-3":"GHA","country-code":"288","iso_3166-2":"ISO 3166-2:GH","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Gibraltar","alpha-2":"GI","alpha-3":"GIB","country-code":"292","iso_3166-2":"ISO 3166-2:GI","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Greece","alpha-2":"GR","alpha-3":"GRC","country-code":"300","iso_3166-2":"ISO 3166-2:GR","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Greenland","alpha-2":"GL","alpha-3":"GRL","country-code":"304","iso_3166-2":"ISO 3166-2:GL","region":"Americas","sub-region":"Northern America","intermediate-region":"","region-code":"019","sub-region-code":"021","intermediate-region-code":""}, +{"name":"Grenada","alpha-2":"GD","alpha-3":"GRD","country-code":"308","iso_3166-2":"ISO 3166-2:GD","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Guadeloupe","alpha-2":"GP","alpha-3":"GLP","country-code":"312","iso_3166-2":"ISO 3166-2:GP","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Guam","alpha-2":"GU","alpha-3":"GUM","country-code":"316","iso_3166-2":"ISO 3166-2:GU","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Guatemala","alpha-2":"GT","alpha-3":"GTM","country-code":"320","iso_3166-2":"ISO 3166-2:GT","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Guernsey","alpha-2":"GG","alpha-3":"GGY","country-code":"831","iso_3166-2":"ISO 3166-2:GG","region":"Europe","sub-region":"Northern Europe","intermediate-region":"Channel Islands","region-code":"150","sub-region-code":"154","intermediate-region-code":"830"}, +{"name":"Guinea","alpha-2":"GN","alpha-3":"GIN","country-code":"324","iso_3166-2":"ISO 3166-2:GN","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Guinea-Bissau","alpha-2":"GW","alpha-3":"GNB","country-code":"624","iso_3166-2":"ISO 3166-2:GW","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Guyana","alpha-2":"GY","alpha-3":"GUY","country-code":"328","iso_3166-2":"ISO 3166-2:GY","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Haiti","alpha-2":"HT","alpha-3":"HTI","country-code":"332","iso_3166-2":"ISO 3166-2:HT","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Heard Island and McDonald Islands","alpha-2":"HM","alpha-3":"HMD","country-code":"334","iso_3166-2":"ISO 3166-2:HM","region":"Oceania","sub-region":"Australia and New Zealand","intermediate-region":"","region-code":"009","sub-region-code":"053","intermediate-region-code":""}, +{"name":"Holy See","alpha-2":"VA","alpha-3":"VAT","country-code":"336","iso_3166-2":"ISO 3166-2:VA","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Honduras","alpha-2":"HN","alpha-3":"HND","country-code":"340","iso_3166-2":"ISO 3166-2:HN","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Hong Kong","alpha-2":"HK","alpha-3":"HKG","country-code":"344","iso_3166-2":"ISO 3166-2:HK","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Hungary","alpha-2":"HU","alpha-3":"HUN","country-code":"348","iso_3166-2":"ISO 3166-2:HU","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Iceland","alpha-2":"IS","alpha-3":"ISL","country-code":"352","iso_3166-2":"ISO 3166-2:IS","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"India","alpha-2":"IN","alpha-3":"IND","country-code":"356","iso_3166-2":"ISO 3166-2:IN","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Indonesia","alpha-2":"ID","alpha-3":"IDN","country-code":"360","iso_3166-2":"ISO 3166-2:ID","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Iran (Islamic Republic of)","alpha-2":"IR","alpha-3":"IRN","country-code":"364","iso_3166-2":"ISO 3166-2:IR","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Iraq","alpha-2":"IQ","alpha-3":"IRQ","country-code":"368","iso_3166-2":"ISO 3166-2:IQ","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Ireland","alpha-2":"IE","alpha-3":"IRL","country-code":"372","iso_3166-2":"ISO 3166-2:IE","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Isle of Man","alpha-2":"IM","alpha-3":"IMN","country-code":"833","iso_3166-2":"ISO 3166-2:IM","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Israel","alpha-2":"IL","alpha-3":"ISR","country-code":"376","iso_3166-2":"ISO 3166-2:IL","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Italy","alpha-2":"IT","alpha-3":"ITA","country-code":"380","iso_3166-2":"ISO 3166-2:IT","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Jamaica","alpha-2":"JM","alpha-3":"JAM","country-code":"388","iso_3166-2":"ISO 3166-2:JM","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Japan","alpha-2":"JP","alpha-3":"JPN","country-code":"392","iso_3166-2":"ISO 3166-2:JP","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Jersey","alpha-2":"JE","alpha-3":"JEY","country-code":"832","iso_3166-2":"ISO 3166-2:JE","region":"Europe","sub-region":"Northern Europe","intermediate-region":"Channel Islands","region-code":"150","sub-region-code":"154","intermediate-region-code":"830"}, +{"name":"Jordan","alpha-2":"JO","alpha-3":"JOR","country-code":"400","iso_3166-2":"ISO 3166-2:JO","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Kazakhstan","alpha-2":"KZ","alpha-3":"KAZ","country-code":"398","iso_3166-2":"ISO 3166-2:KZ","region":"Asia","sub-region":"Central Asia","intermediate-region":"","region-code":"142","sub-region-code":"143","intermediate-region-code":""}, +{"name":"Kenya","alpha-2":"KE","alpha-3":"KEN","country-code":"404","iso_3166-2":"ISO 3166-2:KE","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Kiribati","alpha-2":"KI","alpha-3":"KIR","country-code":"296","iso_3166-2":"ISO 3166-2:KI","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Korea (Democratic People's Republic of)","alpha-2":"KP","alpha-3":"PRK","country-code":"408","iso_3166-2":"ISO 3166-2:KP","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Korea, Republic of","alpha-2":"KR","alpha-3":"KOR","country-code":"410","iso_3166-2":"ISO 3166-2:KR","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Kuwait","alpha-2":"KW","alpha-3":"KWT","country-code":"414","iso_3166-2":"ISO 3166-2:KW","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Kyrgyzstan","alpha-2":"KG","alpha-3":"KGZ","country-code":"417","iso_3166-2":"ISO 3166-2:KG","region":"Asia","sub-region":"Central Asia","intermediate-region":"","region-code":"142","sub-region-code":"143","intermediate-region-code":""}, +{"name":"Lao People's Democratic Republic","alpha-2":"LA","alpha-3":"LAO","country-code":"418","iso_3166-2":"ISO 3166-2:LA","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Latvia","alpha-2":"LV","alpha-3":"LVA","country-code":"428","iso_3166-2":"ISO 3166-2:LV","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Lebanon","alpha-2":"LB","alpha-3":"LBN","country-code":"422","iso_3166-2":"ISO 3166-2:LB","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Lesotho","alpha-2":"LS","alpha-3":"LSO","country-code":"426","iso_3166-2":"ISO 3166-2:LS","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Southern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"018"}, +{"name":"Liberia","alpha-2":"LR","alpha-3":"LBR","country-code":"430","iso_3166-2":"ISO 3166-2:LR","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Libya","alpha-2":"LY","alpha-3":"LBY","country-code":"434","iso_3166-2":"ISO 3166-2:LY","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"Liechtenstein","alpha-2":"LI","alpha-3":"LIE","country-code":"438","iso_3166-2":"ISO 3166-2:LI","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Lithuania","alpha-2":"LT","alpha-3":"LTU","country-code":"440","iso_3166-2":"ISO 3166-2:LT","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Luxembourg","alpha-2":"LU","alpha-3":"LUX","country-code":"442","iso_3166-2":"ISO 3166-2:LU","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Macao","alpha-2":"MO","alpha-3":"MAC","country-code":"446","iso_3166-2":"ISO 3166-2:MO","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Madagascar","alpha-2":"MG","alpha-3":"MDG","country-code":"450","iso_3166-2":"ISO 3166-2:MG","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Malawi","alpha-2":"MW","alpha-3":"MWI","country-code":"454","iso_3166-2":"ISO 3166-2:MW","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Malaysia","alpha-2":"MY","alpha-3":"MYS","country-code":"458","iso_3166-2":"ISO 3166-2:MY","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Maldives","alpha-2":"MV","alpha-3":"MDV","country-code":"462","iso_3166-2":"ISO 3166-2:MV","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Mali","alpha-2":"ML","alpha-3":"MLI","country-code":"466","iso_3166-2":"ISO 3166-2:ML","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Malta","alpha-2":"MT","alpha-3":"MLT","country-code":"470","iso_3166-2":"ISO 3166-2:MT","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Marshall Islands","alpha-2":"MH","alpha-3":"MHL","country-code":"584","iso_3166-2":"ISO 3166-2:MH","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Martinique","alpha-2":"MQ","alpha-3":"MTQ","country-code":"474","iso_3166-2":"ISO 3166-2:MQ","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Mauritania","alpha-2":"MR","alpha-3":"MRT","country-code":"478","iso_3166-2":"ISO 3166-2:MR","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Mauritius","alpha-2":"MU","alpha-3":"MUS","country-code":"480","iso_3166-2":"ISO 3166-2:MU","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Mayotte","alpha-2":"YT","alpha-3":"MYT","country-code":"175","iso_3166-2":"ISO 3166-2:YT","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Mexico","alpha-2":"MX","alpha-3":"MEX","country-code":"484","iso_3166-2":"ISO 3166-2:MX","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Micronesia (Federated States of)","alpha-2":"FM","alpha-3":"FSM","country-code":"583","iso_3166-2":"ISO 3166-2:FM","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Moldova, Republic of","alpha-2":"MD","alpha-3":"MDA","country-code":"498","iso_3166-2":"ISO 3166-2:MD","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Monaco","alpha-2":"MC","alpha-3":"MCO","country-code":"492","iso_3166-2":"ISO 3166-2:MC","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Mongolia","alpha-2":"MN","alpha-3":"MNG","country-code":"496","iso_3166-2":"ISO 3166-2:MN","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Montenegro","alpha-2":"ME","alpha-3":"MNE","country-code":"499","iso_3166-2":"ISO 3166-2:ME","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Montserrat","alpha-2":"MS","alpha-3":"MSR","country-code":"500","iso_3166-2":"ISO 3166-2:MS","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Morocco","alpha-2":"MA","alpha-3":"MAR","country-code":"504","iso_3166-2":"ISO 3166-2:MA","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"Mozambique","alpha-2":"MZ","alpha-3":"MOZ","country-code":"508","iso_3166-2":"ISO 3166-2:MZ","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Myanmar","alpha-2":"MM","alpha-3":"MMR","country-code":"104","iso_3166-2":"ISO 3166-2:MM","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Namibia","alpha-2":"NA","alpha-3":"NAM","country-code":"516","iso_3166-2":"ISO 3166-2:NA","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Southern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"018"}, +{"name":"Nauru","alpha-2":"NR","alpha-3":"NRU","country-code":"520","iso_3166-2":"ISO 3166-2:NR","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Nepal","alpha-2":"NP","alpha-3":"NPL","country-code":"524","iso_3166-2":"ISO 3166-2:NP","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Netherlands","alpha-2":"NL","alpha-3":"NLD","country-code":"528","iso_3166-2":"ISO 3166-2:NL","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"New Caledonia","alpha-2":"NC","alpha-3":"NCL","country-code":"540","iso_3166-2":"ISO 3166-2:NC","region":"Oceania","sub-region":"Melanesia","intermediate-region":"","region-code":"009","sub-region-code":"054","intermediate-region-code":""}, +{"name":"New Zealand","alpha-2":"NZ","alpha-3":"NZL","country-code":"554","iso_3166-2":"ISO 3166-2:NZ","region":"Oceania","sub-region":"Australia and New Zealand","intermediate-region":"","region-code":"009","sub-region-code":"053","intermediate-region-code":""}, +{"name":"Nicaragua","alpha-2":"NI","alpha-3":"NIC","country-code":"558","iso_3166-2":"ISO 3166-2:NI","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Niger","alpha-2":"NE","alpha-3":"NER","country-code":"562","iso_3166-2":"ISO 3166-2:NE","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Nigeria","alpha-2":"NG","alpha-3":"NGA","country-code":"566","iso_3166-2":"ISO 3166-2:NG","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Niue","alpha-2":"NU","alpha-3":"NIU","country-code":"570","iso_3166-2":"ISO 3166-2:NU","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Norfolk Island","alpha-2":"NF","alpha-3":"NFK","country-code":"574","iso_3166-2":"ISO 3166-2:NF","region":"Oceania","sub-region":"Australia and New Zealand","intermediate-region":"","region-code":"009","sub-region-code":"053","intermediate-region-code":""}, +{"name":"North Macedonia","alpha-2":"MK","alpha-3":"MKD","country-code":"807","iso_3166-2":"ISO 3166-2:MK","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Northern Mariana Islands","alpha-2":"MP","alpha-3":"MNP","country-code":"580","iso_3166-2":"ISO 3166-2:MP","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Norway","alpha-2":"NO","alpha-3":"NOR","country-code":"578","iso_3166-2":"ISO 3166-2:NO","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Oman","alpha-2":"OM","alpha-3":"OMN","country-code":"512","iso_3166-2":"ISO 3166-2:OM","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Pakistan","alpha-2":"PK","alpha-3":"PAK","country-code":"586","iso_3166-2":"ISO 3166-2:PK","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Palau","alpha-2":"PW","alpha-3":"PLW","country-code":"585","iso_3166-2":"ISO 3166-2:PW","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Palestine, State of","alpha-2":"PS","alpha-3":"PSE","country-code":"275","iso_3166-2":"ISO 3166-2:PS","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Panama","alpha-2":"PA","alpha-3":"PAN","country-code":"591","iso_3166-2":"ISO 3166-2:PA","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Central America","region-code":"019","sub-region-code":"419","intermediate-region-code":"013"}, +{"name":"Papua New Guinea","alpha-2":"PG","alpha-3":"PNG","country-code":"598","iso_3166-2":"ISO 3166-2:PG","region":"Oceania","sub-region":"Melanesia","intermediate-region":"","region-code":"009","sub-region-code":"054","intermediate-region-code":""}, +{"name":"Paraguay","alpha-2":"PY","alpha-3":"PRY","country-code":"600","iso_3166-2":"ISO 3166-2:PY","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Peru","alpha-2":"PE","alpha-3":"PER","country-code":"604","iso_3166-2":"ISO 3166-2:PE","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Philippines","alpha-2":"PH","alpha-3":"PHL","country-code":"608","iso_3166-2":"ISO 3166-2:PH","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Pitcairn","alpha-2":"PN","alpha-3":"PCN","country-code":"612","iso_3166-2":"ISO 3166-2:PN","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Poland","alpha-2":"PL","alpha-3":"POL","country-code":"616","iso_3166-2":"ISO 3166-2:PL","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Portugal","alpha-2":"PT","alpha-3":"PRT","country-code":"620","iso_3166-2":"ISO 3166-2:PT","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Puerto Rico","alpha-2":"PR","alpha-3":"PRI","country-code":"630","iso_3166-2":"ISO 3166-2:PR","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Qatar","alpha-2":"QA","alpha-3":"QAT","country-code":"634","iso_3166-2":"ISO 3166-2:QA","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Réunion","alpha-2":"RE","alpha-3":"REU","country-code":"638","iso_3166-2":"ISO 3166-2:RE","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Romania","alpha-2":"RO","alpha-3":"ROU","country-code":"642","iso_3166-2":"ISO 3166-2:RO","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Russian Federation","alpha-2":"RU","alpha-3":"RUS","country-code":"643","iso_3166-2":"ISO 3166-2:RU","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Rwanda","alpha-2":"RW","alpha-3":"RWA","country-code":"646","iso_3166-2":"ISO 3166-2:RW","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Saint Barthélemy","alpha-2":"BL","alpha-3":"BLM","country-code":"652","iso_3166-2":"ISO 3166-2:BL","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Saint Helena, Ascension and Tristan da Cunha","alpha-2":"SH","alpha-3":"SHN","country-code":"654","iso_3166-2":"ISO 3166-2:SH","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Saint Kitts and Nevis","alpha-2":"KN","alpha-3":"KNA","country-code":"659","iso_3166-2":"ISO 3166-2:KN","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Saint Lucia","alpha-2":"LC","alpha-3":"LCA","country-code":"662","iso_3166-2":"ISO 3166-2:LC","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Saint Martin (French part)","alpha-2":"MF","alpha-3":"MAF","country-code":"663","iso_3166-2":"ISO 3166-2:MF","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Saint Pierre and Miquelon","alpha-2":"PM","alpha-3":"SPM","country-code":"666","iso_3166-2":"ISO 3166-2:PM","region":"Americas","sub-region":"Northern America","intermediate-region":"","region-code":"019","sub-region-code":"021","intermediate-region-code":""}, +{"name":"Saint Vincent and the Grenadines","alpha-2":"VC","alpha-3":"VCT","country-code":"670","iso_3166-2":"ISO 3166-2:VC","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Samoa","alpha-2":"WS","alpha-3":"WSM","country-code":"882","iso_3166-2":"ISO 3166-2:WS","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"San Marino","alpha-2":"SM","alpha-3":"SMR","country-code":"674","iso_3166-2":"ISO 3166-2:SM","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Sao Tome and Principe","alpha-2":"ST","alpha-3":"STP","country-code":"678","iso_3166-2":"ISO 3166-2:ST","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Middle Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"017"}, +{"name":"Saudi Arabia","alpha-2":"SA","alpha-3":"SAU","country-code":"682","iso_3166-2":"ISO 3166-2:SA","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Senegal","alpha-2":"SN","alpha-3":"SEN","country-code":"686","iso_3166-2":"ISO 3166-2:SN","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Serbia","alpha-2":"RS","alpha-3":"SRB","country-code":"688","iso_3166-2":"ISO 3166-2:RS","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Seychelles","alpha-2":"SC","alpha-3":"SYC","country-code":"690","iso_3166-2":"ISO 3166-2:SC","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Sierra Leone","alpha-2":"SL","alpha-3":"SLE","country-code":"694","iso_3166-2":"ISO 3166-2:SL","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Singapore","alpha-2":"SG","alpha-3":"SGP","country-code":"702","iso_3166-2":"ISO 3166-2:SG","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Sint Maarten (Dutch part)","alpha-2":"SX","alpha-3":"SXM","country-code":"534","iso_3166-2":"ISO 3166-2:SX","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Slovakia","alpha-2":"SK","alpha-3":"SVK","country-code":"703","iso_3166-2":"ISO 3166-2:SK","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"Slovenia","alpha-2":"SI","alpha-3":"SVN","country-code":"705","iso_3166-2":"ISO 3166-2:SI","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Solomon Islands","alpha-2":"SB","alpha-3":"SLB","country-code":"090","iso_3166-2":"ISO 3166-2:SB","region":"Oceania","sub-region":"Melanesia","intermediate-region":"","region-code":"009","sub-region-code":"054","intermediate-region-code":""}, +{"name":"Somalia","alpha-2":"SO","alpha-3":"SOM","country-code":"706","iso_3166-2":"ISO 3166-2:SO","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"South Africa","alpha-2":"ZA","alpha-3":"ZAF","country-code":"710","iso_3166-2":"ISO 3166-2:ZA","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Southern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"018"}, +{"name":"South Georgia and the South Sandwich Islands","alpha-2":"GS","alpha-3":"SGS","country-code":"239","iso_3166-2":"ISO 3166-2:GS","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"South Sudan","alpha-2":"SS","alpha-3":"SSD","country-code":"728","iso_3166-2":"ISO 3166-2:SS","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Spain","alpha-2":"ES","alpha-3":"ESP","country-code":"724","iso_3166-2":"ISO 3166-2:ES","region":"Europe","sub-region":"Southern Europe","intermediate-region":"","region-code":"150","sub-region-code":"039","intermediate-region-code":""}, +{"name":"Sri Lanka","alpha-2":"LK","alpha-3":"LKA","country-code":"144","iso_3166-2":"ISO 3166-2:LK","region":"Asia","sub-region":"Southern Asia","intermediate-region":"","region-code":"142","sub-region-code":"034","intermediate-region-code":""}, +{"name":"Sudan","alpha-2":"SD","alpha-3":"SDN","country-code":"729","iso_3166-2":"ISO 3166-2:SD","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"Suriname","alpha-2":"SR","alpha-3":"SUR","country-code":"740","iso_3166-2":"ISO 3166-2:SR","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Svalbard and Jan Mayen","alpha-2":"SJ","alpha-3":"SJM","country-code":"744","iso_3166-2":"ISO 3166-2:SJ","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Sweden","alpha-2":"SE","alpha-3":"SWE","country-code":"752","iso_3166-2":"ISO 3166-2:SE","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"Switzerland","alpha-2":"CH","alpha-3":"CHE","country-code":"756","iso_3166-2":"ISO 3166-2:CH","region":"Europe","sub-region":"Western Europe","intermediate-region":"","region-code":"150","sub-region-code":"155","intermediate-region-code":""}, +{"name":"Syrian Arab Republic","alpha-2":"SY","alpha-3":"SYR","country-code":"760","iso_3166-2":"ISO 3166-2:SY","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Taiwan, Province of China","alpha-2":"TW","alpha-3":"TWN","country-code":"158","iso_3166-2":"ISO 3166-2:TW","region":"Asia","sub-region":"Eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"030","intermediate-region-code":""}, +{"name":"Tajikistan","alpha-2":"TJ","alpha-3":"TJK","country-code":"762","iso_3166-2":"ISO 3166-2:TJ","region":"Asia","sub-region":"Central Asia","intermediate-region":"","region-code":"142","sub-region-code":"143","intermediate-region-code":""}, +{"name":"Tanzania, United Republic of","alpha-2":"TZ","alpha-3":"TZA","country-code":"834","iso_3166-2":"ISO 3166-2:TZ","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Thailand","alpha-2":"TH","alpha-3":"THA","country-code":"764","iso_3166-2":"ISO 3166-2:TH","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Timor-Leste","alpha-2":"TL","alpha-3":"TLS","country-code":"626","iso_3166-2":"ISO 3166-2:TL","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Togo","alpha-2":"TG","alpha-3":"TGO","country-code":"768","iso_3166-2":"ISO 3166-2:TG","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Western Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"011"}, +{"name":"Tokelau","alpha-2":"TK","alpha-3":"TKL","country-code":"772","iso_3166-2":"ISO 3166-2:TK","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Tonga","alpha-2":"TO","alpha-3":"TON","country-code":"776","iso_3166-2":"ISO 3166-2:TO","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Trinidad and Tobago","alpha-2":"TT","alpha-3":"TTO","country-code":"780","iso_3166-2":"ISO 3166-2:TT","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Tunisia","alpha-2":"TN","alpha-3":"TUN","country-code":"788","iso_3166-2":"ISO 3166-2:TN","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"Turkey","alpha-2":"TR","alpha-3":"TUR","country-code":"792","iso_3166-2":"ISO 3166-2:TR","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Turkmenistan","alpha-2":"TM","alpha-3":"TKM","country-code":"795","iso_3166-2":"ISO 3166-2:TM","region":"Asia","sub-region":"Central Asia","intermediate-region":"","region-code":"142","sub-region-code":"143","intermediate-region-code":""}, +{"name":"Turks and Caicos Islands","alpha-2":"TC","alpha-3":"TCA","country-code":"796","iso_3166-2":"ISO 3166-2:TC","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Tuvalu","alpha-2":"TV","alpha-3":"TUV","country-code":"798","iso_3166-2":"ISO 3166-2:TV","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Uganda","alpha-2":"UG","alpha-3":"UGA","country-code":"800","iso_3166-2":"ISO 3166-2:UG","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Ukraine","alpha-2":"UA","alpha-3":"UKR","country-code":"804","iso_3166-2":"ISO 3166-2:UA","region":"Europe","sub-region":"Eastern Europe","intermediate-region":"","region-code":"150","sub-region-code":"151","intermediate-region-code":""}, +{"name":"United Arab Emirates","alpha-2":"AE","alpha-3":"ARE","country-code":"784","iso_3166-2":"ISO 3166-2:AE","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"United Kingdom of Great Britain and Northern Ireland","alpha-2":"GB","alpha-3":"GBR","country-code":"826","iso_3166-2":"ISO 3166-2:GB","region":"Europe","sub-region":"Northern Europe","intermediate-region":"","region-code":"150","sub-region-code":"154","intermediate-region-code":""}, +{"name":"United States of America","alpha-2":"US","alpha-3":"USA","country-code":"840","iso_3166-2":"ISO 3166-2:US","region":"Americas","sub-region":"Northern America","intermediate-region":"","region-code":"019","sub-region-code":"021","intermediate-region-code":""}, +{"name":"United States Minor Outlying Islands","alpha-2":"UM","alpha-3":"UMI","country-code":"581","iso_3166-2":"ISO 3166-2:UM","region":"Oceania","sub-region":"Micronesia","intermediate-region":"","region-code":"009","sub-region-code":"057","intermediate-region-code":""}, +{"name":"Uruguay","alpha-2":"UY","alpha-3":"URY","country-code":"858","iso_3166-2":"ISO 3166-2:UY","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Uzbekistan","alpha-2":"UZ","alpha-3":"UZB","country-code":"860","iso_3166-2":"ISO 3166-2:UZ","region":"Asia","sub-region":"Central Asia","intermediate-region":"","region-code":"142","sub-region-code":"143","intermediate-region-code":""}, +{"name":"Vanuatu","alpha-2":"VU","alpha-3":"VUT","country-code":"548","iso_3166-2":"ISO 3166-2:VU","region":"Oceania","sub-region":"Melanesia","intermediate-region":"","region-code":"009","sub-region-code":"054","intermediate-region-code":""}, +{"name":"Venezuela (Bolivarian Republic of)","alpha-2":"VE","alpha-3":"VEN","country-code":"862","iso_3166-2":"ISO 3166-2:VE","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"South America","region-code":"019","sub-region-code":"419","intermediate-region-code":"005"}, +{"name":"Viet Nam","alpha-2":"VN","alpha-3":"VNM","country-code":"704","iso_3166-2":"ISO 3166-2:VN","region":"Asia","sub-region":"South-eastern Asia","intermediate-region":"","region-code":"142","sub-region-code":"035","intermediate-region-code":""}, +{"name":"Virgin Islands (British)","alpha-2":"VG","alpha-3":"VGB","country-code":"092","iso_3166-2":"ISO 3166-2:VG","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Virgin Islands (U.S.)","alpha-2":"VI","alpha-3":"VIR","country-code":"850","iso_3166-2":"ISO 3166-2:VI","region":"Americas","sub-region":"Latin America and the Caribbean","intermediate-region":"Caribbean","region-code":"019","sub-region-code":"419","intermediate-region-code":"029"}, +{"name":"Wallis and Futuna","alpha-2":"WF","alpha-3":"WLF","country-code":"876","iso_3166-2":"ISO 3166-2:WF","region":"Oceania","sub-region":"Polynesia","intermediate-region":"","region-code":"009","sub-region-code":"061","intermediate-region-code":""}, +{"name":"Western Sahara","alpha-2":"EH","alpha-3":"ESH","country-code":"732","iso_3166-2":"ISO 3166-2:EH","region":"Africa","sub-region":"Northern Africa","intermediate-region":"","region-code":"002","sub-region-code":"015","intermediate-region-code":""}, +{"name":"Yemen","alpha-2":"YE","alpha-3":"YEM","country-code":"887","iso_3166-2":"ISO 3166-2:YE","region":"Asia","sub-region":"Western Asia","intermediate-region":"","region-code":"142","sub-region-code":"145","intermediate-region-code":""}, +{"name":"Zambia","alpha-2":"ZM","alpha-3":"ZMB","country-code":"894","iso_3166-2":"ISO 3166-2:ZM","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"}, +{"name":"Zimbabwe","alpha-2":"ZW","alpha-3":"ZWE","country-code":"716","iso_3166-2":"ISO 3166-2:ZW","region":"Africa","sub-region":"Sub-Saharan Africa","intermediate-region":"Eastern Africa","region-code":"002","sub-region-code":"202","intermediate-region-code":"014"} +] diff --git a/vendor/github.com/go-openapi/strfmt/mongo.go b/vendor/github.com/go-openapi/strfmt/mongo.go index be904ffa5de..15bfbed192f 100644 --- a/vendor/github.com/go-openapi/strfmt/mongo.go +++ b/vendor/github.com/go-openapi/strfmt/mongo.go @@ -4,7 +4,6 @@ package strfmt import ( - "encoding/base64" "encoding/binary" "fmt" "time" @@ -41,6 +40,8 @@ var ( _ bsonUnmarshaler = &Base64{} _ bsonMarshaler = Duration(0) _ bsonUnmarshaler = (*Duration)(nil) + _ bsonMarshaler = DurationISO8601(0) + _ bsonUnmarshaler = (*DurationISO8601)(nil) _ bsonMarshaler = DateTime{} _ bsonUnmarshaler = &DateTime{} _ bsonMarshaler = ULID{} @@ -92,6 +93,10 @@ var ( _ bsonValueUnmarshaler = &DateTime{} _ bsonValueMarshaler = ObjectId{} _ bsonValueUnmarshaler = &ObjectId{} + _ bsonMarshaler = Currency{} + _ bsonUnmarshaler = (*Currency)(nil) + _ bsonMarshaler = Country{} + _ bsonUnmarshaler = (*Country)(nil) ) const ( @@ -140,7 +145,7 @@ func (b *Base64) UnmarshalBSON(data []byte) error { return fmt.Errorf("couldn't unmarshal bson bytes as base64: %w", ErrFormat) } - vb, err := base64.StdEncoding.DecodeString(s) + vb, err := base64Encoding.DecodeString(s) if err != nil { return err } @@ -171,6 +176,38 @@ func (d *Duration) UnmarshalBSON(data []byte) error { return nil } +// MarshalBSON renders the [ISODuration] as a BSON document. +// +// BSON is a storage boundary (like SQL): the value is emitted losslessly with [ISODuration.String], regardless of the +// policy P — a strict policy that could not serialize a sign or sub-second precision on the interchange path must still +// be persistable. +func (d ISODuration[P]) MarshalBSON() ([]byte, error) { + return bsonlite.C.MarshalDoc(d.String()) +} + +// UnmarshalBSON reads an [ISODuration] from a BSON document. +// +// The stored value is our own canonical output, so it is parsed leniently: BSON is trusted storage, not external +// interchange, and must round-trip whatever [ISODuration.MarshalBSON] emitted even under a strict policy P. +func (d *ISODuration[P]) UnmarshalBSON(data []byte) error { + v, err := bsonlite.C.UnmarshalDoc(data) + if err != nil { + return err + } + + s, ok := v.(string) + if !ok { + return fmt.Errorf("couldn't unmarshal bson bytes value as ISODuration: %w", ErrFormat) + } + + rd, err := parseISO8601Duration(s, DurationLenient{}.isoDurationConfig()) + if err != nil { + return err + } + *d = ISODuration[P](rd) + return nil +} + // MarshalBSON renders the [DateTime] as a BSON document. func (t DateTime) MarshalBSON() ([]byte, error) { tNorm := NormalizeTimeForMarshal(time.Time(t)) @@ -599,3 +636,47 @@ func (id *ObjectId) UnmarshalBSONValue(_ byte, data []byte) error { *id = ObjectId(oid) return nil } + +// MarshalBSON document from this value. +func (u Currency) MarshalBSON() ([]byte, error) { + return bsonlite.C.MarshalDoc(u.String()) +} + +// UnmarshalBSON document into this value. +func (u *Currency) UnmarshalBSON(data []byte) error { + s, err := unmarshalBSONString(data, "Currency") + if err != nil { + return err + } + + cur, err := ParseCurrency(s) + if err != nil { + return err + } + + *u = cur + + return nil +} + +// MarshalBSON document from this value. +func (u Country) MarshalBSON() ([]byte, error) { + return bsonlite.C.MarshalDoc(u.String()) +} + +// UnmarshalBSON document into this value. +func (u *Country) UnmarshalBSON(data []byte) error { + s, err := unmarshalBSONString(data, "Country") + if err != nil { + return err + } + + cur, err := ParseCountry(s) + if err != nil { + return err + } + + *u = cur + + return nil +} diff --git a/vendor/github.com/go-openapi/strfmt/register.go b/vendor/github.com/go-openapi/strfmt/register.go new file mode 100644 index 00000000000..4a4c185b53a --- /dev/null +++ b/vendor/github.com/go-openapi/strfmt/register.go @@ -0,0 +1,138 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package strfmt + +// Default is the default formats registry. +// +// NOTE: format "duration" is wire by default onto "duration-human". +var Default Registry //nolint:gochecknoglobals // package-level default registry, by design + +// JSONSchema2020Registry is the format registry with JSONSchema draft 2020 formats (e.g. duration is an iso8601 duration). +var JSONSchema2020Registry Registry //nolint:gochecknoglobals // package-level default registry, by design + +func init() { //nolint:gochecknoinits // registers all default string formats in the registry + // register formats in the default registry: + // - byte + // - creditcard + // - email + // - hexcolor + // - hostname + // - ipv4 + // - ipv6 + // - cidr + // - isbn + // - isbn10 + // - isbn13 + // - mac + // - password + // - rgbcolor + // - ssn + // - uri + // - uuid + // - uuid3 + // - uuid4 + // - uuid5 + // - uuid7 + // - ulid + // - date, date-time + // - duration, duration-human, duration-iso8601 + // - objectid + // - currency, country + Default = NewSeededFormats(nil, nil) + + u := URI("") + Default.Add("uri", &u, isRequestURI) + + eml := Email("") + Default.Add("email", &eml, IsEmail) + + hn := Hostname("") + Default.Add("hostname", &hn, IsHostname) + + ip4 := IPv4("") + Default.Add("ipv4", &ip4, isIPv4) + + ip6 := IPv6("") + Default.Add("ipv6", &ip6, isIPv6) + + cidr := CIDR("") + Default.Add("cidr", &cidr, isCIDR) + + mac := MAC("") + Default.Add("mac", &mac, isMAC) + + uid := UUID("") + Default.Add("uuid", &uid, IsUUID) + + uid3 := UUID3("") + Default.Add("uuid3", &uid3, IsUUID3) + + uid4 := UUID4("") + Default.Add("uuid4", &uid4, IsUUID4) + + uid5 := UUID5("") + Default.Add("uuid5", &uid5, IsUUID5) + + uid7 := UUID7("") + Default.Add("uuid7", &uid7, IsUUID7) + + isbn := ISBN("") + Default.Add("isbn", &isbn, func(str string) bool { return isISBN10(str) || isISBN13(str) }) + + isbn10 := ISBN10("") + Default.Add("isbn10", &isbn10, isISBN10) + + isbn13 := ISBN13("") + Default.Add("isbn13", &isbn13, isISBN13) + + cc := CreditCard("") + Default.Add("creditcard", &cc, isCreditCard) + + ssn := SSN("") + Default.Add("ssn", &ssn, isSSN) + + hc := HexColor("") + Default.Add("hexcolor", &hc, isHexcolor) + + rc := RGBColor("") + Default.Add("rgbcolor", &rc, isRGBcolor) + + b64 := Base64([]byte(nil)) + Default.Add("byte", &b64, isBase64) + + pw := Password("") + Default.Add("password", &pw, func(_ string) bool { return true }) + + d := Date{} + Default.Add("date", &d, IsDate) + + dt := DateTime{} + Default.Add("datetime", &dt, IsDateTime) + + du := Duration(0) + Default.Add("duration", &du, IsDuration) + Default.Add("duration-human", &du, IsDuration) + + di := DurationISO8601(0) + Default.Add("duration-iso8601", &di, IsDurationISO8601) + + var id ObjectId + Default.Add("bsonobjectid", &id, IsBSONObjectID) + + ulid := ULID{} + Default.Add("ulid", &ulid, IsULID) + + cur := Currency{} + Default.Add("currency", &cur, IsCurrency) + + co := Country{} + Default.Add("country", &co, IsCountry) + + def, ok := Default.(*defaultFormats) + if !ok { + panic("internal error: can't initialize") + } + + JSONSchema2020Registry = NewSeededFormats(def.data, JSONSchema2020Normalizer) +} diff --git a/vendor/github.com/go-openapi/strfmt/time.go b/vendor/github.com/go-openapi/strfmt/time.go index 1fde8c6b119..94e409e0637 100644 --- a/vendor/github.com/go-openapi/strfmt/time.go +++ b/vendor/github.com/go-openapi/strfmt/time.go @@ -17,11 +17,6 @@ import ( // Unix 0 for an EST timezone is not equivalent to a UTC timezone. var UnixZero = time.Unix(0, 0).UTC() //nolint:gochecknoglobals // package-level sentinel value for unix epoch -func init() { //nolint:gochecknoinits // registers datetime format in the default registry - dt := DateTime{} - Default.Add("datetime", &dt, IsDateTime) -} - // IsDateTime returns true when the string is a valid date-time. // // JSON datetime format consist of a date and a time separated by a "T", e.g. 2012-04-23T18:25:43.511Z. diff --git a/vendor/github.com/go-openapi/strfmt/ulid.go b/vendor/github.com/go-openapi/strfmt/ulid.go index f05d22c5187..38809adba42 100644 --- a/vendor/github.com/go-openapi/strfmt/ulid.go +++ b/vendor/github.com/go-openapi/strfmt/ulid.go @@ -69,11 +69,6 @@ var ( ULIDValueOverrideFunc = ULIDValueDefaultFunc ) -func init() { //nolint:gochecknoinits // registers ulid format in the default registry - ulid := ULID{} - Default.Add("ulid", &ulid, IsULID) -} - // IsULID checks if provided string is [ULID] format // Be noticed that this function considers overflowed [ULID] as non-[ulid]. // For more details see https://github.com/[ulid]/spec diff --git a/vendor/github.com/go-openapi/swag/.gitignore b/vendor/github.com/go-openapi/swag/.gitignore index 1680db44c01..3ceb596fa2a 100644 --- a/vendor/github.com/go-openapi/swag/.gitignore +++ b/vendor/github.com/go-openapi/swag/.gitignore @@ -4,3 +4,4 @@ Godeps .idea *.out .mcp.json +.worktrees diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml index 126264a6b89..099c0a78c63 100644 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ b/vendor/github.com/go-openapi/swag/.golangci.yml @@ -14,7 +14,10 @@ linters: - gocognit - godot - godox + - goconst - gomoddirectives + - gomodguard + - gomodguard_v2 - gosmopolitan - inamedparam - intrange diff --git a/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md b/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md index 286878acff9..0f0711cd5f4 100644 --- a/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/swag/CONTRIBUTORS.md @@ -4,11 +4,11 @@ | Total Contributors | Total Contributions | | --- | --- | -| 24 | 242 | +| 24 | 251 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | -| @fredbi | 112 | | +| @fredbi | 121 | | | @casualjim | 98 | | | @alexandear | 4 | | | @orisano | 3 | | diff --git a/vendor/github.com/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md index 64f66710397..c6c2d21e944 100644 --- a/vendor/github.com/go-openapi/swag/README.md +++ b/vendor/github.com/go-openapi/swag/README.md @@ -34,12 +34,9 @@ You may also use it standalone for your projects. * **2025-12-19** : new community chat on discord * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] - ## Status API is stable. @@ -70,11 +67,12 @@ Child modules will continue to evolve and some new ones may be added in the futu | `cmdutils` | utilities to work with CLIs || | `conv` | type conversion utilities | convert between values and pointers for any types
convert from string to builtin types (wraps `strconv`)
require `./typeutils` (test dependency)
| | `fileutils` | file utilities | | -| `jsonname` | JSON utilities | infer JSON names from `go` properties
| +| `jsonname` | JSON utilities (deprecated) | infer JSON names from `go` properties
use `github.com/go-openapi/jsonpointer/jsonname` instead | | `jsonutils` | JSON utilities | fast json concatenation
read and write JSON from and to dynamic `go` data structures
~require `github.com/mailru/easyjson`~
| | `loading` | file loading | load from file or http
require `./yamlutils`
| | `mangling` | safe name generation | name mangling for `go`
| | `netutils` | networking utilities | host, port from address
| +| `pools` | utilities to work with sync.Pools | | | `stringutils` | `string` utilities | search in slice (with case-insensitive)
split/join query parameters as arrays
| | `typeutils` | `go` types utilities | check the zero value for any type
safe check for a nil value
| | `yamlutils` | YAML utilities | converting YAML to JSON
loading YAML into a dynamic YAML document
maintaining the original order of keys in YAML objects
require `./jsonutils`
~require `github.com/mailru/easyjson`~
require `go.yaml.in/yaml/v3`
| @@ -171,9 +169,9 @@ on top of which it has been built. ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -208,9 +206,6 @@ Maintainers can cut a new release by either: [doc-url]: https://goswagger.io/go-openapi [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/swag [godoc-url]: http://pkg.go.dev/github.com/go-openapi/swag -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue [discord-url]: https://discord.gg/FfnFYaC3k5 @@ -222,3 +217,7 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/swag/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/swag [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/swag/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/swag/conv/format.go b/vendor/github.com/go-openapi/swag/conv/format.go index 5b87b8e146b..e14e5bfcfb9 100644 --- a/vendor/github.com/go-openapi/swag/conv/format.go +++ b/vendor/github.com/go-openapi/swag/conv/format.go @@ -7,14 +7,16 @@ import ( "strconv" ) +const baseDecimal = 10 + // FormatInteger turns an integer type into a string. func FormatInteger[T Signed](value T) string { - return strconv.FormatInt(int64(value), 10) + return strconv.FormatInt(int64(value), baseDecimal) } // FormatUinteger turns an unsigned integer type into a string. func FormatUinteger[T Unsigned](value T) string { - return strconv.FormatUint(uint64(value), 10) + return strconv.FormatUint(uint64(value), baseDecimal) } // FormatFloat turns a floating point numerical value into a string. @@ -26,3 +28,23 @@ func FormatFloat[T Float](value T) string { func FormatBool(value bool) string { return strconv.FormatBool(value) } + +// AppendInteger appends the decimal representation of an integer to a slice of bytes. +func AppendInteger[T Signed](dst []byte, value T) []byte { + return strconv.AppendInt(dst, int64(value), baseDecimal) +} + +// AppendUinteger appends the decimal representation of an unsigned integer to a slice of bytes. +func AppendUinteger[T Unsigned](dst []byte, value T) []byte { + return strconv.AppendUint(dst, uint64(value), baseDecimal) +} + +// AppendFloat appends the decimal representation of a floating point number to a slice of bytes. +func AppendFloat[T Float](dst []byte, value T) []byte { + return strconv.AppendFloat(dst, float64(value), 'g', -1, bitsize(value)) +} + +// AppendBool appends the text representation of a boolean to a slice of bytes. +func AppendBool(dst []byte, value bool) []byte { + return strconv.AppendBool(dst, value) +} diff --git a/vendor/github.com/go-openapi/swag/go.work b/vendor/github.com/go-openapi/swag/go.work index 8537cb2a76a..f1dddc436e7 100644 --- a/vendor/github.com/go-openapi/swag/go.work +++ b/vendor/github.com/go-openapi/swag/go.work @@ -12,6 +12,7 @@ use ( ./loading ./mangling ./netutils + ./pools ./stringutils ./typeutils ./yamlutils diff --git a/vendor/github.com/go-openapi/swag/jsonname_iface.go b/vendor/github.com/go-openapi/swag/jsonname_iface.go index 303a007f6f4..443560caad4 100644 --- a/vendor/github.com/go-openapi/swag/jsonname_iface.go +++ b/vendor/github.com/go-openapi/swag/jsonname_iface.go @@ -4,21 +4,21 @@ package swag import ( - "github.com/go-openapi/swag/jsonname" + "github.com/go-openapi/jsonpointer/jsonname" ) // DefaultJSONNameProvider is the default cache for types // -// Deprecated: use [jsonname.DefaultJSONNameProvider] instead. +// Deprecated: use [github.com/go-openapi/jsonpointer/jsonname.DefaultJSONNameProvider] instead. var DefaultJSONNameProvider = jsonname.DefaultJSONNameProvider // NameProvider represents an object capable of translating from go property names // to json property names. // -// Deprecated: use [jsonname.NameProvider] instead. +// Deprecated: use [github.com/go-openapi/jsonpointer/jsonname.NameProvider] instead. type NameProvider = jsonname.NameProvider // NewNameProvider creates a new name provider // -// Deprecated: use [jsonname.NewNameProvider] instead. +// Deprecated: use [github.com/go-openapi/jsonpointer/jsonname.NewNameProvider] instead. func NewNameProvider() *NameProvider { return jsonname.NewNameProvider() } diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go index 0213ff5c29f..94185f79c10 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go @@ -5,6 +5,7 @@ package json import ( stdjson "encoding/json" + "fmt" "github.com/go-openapi/swag/jsonutils/adapters/ifaces" "github.com/go-openapi/swag/typeutils" @@ -24,11 +25,16 @@ var ErrStdlib jsonError = "error from the JSON adapter stdlib" var _ ifaces.Adapter = &Adapter{} type Adapter struct { + options } // NewAdapter yields an [ifaces.Adapter] using the standard library. -func NewAdapter() *Adapter { - return &Adapter{} +func NewAdapter(opts ...Option) *Adapter { + var o options + + return &Adapter{ + options: buildOptions(o, opts), + } } func (a *Adapter) Marshal(value any) ([]byte, error) { @@ -40,45 +46,18 @@ func (a *Adapter) Unmarshal(data []byte, value any) error { } func (a *Adapter) OrderedMarshal(value ifaces.Ordered) ([]byte, error) { - w := poolOfWriters.Borrow() - defer func() { - poolOfWriters.Redeem(w) - }() - - if typeutils.IsNil(value) { - w.RawString("null") - - return w.BuildBytes() - } - - w.RawByte('{') - first := true - for k, v := range value.OrderedItems() { - if first { - first = false - } else { - w.RawByte(',') - } + w, redeem := poolOfWriters.BorrowWithRedeem() + defer redeem() + w.setBuf() - w.String(k) - w.RawByte(':') - - switch val := v.(type) { - case ifaces.Ordered: - w.Raw(a.OrderedMarshal(val)) - default: - w.Raw(stdjson.Marshal(v)) - } - } - - w.RawByte('}') + a.orderedMarshal(w, value, 1) return w.BuildBytes() } func (a *Adapter) OrderedUnmarshal(data []byte, value ifaces.SetOrdered) error { var m MapSlice - if err := m.OrderedUnmarshalJSON(data); err != nil { + if err := m.orderedUnmarshalJSON(data, a.maxDepth()); err != nil { return err } @@ -112,4 +91,43 @@ func (a *Adapter) Redeem() { } func (a *Adapter) Reset() { + a.options = options{} +} + +// orderedMarshal writes value to w, tracking the container nesting depth to guard +// against stack overflow on deeply nested structures. +func (a *Adapter) orderedMarshal(w *jwriter, value ifaces.Ordered, depth int) { + if typeutils.IsNil(value) { + w.RawString("null") + + return + } + + if maxDepth := a.maxDepth(); depth > maxDepth { + w.SetErr(fmt.Errorf("maximum nesting depth of %d exceeded: %w", maxDepth, ErrStdlib)) + + return + } + + w.RawByte('{') + first := true + for k, v := range value.OrderedItems() { + if first { + first = false + } else { + w.RawByte(',') + } + + w.String(k) + w.RawByte(':') + + switch val := v.(type) { + case ifaces.Ordered: + a.orderedMarshal(w, val, depth+1) + default: + w.Raw(stdjson.Marshal(v)) + } + } + + w.RawByte('}') } diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go index b5aa1c7972e..ac81cbc75fa 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go @@ -54,7 +54,7 @@ func (t token) Delim() byte { return 0 } - return byte(r) + return byte(r) //nolint:gosec // delimiter runes are single byte } type tokenKind uint8 @@ -91,6 +91,13 @@ type jlexer struct { // current token next token // started bool + + // depth tracks the current JSON container nesting level, and maxDepth caps it + // to guard against stack-overflow on adversarially deep documents. The standard + // library's streaming [encoding/json.Decoder.Token] API (used here) does not + // enforce the max-depth guard that [encoding/json.Unmarshal] provides, so we do. + depth int + maxDepth int } type bytesReader struct { @@ -130,7 +137,8 @@ var _ io.Reader = &bytesReader{} func newLexer(data []byte) *jlexer { l := &jlexer{ // current: undefToken, - next: undefToken, + next: undefToken, + maxDepth: defaultMaxNestingDepth, } l.buf = &bytesReader{ buf: data, @@ -143,7 +151,11 @@ func newLexer(data []byte) *jlexer { func (l *jlexer) Reset() { l.err = nil l.next = undefToken - // leave l.dec and l.buf alone, since they are replaced at every Borrow + l.depth = 0 + l.maxDepth = defaultMaxNestingDepth + l.dec = nil + // leave l.buf alone, since they are replaced at every Borrow + l.buf = nil } func (l *jlexer) Error() error { @@ -228,6 +240,21 @@ func (l *jlexer) Delim(c byte) { if tok.Delim() != c { l.err = fmt.Errorf("expected delimiter '%q' but got '%q': %w", c, tok.Delim(), ErrStdlib) + + return + } + + // Track container nesting depth centrally: every '{' or '[' opens a level and + // every '}' or ']' closes one. This guards the mutually-recursive unmarshal + // routines (unmarshalObject/unmarshalArray/asInterface) against stack overflow. + switch c { + case '{', '[': + l.depth++ + if l.maxDepth > 0 && l.depth > l.maxDepth { + l.err = fmt.Errorf("maximum nesting depth of %d exceeded: %w", l.maxDepth, ErrStdlib) + } + case '}', ']': + l.depth-- } } @@ -318,3 +345,12 @@ func (l *jlexer) fetchToken() token { return token{Token: jtok} } + +func (l *jlexer) setBuf(data []byte) func() { + rdr, redeemBuf := poolOfReaders.BorrowWithRedeem() + l.buf = rdr + l.buf.buf = data + l.dec = stdjson.NewDecoder(l.buf) // cannot pool, not exposed by the encoding/json API + + return redeemBuf +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go new file mode 100644 index 00000000000..cfcd426852a --- /dev/null +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/options.go @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package json + +// defaultMaxNestingDepth is the default maximum number of nested JSON containers +// ('{' or '[') that the ordered-JSON marshaler and unmarshaler will process before +// returning an error. +// +// It mirrors the limit enforced by the standard library's [encoding/json] decoder +// (see encoding/json's internal maxNestingDepth), which this adapter would otherwise +// not benefit from since it drives [encoding/json.Decoder.Token] directly. +// +// With encoding/json v2 (GOEXPERIMENT=jsonv2, the default from go1.27), Token applies +// that same limit itself and reports "exceeded max depth" before this counter fires. +// Set a lower limit with [WithMaxNestingDepth] to be rejected earlier than the stdlib; +// a higher one does not lift the stdlib's own 10,000-level ceiling on the decode path. +const defaultMaxNestingDepth = 10000 + +// Option selects options for the stdlib adapter. +type Option func(o options) options + +type options struct { + maxNestingDepth int +} + +func buildOptions(o options, opts []Option) options { + for _, apply := range opts { + o = apply(o) + } + + return o +} + +// maxDepth returns the configured maximum nesting depth, or the default when unset. +func (o options) maxDepth() int { + if o.maxNestingDepth <= 0 { + return defaultMaxNestingDepth + } + + return o.maxNestingDepth +} + +// WithMaxNestingDepth sets the maximum number of nested JSON containers accepted +// when marshaling or unmarshaling ordered JSON. +// +// A value <= 0 selects the default (10,000). +// +// This guards against stack-overflow crashes on deeply nested (possibly adversarial) +// JSON documents or in-memory structures. +func WithMaxNestingDepth(depth int) Option { + return func(o options) options { + o.maxNestingDepth = depth + + return o + } +} diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go index 54deef406f3..a5a8f4b6317 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go @@ -70,12 +70,11 @@ func (s MapSlice) MarshalJSON() ([]byte, error) { } func (s MapSlice) OrderedMarshalJSON() ([]byte, error) { - w := poolOfWriters.Borrow() - defer func() { - poolOfWriters.Redeem(w) - }() + w, redeem := poolOfWriters.BorrowWithRedeem() + defer redeem() + w.setBuf() - s.marshalObject(w) + s.marshalObject(w, 1) return w.BuildBytes() // this clones data, so it's okay to redeem the writer and its buffer } @@ -88,23 +87,38 @@ func (s *MapSlice) UnmarshalJSON(data []byte) error { } func (s *MapSlice) OrderedUnmarshalJSON(data []byte) error { - l := poolOfLexers.Borrow(data) - defer func() { - poolOfLexers.Redeem(l) - }() + return s.orderedUnmarshalJSON(data, defaultMaxNestingDepth) +} + +func (s *MapSlice) orderedUnmarshalJSON(data []byte, maxDepth int) error { + l, redeem := poolOfLexers.BorrowWithRedeem() + defer redeem() + + redeemBuf := l.setBuf(data) + defer redeemBuf() + + if maxDepth > 0 { + l.maxDepth = maxDepth + } s.unmarshalObject(l) return l.Error() } -func (s MapSlice) marshalObject(w *jwriter) { +func (s MapSlice) marshalObject(w *jwriter, depth int) { if s == nil { w.RawString("null") return } + if depth > defaultMaxNestingDepth { + w.SetErr(fmt.Errorf("maximum nesting depth of %d exceeded: %w", defaultMaxNestingDepth, ErrStdlib)) + + return + } + w.RawByte('{') if len(s) == 0 { @@ -113,11 +127,11 @@ func (s MapSlice) marshalObject(w *jwriter) { return } - s[0].marshalJSON(w) + s[0].marshalJSON(w, depth) for i := 1; i < len(s); i++ { w.RawByte(',') - s[i].marshalJSON(w) + s[i].marshalJSON(w, depth) } w.RawByte('}') @@ -162,9 +176,18 @@ type MapItem struct { Value any } -func (s MapItem) marshalJSON(w *jwriter) { +func (s MapItem) marshalJSON(w *jwriter, depth int) { w.String(s.Key) w.RawByte(':') + + // Recurse internally for nested ordered maps so the depth guard is not lost across + // the stdjson.Marshal boundary (which would reset it and re-enable stack overflow). + if nested, ok := s.Value.(MapSlice); ok { + nested.marshalObject(w, depth+1) + + return + } + w.Raw(stdjson.Marshal(s.Value)) } diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go index 709b97c3046..2f06b88e808 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go @@ -4,118 +4,15 @@ package json import ( - "encoding/json" - "sync" - "github.com/go-openapi/swag/jsonutils/adapters/ifaces" + "github.com/go-openapi/swag/pools" ) -type adaptersPool struct { - sync.Pool -} - -func (p *adaptersPool) Borrow() *Adapter { - return p.Get().(*Adapter) -} - -func (p *adaptersPool) BorrowIface() ifaces.Adapter { - return p.Get().(*Adapter) -} - -func (p *adaptersPool) Redeem(a *Adapter) { - p.Put(a) -} - -type writersPool struct { - sync.Pool -} - -func (p *writersPool) Borrow() *jwriter { - ptr := p.Get() - - jw := ptr.(*jwriter) - jw.Reset() - - return jw -} - -func (p *writersPool) Redeem(w *jwriter) { - p.Put(w) -} - -type lexersPool struct { - sync.Pool -} - -func (p *lexersPool) Borrow(data []byte) *jlexer { - ptr := p.Get() - - l := ptr.(*jlexer) - l.buf = poolOfReaders.Borrow(data) - l.dec = json.NewDecoder(l.buf) // cannot pool, not exposed by the encoding/json API - l.Reset() - - return l -} - -func (p *lexersPool) Redeem(l *jlexer) { - l.dec = nil - discard := l.buf - l.buf = nil - poolOfReaders.Redeem(discard) - p.Put(l) -} - -type readersPool struct { - sync.Pool -} - -func (p *readersPool) Borrow(data []byte) *bytesReader { - ptr := p.Get() - - b := ptr.(*bytesReader) - b.Reset() - b.buf = data - - return b -} - -func (p *readersPool) Redeem(b *bytesReader) { - p.Put(b) -} - var ( - poolOfAdapters = &adaptersPool{ - Pool: sync.Pool{ - New: func() any { - return NewAdapter() - }, - }, - } - - poolOfWriters = &writersPool{ - Pool: sync.Pool{ - New: func() any { - return newJWriter() - }, - }, - } - - poolOfLexers = &lexersPool{ - Pool: sync.Pool{ - New: func() any { - return newLexer(nil) - }, - }, - } - - poolOfReaders = &readersPool{ - Pool: sync.Pool{ - New: func() any { - return &bytesReader{} - }, - }, - } + poolOfAdapters = pools.New[Adapter]() + poolOfWriters = pools.NewRedeemable[jwriter]() + poolOfLexers = pools.NewRedeemable[jlexer]() + poolOfReaders = pools.NewRedeemable[bytesReader]() ) // BorrowAdapter borrows an [Adapter] from the pool, recycling already allocated instances. @@ -124,10 +21,12 @@ func BorrowAdapter() *Adapter { } // BorrowAdapterIface borrows a stdlib [Adapter] and converts it directly -// to [ifaces.Adapter]. This is useful to avoid further allocations when -// translating the concrete type into an interface. +// to [ifaces.Adapter]. +// +// This is useful to avoid further allocations when translating the concrete type into +// an interface. func BorrowAdapterIface() ifaces.Adapter { - return poolOfAdapters.BorrowIface() + return poolOfAdapters.Borrow() } // RedeemAdapter redeems an [Adapter] to the pool, so it may be recycled. diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go index fc8818694ea..0dec85425ba 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go @@ -10,14 +10,22 @@ import ( "github.com/go-openapi/swag/jsonutils/adapters/ifaces" ) -func Register(dispatcher ifaces.Registrar) { +func Register(dispatcher ifaces.Registrar, opts ...Option) { t := reflect.TypeOf(Adapter{}) + var o options + o = buildOptions(o, opts) + dispatcher.RegisterFor( ifaces.RegistryEntry{ - Who: fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()), - What: ifaces.AllCapabilities, - Constructor: BorrowAdapterIface, - Support: support, + Who: fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()), + What: ifaces.AllCapabilities, + Constructor: func() ifaces.Adapter { + a := BorrowAdapter() + a.options = o + + return a + }, + Support: support, }) } diff --git a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go index dc2325c1a30..c84e02cd838 100644 --- a/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go +++ b/vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go @@ -14,17 +14,21 @@ type jwriter struct { err error } -func newJWriter() *jwriter { - buf := make([]byte, 0, sensibleBufferSize) - - return &jwriter{buf: bytes.NewBuffer(buf)} -} - func (w *jwriter) Reset() { - w.buf.Reset() + if w.buf != nil { + w.buf.Reset() + } w.err = nil } +// SetErr records the first error encountered while building the JSON output. +func (w *jwriter) SetErr(err error) { + if w.err != nil { + return + } + w.err = err +} + func (w *jwriter) RawString(s string) { if w.err != nil { return @@ -73,3 +77,12 @@ func (w *jwriter) BuildBytes() ([]byte, error) { return bytes.Clone(w.buf.Bytes()), nil } + +func (w *jwriter) setBuf() { + if w.buf != nil { + return + } + + buf := make([]byte, 0, sensibleBufferSize) + w.buf = bytes.NewBuffer(buf) +} diff --git a/vendor/github.com/go-openapi/swag/loading/doc.go b/vendor/github.com/go-openapi/swag/loading/doc.go index 8cf7bcb8b9d..112c49968b8 100644 --- a/vendor/github.com/go-openapi/swag/loading/doc.go +++ b/vendor/github.com/go-openapi/swag/loading/doc.go @@ -2,4 +2,28 @@ // SPDX-License-Identifier: Apache-2.0 // Package loading provides tools to load a file from http or from a local file system. +// +// # Security +// +// By default, the local loader reads any path the process can access, including absolute +// paths and "file://" URIs (for example "file:///etc/passwd"). Applications that pass +// untrusted input to [LoadFromFileOrHTTP], [JSONDoc] (or to downstream consumers such as +// go-openapi/loads) must confine local loading to a trusted directory. +// +// Use [WithRoot] to do so: it resolves every requested path relative to a chosen directory +// and rejects anything that escapes it, including via symlink. It is built on [os.Root] +// and is therefore safer than passing an [os.DirFS] to [WithFS], which does not block +// symlink escapes. +// +// Remote loading uses a standard [net/http] client. +// By default it follows redirects and performs no destination filtering — exactly like [net/http.DefaultClient]. +// +// A caller-controlled URL may therefore reach internal services or cloud metadata endpoints +// (server-side request forgery). +// +// This package does not, and should not, embed a network policy: +// when the URL may derive from untrusted input, supply a restricted client with +// [WithHTTPClient] whose transport rejects unwanted destinations at dial time — which also +// covers redirects and DNS rebinding. +// See the example on [LoadFromFileOrHTTP]. package loading diff --git a/vendor/github.com/go-openapi/swag/loading/loading.go b/vendor/github.com/go-openapi/swag/loading/loading.go index 269fb74d167..b06450c64df 100644 --- a/vendor/github.com/go-openapi/swag/loading/loading.go +++ b/vendor/github.com/go-openapi/swag/loading/loading.go @@ -17,7 +17,11 @@ import ( "strings" ) -// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in +// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in. +// +// Security: by default a local path is read with no confinement, so a caller-controlled path +// (including a "file://" URI or an absolute path) may read any file the process can access. +// When the path may derive from untrusted input, confine local loading with [WithRoot]. func LoadFromFileOrHTTP(pth string, opts ...Option) ([]byte, error) { o := optionsWithDefaults(opts) return LoadStrategy(pth, o.ReadFileFunc(), loadHTTPBytes(opts...), opts...)(pth) @@ -54,11 +58,14 @@ func LoadFromFileOrHTTP(pth string, opts ...Option) ([]byte, error) { // - `file:///c:/folder/file` becomes `C:\folder\file` // - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file` func LoadStrategy(pth string, local, remote func(string) ([]byte, error), opts ...Option) func(string) ([]byte, error) { - if strings.HasPrefix(pth, "http") { + if hasHTTPScheme(pth) { return remote } o := optionsWithDefaults(opts) _, isEmbedFS := o.fs.(embed.FS) + // any loader backed by an fs.FS or an os.Root consumes forward-slash paths on every + // platform, so it must not go through the windows-native file:// preprocessing below. + isFSBacked := o.fs != nil || o.root != "" return func(p string) ([]byte, error) { upth, err := url.PathUnescape(p) @@ -67,14 +74,22 @@ func LoadStrategy(pth string, local, remote func(string) ([]byte, error), opts . } cpth, hasPrefix := strings.CutPrefix(upth, "file://") - if !hasPrefix || isEmbedFS || runtime.GOOS != "windows" { + if !hasPrefix || isFSBacked || runtime.GOOS != "windows" { // crude processing: trim the file:// prefix. This leaves full URIs with a host with a (mostly) unexpected result // regular file path provided: just normalize slashes if isEmbedFS { - // on windows, we need to slash the path if FS is an embed FS. + // embed.FS always uses "/" as separator, even on windows, and rejects leading "./" or "/". return local(strings.TrimLeft(filepath.ToSlash(cpth), "./")) // remove invalid leading characters for embed FS } + if isFSBacked { + // other fs.FS (e.g. os.DirFS) and os.Root loaders also use "/" on every platform. + // Path confinement is enforced by the loader, not here: the os.Root loader rebases + // absolute in-root paths and rejects escaping paths ("..", out-of-root absolute, + // escaping symlinks); an fs.FS loader rejects what its file system does not allow. + return local(filepath.ToSlash(cpth)) + } + return local(filepath.FromSlash(cpth)) } @@ -113,6 +128,21 @@ func LoadStrategy(pth string, local, remote func(string) ([]byte, error), opts . } } +// hasHTTPScheme reports whether pth is an absolute URL with an http or https scheme, +// selecting the remote loader. The comparison is case-insensitive, as URL schemes are. +// +// Requiring the "://" separator (rather than a bare "http" prefix) avoids misrouting a +// local file whose name merely starts with "http" (e.g. "httpbin.json") to the remote loader. +func hasHTTPScheme(pth string) bool { + for _, scheme := range [...]string{"http://", "https://"} { + if len(pth) >= len(scheme) && strings.EqualFold(pth[:len(scheme)], scheme) { + return true + } + } + + return false +} + func loadHTTPBytes(opts ...Option) func(path string) ([]byte, error) { o := optionsWithDefaults(opts) diff --git a/vendor/github.com/go-openapi/swag/loading/options.go b/vendor/github.com/go-openapi/swag/loading/options.go index 6674ac69e62..539987547d1 100644 --- a/vendor/github.com/go-openapi/swag/loading/options.go +++ b/vendor/github.com/go-openapi/swag/loading/options.go @@ -4,9 +4,12 @@ package loading import ( + "errors" "io/fs" "net/http" "os" + "path/filepath" + "runtime" "time" ) @@ -23,7 +26,8 @@ type ( } fileOptions struct { - fs fs.ReadFileFS + fs fs.ReadFileFS + root string // when non-empty, local reads are confined to this directory via os.Root } options struct { @@ -33,6 +37,28 @@ type ( ) func (fo fileOptions) ReadFileFunc() func(string) ([]byte, error) { + if fo.root != "" { + root := fo.root + + return func(name string) ([]byte, error) { + // os.Root only accepts paths relative to the root, but callers (and this package's + // own file:// handling) routinely produce absolute paths. Rebase an absolute path + // onto the root before handing it to os.Root. + rel, err := rootRelative(root, name) + if err != nil { + return nil, errors.Join(err, ErrLoader) + } + + r, err := os.OpenRoot(root) + if err != nil { + return nil, errors.Join(err, ErrLoader) + } + defer func() { _ = r.Close() }() + + return r.ReadFile(rel) + } + } + if fo.fs == nil { return os.ReadFile } @@ -40,6 +66,61 @@ func (fo fileOptions) ReadFileFunc() func(string) ([]byte, error) { return fo.fs.ReadFile } +// rootRelative expresses name as a path relative to root, so that it can be resolved by os.Root. +// +// A relative name is returned unchanged: os.Root confines it directly (including "../" traversal +// and symlink escapes, which it rejects at open time). +// +// An absolute name is rebased onto root. If it cannot be expressed relative to root — for +// example because it lives on a different volume on Windows — filepath.Rel returns an error, +// which is propagated so the read is rejected rather than silently escaping the root. An +// absolute path that lexically escapes root yields a "../" prefix here and is then rejected by +// os.Root. +func rootRelative(root, name string) (string, error) { + osName := toOSPath(name) + if !filepath.IsAbs(osName) { + return name, nil + } + + absRoot, err := filepath.Abs(toOSPath(root)) + if err != nil { + return "", err + } + + return filepath.Rel(absRoot, osName) +} + +// toOSPath converts a slash-separated path to an OS-native path. +// +// On Windows it additionally normalizes the "/C:/dir" form — a leading separator before a drive +// letter — that file URIs and URL-style path normalization (as performed by +// github.com/go-openapi/spec) produce. Without this, filepath.IsAbs does not recognize such a +// path as absolute and os.Root rejects an otherwise in-root target. This mirrors the file:// +// drive-letter handling in LoadStrategy, which the os.Root loader bypasses. +func toOSPath(p string) string { + p = filepath.FromSlash(p) + if runtime.GOOS == "windows" { + p = stripLeadingDriveSlash(p) + } + + return p +} + +// stripLeadingDriveSlash removes a leading separator that precedes a Windows drive letter, +// turning "\C:\dir" (from a "/C:/dir" URL path) into "C:\dir". Any other path is returned +// unchanged. It is pure (no OS dependency) so that its logic can be tested on any platform. +func stripLeadingDriveSlash(p string) string { + if len(p) >= 3 && (p[0] == '/' || p[0] == '\\') && p[2] == ':' && isASCIILetter(p[1]) { + return p[1:] + } + + return p +} + +func isASCIILetter(b byte) bool { + return ('a' <= b && b <= 'z') || ('A' <= b && b <= 'Z') +} + // WithTimeout sets a timeout for the remote file loader. // // The default timeout is 30s. @@ -87,8 +168,15 @@ func WithHTTPClient(client *http.Client) Option { // By default, the file system is the one provided by the os package. // // For example, this may be set to consume from an embedded file system, or a rooted FS. +// +// WithFS and [WithRoot] are mutually exclusive: the last one applied wins. +// +// Security note: a file system built from [os.DirFS] confines paths but does NOT protect +// against symlinks that escape the root. To load from a directory derived from untrusted +// input, prefer [WithRoot], which is symlink-escape resistant. func WithFS(filesystem fs.FS) Option { return func(o *options) { + o.root = "" // last-wins vs WithRoot if rfs, ok := filesystem.(fs.ReadFileFS); ok { o.fs = rfs @@ -98,6 +186,30 @@ func WithFS(filesystem fs.FS) Option { } } +// WithRoot confines local file loading to dir. +// +// Every requested path is resolved within dir. A relative path is resolved against dir; an +// absolute path is rebased onto dir (so a caller that normalizes references to absolute paths, +// such as github.com/go-openapi/spec, still resolves correctly). Any path that would escape dir +// — through ".." traversal, an absolute path pointing outside dir, or a symlink pointing outside +// dir — is rejected. This is built on [os.Root] and is therefore resistant to the symlink +// escapes that a plain [os.DirFS] does not prevent. +// +// WithRoot is the recommended option when loading specs from a location derived from +// untrusted input. It applies to local loading only and has no effect on remote +// (http/https) loading. WithRoot and [WithFS] are mutually exclusive: the last one applied +// wins. +// +// Note: [os.Root] confines path resolution but does not, by itself, protect against +// traversal of mount/bind boundaries, /proc special files, or device files. Point WithRoot +// at a directory that holds only the documents you intend to expose. +func WithRoot(dir string) Option { + return func(o *options) { + o.root = dir + o.fs = nil // last-wins vs WithFS + } +} + type readFileFS struct { fs.FS } diff --git a/vendor/github.com/go-openapi/swag/loading_iface.go b/vendor/github.com/go-openapi/swag/loading_iface.go index 27ec3fb8c37..78dadfccdf4 100644 --- a/vendor/github.com/go-openapi/swag/loading_iface.go +++ b/vendor/github.com/go-openapi/swag/loading_iface.go @@ -80,11 +80,13 @@ func YAMLData(path string) (any, error) { // loadingOptionsWithDefaults bridges deprecated default settings that use package-level variables, // with the recommended use of loading.Option. func loadingOptionsWithDefaults(opts []loading.Option) []loading.Option { - o := []loading.Option{ + const defaultOptions = 3 + o := make([]loading.Option, 0, defaultOptions+len(opts)) + o = append(o, []loading.Option{ loading.WithTimeout(LoadHTTPTimeout), loading.WithBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword), loading.WithCustomHeaders(LoadHTTPCustomHeaders), - } + }...) o = append(o, opts...) return o diff --git a/vendor/github.com/go-openapi/swag/pools/LICENSE b/vendor/github.com/go-openapi/swag/pools/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/go-openapi/swag/pools/README.md b/vendor/github.com/go-openapi/swag/pools/README.md new file mode 100644 index 00000000000..1966461cb54 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/README.md @@ -0,0 +1 @@ +# pools diff --git a/vendor/github.com/go-openapi/swag/pools/debug.go b/vendor/github.com/go-openapi/swag/pools/debug.go new file mode 100644 index 00000000000..94415e989e4 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/debug.go @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +// TB is the subset of [testing.TB] used by [AssertNoLeaks]. +// +// It is satisfied by *[testing.T] and *[testing.B]. +// +// A local interface is used (rather than importing "testing") so that the +// release build does not pull the testing package — and its flags — into +// production binaries. +type TB interface { + Helper() + Errorf(format string, args ...any) + Logf(format string, args ...any) +} diff --git a/vendor/github.com/go-openapi/swag/pools/debug_off.go b/vendor/github.com/go-openapi/swag/pools/debug_off.go new file mode 100644 index 00000000000..9163d6d60e4 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/debug_off.go @@ -0,0 +1,51 @@ +//go:build !poolsdebug + +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +// This is the release implementation of the pool instrumentation: it does +// nothing. +// +// tracker is an empty struct, so it adds no field to the pool types and its +// methods inline away to nothing. +// +// Build with -tags poolsdebug to get the instrumented variant (see +// debug_on.go). + +// debugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug tag). +const debugBuild = false + +// DebugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug build tag). +// +// It lets a test that must run in both modes skip the parts that are invalid +// under instrumentation — e.g. an allocation-count assertion, since the +// instrumented build allocates a per-borrow tracker. +const DebugBuild = debugBuild + +type tracker[T any] struct{} + +func (tracker[T]) register() {} + +func (tracker[T]) onBorrow(*T) {} + +func (tracker[T]) onRedeem(*T) {} + +func (tracker[T]) borrowRedeemer(_ *T, cached func()) func() { return cached } + +// AssertNoLeaks reports whether every borrowed object has been redeemed across +// all pools. +// +// It is only meaningful in the instrumented build (-tags poolsdebug). +// +// In a release build it is a no-op that always reports true, so the same test +// can run in both modes. +func AssertNoLeaks(TB) bool { return true } + +// ResetTracking clears all recorded borrow/redeem tracking. +// +// This is a no-op in a release build. +func ResetTracking() {} diff --git a/vendor/github.com/go-openapi/swag/pools/debug_on.go b/vendor/github.com/go-openapi/swag/pools/debug_on.go new file mode 100644 index 00000000000..64ccc57d38f --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/debug_on.go @@ -0,0 +1,237 @@ +//go:build poolsdebug + +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +import ( + "fmt" + "runtime" + "sync" +) + +// This is the instrumented implementation of the pool tracking, enabled with +// -tags poolsdebug. +// +// Each pool carries a tracker that records, per recycled pointer, whether it is +// currently borrowed or redeemed, together with the call sites of the last +// borrow and redeem. +// It panics loudly (with those call sites) when it detects misuse: +// +// - a double redeem (the same object returned to the pool twice — corrupts sync.Pool); +// - for the redeemable pools, a redeem of a stale borrow (the slot was re-borrowed since — the +// ABA case the production atomic guard cannot catch), thanks to a per-borrow generation; +// - a redeem of an object the pool never handed out; +// - a borrow of an object still checked out (a symptom of an earlier double-Put). +// +// Borrowed-but-never-redeemed objects (leaks) are reported by [AssertNoLeaks]. + +// debugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug tag). +const debugBuild = true + +// DebugBuild reports whether the pool instrumentation is compiled in (the +// poolsdebug build tag). +// +// See the release-build doc for usage. +const DebugBuild = debugBuild + +type trackStatus uint8 + +const ( + trackBorrowed trackStatus = iota + 1 + trackRedeemed +) + +type trackEntry struct { + status trackStatus + gen uint64 // identifies the current borrow, to detect a redeem racing a re-borrow (ABA) + borrowedAt string + redeemedAt string +} + +type tracker[T any] struct { + mu sync.Mutex + entries map[*T]*trackEntry + nextGen uint64 +} + +func (t *tracker[T]) register() { + t.mu.Lock() + if t.entries == nil { + t.entries = make(map[*T]*trackEntry) + } + t.mu.Unlock() + + registerLeakChecker(t) +} + +// markBorrow records a borrow of ptr and returns its generation. +// +// Caller must hold no lock. +func (t *tracker[T]) markBorrow(ptr *T, site string) uint64 { + t.mu.Lock() + defer t.mu.Unlock() + + e := t.entries[ptr] + if e == nil { + e = &trackEntry{} + t.entries[ptr] = e + } else if e.status == trackBorrowed { + panic(fmt.Sprintf( + "pools: borrow of an object still checked out (borrowed at %s); "+ + "this usually means it was redeemed twice earlier", e.borrowedAt)) + } + + t.nextGen++ + e.status = trackBorrowed + e.gen = t.nextGen + e.borrowedAt = site + + return t.nextGen +} + +// markRedeem validates and records a redeem of ptr. gen is the borrow +// generation the caller is redeeming, or 0 to skip the ABA check (plain +// Pool[T], which has no per-borrow token). +func (t *tracker[T]) markRedeem(ptr *T, gen uint64, site string) { + t.mu.Lock() + defer t.mu.Unlock() + + e := t.entries[ptr] + switch { + case e == nil: + panic("pools: redeem of an object this pool never handed out") + case e.status != trackBorrowed: + panic(fmt.Sprintf("pools: double redeem (first redeemed at %s)", e.redeemedAt)) + case gen != 0 && e.gen != gen: + panic(fmt.Sprintf( + "pools: redeem of a stale borrow (the slot was re-borrowed at %s since this borrow); "+ + "a redeem is racing a re-borrow of the same slot (ABA)", e.borrowedAt)) + } + + e.status = trackRedeemed + e.redeemedAt = site +} + +const stackOffset = 3 + +func (t *tracker[T]) onBorrow(ptr *T) { + t.markBorrow(ptr, caller(stackOffset)) +} + +func (t *tracker[T]) onRedeem(ptr *T) { + t.markRedeem(ptr, 0, caller(stackOffset)) +} + +// borrowRedeemer records the borrow and returns a generation-stamped redeemer +// that validates the redeem (catching double-redeem and ABA) before delegating +// to the cached redeemer. +func (t *tracker[T]) borrowRedeemer(ptr *T, cached func()) func() { + gen := t.markBorrow(ptr, caller(stackOffset)) + + return func() { + t.markRedeem(ptr, gen, caller(stackOffset-1)) + cached() + } +} + +func (t *tracker[T]) checkLeaks(tb TB) bool { + t.mu.Lock() + defer t.mu.Unlock() + + ok := true + for _, e := range t.entries { + if e.status != trackRedeemed { + tb.Logf("pools: object borrowed but never redeemed (borrowed at %s)", e.borrowedAt) + ok = false + } + } + + return ok +} + +func (t *tracker[T]) resetTracking() { + t.mu.Lock() + t.entries = make(map[*T]*trackEntry) + t.nextGen = 0 + t.mu.Unlock() +} + +// leakChecker is the build-erased view of a tracker that the global registry +// holds, so trackers of different element types can be checked uniformly. +type leakChecker interface { + checkLeaks(tb TB) bool + resetTracking() +} + +var ( + registryMu sync.Mutex + registry []leakChecker +) + +func registerLeakChecker(c leakChecker) { + registryMu.Lock() + registry = append(registry, c) + registryMu.Unlock() +} + +// AssertNoLeaks reports whether every borrowed object has been redeemed across +// all pools created so far. +// +// It logs the borrow call site of each leaked object and fails tb when any are +// found. +// +// Typical use, with [ResetTracking] to isolate the test from earlier ones: +// +// func TestX(t *testing.T) { +// pools.ResetTracking() +// t.Cleanup(func() { pools.AssertNoLeaks(t) }) +// // ... exercise code that borrows/redeems ... +// } +func AssertNoLeaks(tb TB) bool { + tb.Helper() + registryMu.Lock() + defer registryMu.Unlock() + + ok := true + for _, c := range registry { + if !c.checkLeaks(tb) { + ok = false + } + } + if !ok { + tb.Errorf("pools: leaked pooled objects detected (borrowed but never redeemed)") + } + + return ok +} + +// ResetTracking clears all recorded borrow/redeem tracking across every pool. +// +// Call it at the start of a test so leaks from earlier tests are not attributed +// to it. +func ResetTracking() { + registryMu.Lock() + defer registryMu.Unlock() + + for _, c := range registry { + c.resetTracking() + } +} + +// caller returns "file:line" of the frame skip levels above caller itself. +func caller(skip int) string { + pc, _, _, ok := runtime.Caller(skip) + if !ok { + return "unknown" + } + fn := runtime.FuncForPC(pc) + if fn == nil { + return "unknown" + } + file, line := fn.FileLine(pc) + + return fmt.Sprintf("%s:%d", file, line) +} diff --git a/vendor/github.com/go-openapi/swag/pools/doc.go b/vendor/github.com/go-openapi/swag/pools/doc.go new file mode 100644 index 00000000000..395c24d29a6 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/doc.go @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Package pools provide utilities to recycle allocated objects. +// +// This package provides: +// +// - a generic [Pool] type that wraps [sync.Pool], +// - a [PoolRedeemable] variant that hands out a cached redeem closure, +// - a [PoolSlice] for recycling slices without juggling pointers. +// +// # Debug build +// +// Building with the "poolsdebug" tag (go test -tags poolsdebug ./...) turns on +// instrumentation that tracks every borrow and redeem and panics on misuse: +// +// - double redeem (including the A -> B -> A case for the redeemable pools), +// - redeem of a foreign object, +// - borrow of an object still checked out +// +// It reports the offending call sites. +// +// [AssertNoLeaks] then reports any object borrowed but never redeemed. +// +// The instrumentation is a no-op with zero overhead when the tag is absent. +package pools diff --git a/vendor/github.com/go-openapi/swag/pools/pools.go b/vendor/github.com/go-openapi/swag/pools/pools.go new file mode 100644 index 00000000000..d78ea5790a3 --- /dev/null +++ b/vendor/github.com/go-openapi/swag/pools/pools.go @@ -0,0 +1,410 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package pools + +import ( + "iter" + "slices" + "sync" + "sync/atomic" +) + +// Resettable is an interface for types that want to recycle a clean instance +// from a [Pool]. +// +// When T (or rather *T) implements [Resettable], the pool calls Reset on an +// instance both when it is redeemed and when it is borrowed: +// +// - on redeem, so that no references held by the instance are retained while it sits idle in the +// pool (which would pin a reference graph alive across a GC cycle); +// - on borrow, so that the next borrower receives a clean object regardless of how the instance +// reached the pool. +// +// Reset must be safe to call more than once on the same instance (it runs at +// least twice per cycle). +type Resettable interface { + Reset() +} + +// resetIfResettable calls Reset on v when *T implements [Resettable]. +func resetIfResettable[T any](v *T) { + if r, ok := any(v).(Resettable); ok { + r.Reset() + } +} + +// borrow state of a [redeemable] wrapper, used to detect double-redeem. +const ( + stateIdle uint32 = iota // sitting in the pool (or freshly created), not checked out + stateBorrowed // checked out by a borrower +) + +type redeemable[T any] struct { + inner *T + redeemer func() + // state guards against a double-redeem (the same wrapper Put into the pool + // twice, which would let one object be handed to two borrowers). + // + // It is set to stateBorrowed on borrow and atomically flipped back to + // stateIdle on redeem; a redeem that finds it already idle panics. + state atomic.Uint32 +} + +// redeemPanic is the message raised when a slot is redeemed while already idle. +const redeemPanic = "pools: " + + "double redeem detected (object already returned to the pool); " + + "a borrowed object must be redeemed exactly once" + +// Pool wraps a [sync.Pool] to make it available for any type. +// +// T must be the value type of the pooled object (e.g. Pool[bytes.Buffer]): +// [Pool.Borrow] returns a *T. Using a pointer type as T (e.g. +// Pool[*bytes.Buffer]) would yield a **T and is almost certainly a mistake. +type Pool[T any] struct { + pool sync.Pool + tracker tracker[T] // empty (zero-cost) unless built with the poolsdebug tag +} + +// PoolRedeemable wraps a [sync.Pool] to make it available for any type. +// +// It differs from [Pool] in the way objects are redeemed to the pool: borrowing +// also yields a cached redeem closure, so no closure is allocated at redeem +// time. +type PoolRedeemable[T any] struct { + pool sync.Pool + tracker tracker[redeemable[T]] // empty (zero-cost) unless built with the poolsdebug tag +} + +// New builds a new [Pool] to recycle allocations of type T explicitly using +// [Pool.Redeem] and the allocated pointer. +// +// Freshly allocated instances of type T are set to their zero value; like +// recycled instances they are reset (if [Resettable]) when borrowed, so +// [Pool.Borrow] always yields a clean object. +func New[T any]() *Pool[T] { + p := &Pool[T]{} + p.pool = sync.Pool{ + New: func() any { + return new(T) + }, + } + p.tracker.register() + + return p +} + +// NewRedeemable builds a new redeemable [Pool] to recycle allocations of type +// T, and use the inner redeemer to relinquish objects to the pool. +func NewRedeemable[T any]() *PoolRedeemable[T] { + p := &PoolRedeemable[T]{} + p.pool = sync.Pool{ + New: func() any { + r := &redeemable[T]{inner: new(T)} + r.redeemer = func() { + if !r.state.CompareAndSwap(stateBorrowed, stateIdle) { + panic(redeemPanic) + } + resetIfResettable(r.inner) + p.pool.Put(r) + } + + return r + }, + } + p.tracker.register() + + return p +} + +// Borrow an instance from the pool. +// +// If the type implements [Resettable], the returned instance is reset before +// being handed out, so it is always clean. +func (p *Pool[T]) Borrow() *T { + target := p.pool.Get().(*T) + resetIfResettable(target) + p.tracker.onBorrow(target) + + return target +} + +// Redeem a borrowed instance to the pool. +// +// A nil pointer is ignored (it would otherwise corrupt the pool: a typed-nil +// boxed into an interface is not the nil interface that [sync.Pool.Put] skips). +// +// The instance is reset (if it implements [Resettable]) before being returned +// to the pool. +// After calling Redeem, the caller must drop its reference to ptr: continuing +// to use it is a use-after-redeem bug. +// +// Unlike [PoolRedeemable], this plain pool holds no per-object state, so it +// cannot detect a double-redeem of the same pointer (which corrupts the pool). +// +// Prefer [PoolRedeemable] when you want that guard, or the debug build for full +// tracking. +func (p *Pool[T]) Redeem(ptr *T) { + if ptr == nil { + return + } + p.tracker.onRedeem(ptr) + resetIfResettable(ptr) + p.pool.Put(ptr) +} + +// BorrowWithRedeem borrows an instance from the pool and provides the +// corresponding redeem function. +// +// This is useful for instance to use with defer. +// +// The instance is reset (if it implements [Resettable]) both when borrowed and +// when the returned redeem closure is called. +// After calling the redeem closure, the caller must drop its reference to the +// returned instance. +// +// Calling the redeem closure more than once panics (see [redeemable.state]): a +// borrowed instance must be redeemed exactly once. +func (p *PoolRedeemable[T]) BorrowWithRedeem() (*T, func()) { + container := p.pool.Get().(*redeemable[T]) + container.state.Store(stateBorrowed) + resetIfResettable(container.inner) + + // In release builds borrowRedeemer returns container.redeemer unchanged (zero + // cost). + // Under the poolsdebug tag it returns a generation-stamped wrapper that tracks + // the borrow and detects double-redeem (incl. + // + // ABA), foreign-redeem and leaks. + return container.inner, p.tracker.borrowRedeemer(container, container.redeemer) +} + +// Slice is a struct that wraps a slice []T. +// +// This is useful to borrow and redeem slices from a pool, without having to +// constantly manipulate pointers to the slice. +// +// The wrapper holds the authoritative slice header. +// +// Its mutating methods ([Slice.Append], [Slice.Concat], [Slice.Grow]) return +// the current backing slice for convenience, so it reads as an idiomatic []T. +// +// But the returned slice is only a snapshot of the wrapper's state at that +// moment: if you keep it and grow it yourself with the builtin append and it +// reallocates, the new backing array lives only in your local copy and is NOT +// tracked by the wrapper — it will not be recycled when the wrapper is +// redeemed (and a later borrower would get the old, smaller array). +// +// Rule of thumb: it is fine to read or pass the returned []T to a consumer; but +// if you plan to grow the slice, keep calling the wrapper's methods so the +// growth is tracked and recycled. +type Slice[T any] struct { + length int + inner []T +} + +// Slice returns the inner slice. +// +// Treat the result as a read-only view (for ranging or passing to a consumer), +// valid until the next mutation or redeem. +// To grow or append, use the wrapper methods so the new backing array is +// tracked and recycled (see [Slice]). +func (s *Slice[T]) Slice() []T { + return s.inner +} + +// Grow the inner slice so it can accommodate at least size more elements +// without reallocating, and return the current backing slice. +// +// Growth is tracked by the wrapper, so the enlarged backing array is recycled +// on redeem. +// See [Slice] for the caveat about growing the returned slice yourself. +func (s *Slice[T]) Grow(size int) []T { + s.inner = slices.Grow(s.inner, size) + + return s.inner +} + +func (s *Slice[T]) Len() int { + return len(s.inner) +} + +func (s *Slice[T]) Cap() int { + return cap(s.inner) +} + +// Append elements to the inner slice and return the current backing slice. +// +// This should be preferred to the append builtin if you plan that the slice will +// grow and you want the newly allocated space to be tracked and recycled. +// See [Slice] for the caveat about growing the returned slice yourself. +func (s *Slice[T]) Append(elems ...T) []T { + s.inner = append(s.inner, elems...) + + return s.inner +} + +// Concat another slice to the inner slice and return the current backing slice. +// +// Unlike [slices.Concat], this reuses the inner slice's capacity instead of +// always allocating a fresh backing array. +// See [Slice] for the caveat about growing the returned slice yourself. +func (s *Slice[T]) Concat(slice []T) []T { + s.inner = append(s.inner, slice...) + + return s.inner +} + +// IndexedElems iterates over the inner slice. +func (s *Slice[T]) IndexedElems() iter.Seq2[int, T] { + return func(yield func(int, T) bool) { + for i, elem := range s.inner { + if !yield(i, elem) { + return + } + } + } +} + +// Reset the inner slice to its configured initial length, keeping allocated +// capacity. +// +// All elements are zeroed, so the pool never retains stale element references +// (which would keep a referenced graph alive for slices of pointers) and so a +// [WithLength] slice is handed out clean rather than carrying data from a +// previous borrower. +func (s *Slice[T]) Reset() { + clear(s.inner) + if s.length > cap(s.inner) { + s.inner = slices.Grow(s.inner[:0], s.length) + } + s.inner = s.inner[:s.length] +} + +// Clip removes unused capacity from the inner slice. +func (s *Slice[T]) Clip() { + s.inner = slices.Clip(s.inner) +} + +// resetWithCapacity discards the current backing array and replaces it with a +// fresh one of the configured length and the given capacity. +// +// It is used by a capacity-capped pool to stop recycling an oversized backing +// array (the old array is left for the GC). +func (s *Slice[T]) resetWithCapacity(capacity int) { + s.inner = make([]T, s.length, max(s.length, capacity)) +} + +// PoolSlice is a pool of [Slice[T]]. +// +// [PoolSlice.BorrowWithRedeem] will return an empty inner slice by default. +// This default may be altered using [WithMinimumCapacity]. +// +// Use [PoolSlice.BorrowWithSizeAndRedeem] or [Slice.Grow] to grow the capacity +// of the inner slice. +type PoolSlice[T any] struct { + // redeemable is held as an unexported field rather than embedded, so the + // underlying [PoolRedeemable] and its [sync.Pool] are not part of PoolSlice's + // public surface. + redeemable *PoolRedeemable[Slice[T]] +} + +// PoolSliceOption alters the default settings to allocate new pooled slices +type PoolSliceOption func(*poolSliceOptions) + +type poolSliceOptions struct { + minCapacity int + length int + maxCapacity int +} + +func WithMinimumCapacity(size int) PoolSliceOption { + return func(o *poolSliceOptions) { + o.minCapacity = size + } +} + +// WithMaxCapacity bounds the capacity of recycled slices. +// +// When a borrowed slice has grown past size at redeem time, its (oversized) +// backing array is discarded and replaced with a fresh one sized to the minimum +// capacity, instead of being recycled. +// +// This stops the pool from accumulating large backing arrays after an +// occasional large request, keeping the steady-state memory bounded. +// +// The trade-off: a workload that genuinely needs slices larger than size will +// reallocate on every cycle. +// Set size from the high-water mark you actually expect, not below it. +// A size of 0 (the default) means no cap: grown slices are recycled as-is. +func WithMaxCapacity(size int) PoolSliceOption { + return func(o *poolSliceOptions) { + o.maxCapacity = size + } +} + +// WithLength ensures that the borrowed slices have a fixed given initial +// length. +// +// By default, the borrowed slices are reset to length 0. +func WithLength(size int) PoolSliceOption { + return func(o *poolSliceOptions) { + o.length = size + } +} + +// NewPoolSlice builds a pool to recycle slices of type []T. +func NewPoolSlice[T any](opts ...PoolSliceOption) *PoolSlice[T] { + var o poolSliceOptions + for _, apply := range opts { + apply(&o) + } + + rp := &PoolRedeemable[Slice[T]]{} + rp.pool = sync.Pool{ + New: func() any { + s := &redeemable[Slice[T]]{ + inner: &Slice[T]{ + length: o.length, + inner: make([]T, o.length, max(o.length, o.minCapacity)), + }, + } + + s.redeemer = func() { + if !s.state.CompareAndSwap(stateBorrowed, stateIdle) { + panic(redeemPanic) + } + if o.maxCapacity > 0 && s.inner.Cap() > o.maxCapacity { + s.inner.resetWithCapacity(o.minCapacity) + } else { + s.inner.Reset() + } + rp.pool.Put(s) + } + + return s + }, + } + rp.tracker.register() + + return &PoolSlice[T]{redeemable: rp} +} + +// BorrowWithRedeem returns the slice wrapper and the redeem closure to +// relinquish the allocated wrapper. +// +// The wrapper is reset (elements zeroed, length restored) both on borrow and +// when the redeem closure is called. +// Calling the redeem closure more than once panics. +func (p *PoolSlice[T]) BorrowWithRedeem() (*Slice[T], func()) { + return p.redeemable.BorrowWithRedeem() +} + +// BorrowWithSizeAndRedeem borrows a slice []T from the pool and ensures that +// its capacity is at least the provided size. +func (p *PoolSlice[T]) BorrowWithSizeAndRedeem(size int) (*Slice[T], func()) { + s, redeem := p.BorrowWithRedeem() + s.Grow(size) + + return s, redeem +} diff --git a/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go b/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go index 3daf68dbba0..24d951f8de0 100644 --- a/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go +++ b/vendor/github.com/go-openapi/swag/yamlutils/ordered_map.go @@ -123,7 +123,7 @@ func (s YAMLMapSlice) MarshalYAML() (any, error) { var nodes []*yaml.Node for _, item := range s { - nn, err := json2yaml(item.Value) + nn, err := json2yaml(item.Value, 1) if err != nil { return nil, err } @@ -153,6 +153,17 @@ func (s YAMLMapSlice) MarshalYAML() (any, error) { // // It implements [yaml.Unmarshaler]. func (s *YAMLMapSlice) UnmarshalYAML(node *yaml.Node) error { + return s.unmarshalYAML(newYAMLWalker(), node, 0) +} + +// unmarshalYAML builds the slice from a [yaml.Node], tracking the recursion depth (against +// stack-overflow) and threading the [yamlWalker] so anchor/alias expansion stays bounded +// across the whole document. +func (s *YAMLMapSlice) unmarshalYAML(w *yamlWalker, node *yaml.Node, depth int) error { + if depth > defaultMaxNestingDepth { + return errMaxNestingDepth + } + if typeutils.IsNil(*s) { // allow to unmarshal with a simple var declaration (nil slice) *s = YAMLMapSlice{} @@ -167,13 +178,17 @@ func (s *YAMLMapSlice) UnmarshalYAML(node *yaml.Node) error { m = m[:0] for i := 0; i < len(node.Content); i += 2 { + if err := w.account(); err != nil { // account the key node + return err + } + var nmi YAMLMapItem k, err := yamlStringScalarC(node.Content[i]) if err != nil { return fmt.Errorf("unable to decode YAML map key: %w: %w", err, ErrYAML) } nmi.Key = k - v, err := yamlNode(node.Content[i+1]) + v, err := w.node(node.Content[i+1], depth+1) if err != nil { return fmt.Errorf("unable to process YAML map value for key %q: %w: %w", k, err, ErrYAML) } @@ -186,7 +201,11 @@ func (s *YAMLMapSlice) UnmarshalYAML(node *yaml.Node) error { return nil } -func json2yaml(item any) (*yaml.Node, error) { +func json2yaml(item any, depth int) (*yaml.Node, error) { + if depth > defaultMaxNestingDepth { + return nil, errMaxNestingDepth + } + if typeutils.IsNil(item) { return &yaml.Node{ Kind: yaml.ScalarNode, @@ -196,7 +215,7 @@ func json2yaml(item any) (*yaml.Node, error) { switch val := item.(type) { case ifaces.Ordered: - return orderedYAML(val) + return orderedYAML(val, depth) case map[string]any: var n yaml.Node @@ -209,7 +228,7 @@ func json2yaml(item any) (*yaml.Node, error) { for _, k := range keys { v := val[k] - childNode, err := json2yaml(v) + childNode, err := json2yaml(v, depth+1) if err != nil { return nil, err } @@ -225,7 +244,7 @@ func json2yaml(item any) (*yaml.Node, error) { var n yaml.Node n.Kind = yaml.SequenceNode for i := range val { - childNode, err := json2yaml(val[i]) + childNode, err := json2yaml(val[i], depth+1) if err != nil { return nil, err } @@ -297,11 +316,11 @@ func uintegerNode[T conv.Unsigned](val T) (*yaml.Node, error) { }, nil } -func orderedYAML[T ifaces.Ordered](val T) (*yaml.Node, error) { +func orderedYAML[T ifaces.Ordered](val T, depth int) (*yaml.Node, error) { var n yaml.Node n.Kind = yaml.MappingNode for key, value := range val.OrderedItems() { - childNode, err := json2yaml(value) + childNode, err := json2yaml(value, depth+1) if err != nil { return nil, err } diff --git a/vendor/github.com/go-openapi/swag/yamlutils/yaml.go b/vendor/github.com/go-openapi/swag/yamlutils/yaml.go index e3aff3c2fde..d4b5335f6f2 100644 --- a/vendor/github.com/go-openapi/swag/yamlutils/yaml.go +++ b/vendor/github.com/go-openapi/swag/yamlutils/yaml.go @@ -12,13 +12,99 @@ import ( yaml "go.yaml.in/yaml/v3" ) +// defaultMaxNestingDepth caps the recursion depth of the YAML<->JSON transforms to +// guard against stack-overflow on deeply nested (possibly adversarial) input. +// +// It matches the limit enforced by go.yaml.in/yaml/v3's own parser and by +// encoding/json's decoder. +const defaultMaxNestingDepth = 10000 + +// Bounds on YAML anchor/alias expansion. +// +// go.yaml.in/yaml/v3 enforces these when decoding into Go values, but that guard is +// coupled to the library's own tree walk: when we decode into a low-level [yaml.Node] +// (to preserve key order) and expand aliases ourselves in [yamlWalker.node], we bypass +// it. We therefore reproduce it here, with the same constants and ratio schedule as the +// library's decoder (see go.yaml.in/yaml/v3 decode.go, "excessive aliasing"). +const ( + aliasCountThreshold = 100 + decodeCountThreshold = 1000 + + // 400,000 decode operations is ~500kb of dense object declarations, or + // ~5kb of dense object declarations with 10000% alias expansion. + aliasRatioRangeLow = 400000 + // 4,000,000 decode operations is ~5MB of dense object declarations. + aliasRatioRangeHigh = 4000000 + aliasRatioRange = float64(aliasRatioRangeHigh - aliasRatioRangeLow) + + // tolerated share of alias-driven decodes: from aliasRatioSmall (small/medium documents) + // down to aliasRatioLarge (very large ones), interpolated with slope aliasRatioSlope. + aliasRatioSmall = 0.99 + aliasRatioLarge = 0.10 + aliasRatioSlope = aliasRatioSmall - aliasRatioLarge +) + +var ( + // errMaxNestingDepth is returned when a document nests deeper than [defaultMaxNestingDepth]. + errMaxNestingDepth = fmt.Errorf("maximum nesting depth of %d exceeded: %w", defaultMaxNestingDepth, ErrYAML) + + // errExcessiveAliasing is returned when anchor/alias expansion is disproportionate to the + // size of the document, i.e. an "alias bomb". + errExcessiveAliasing = fmt.Errorf("document contains excessive aliasing: %w", ErrYAML) +) + +// allowedAliasRatio scales the tolerated share of alias-driven decode operations from 99% +// for small-to-medium documents down to 10% for very large ones, mirroring go.yaml.in/yaml/v3. +func allowedAliasRatio(decodeCount int) float64 { + switch { + case decodeCount <= aliasRatioRangeLow: + return aliasRatioSmall + case decodeCount >= aliasRatioRangeHigh: + return aliasRatioLarge + default: + return aliasRatioSmall - aliasRatioSlope*(float64(decodeCount-aliasRatioRangeLow)/aliasRatioRange) + } +} + +// yamlWalker carries the state needed to bound a single YAML-tree traversal: +// anchor/alias expansion accounting and cycle detection. +// +// A fresh walker is created per top-level conversion; it is threaded (not copied) through +// the whole recursive walk so its counters accumulate across the entire document. +type yamlWalker struct { + decodeCount int + aliasCount int + aliasDepth int + aliases map[*yaml.Node]bool // anchors currently being expanded, for cycle detection +} + +func newYAMLWalker() *yamlWalker { + return &yamlWalker{aliases: make(map[*yaml.Node]bool)} +} + +// account records one processed node and fails if alias expansion has become excessive. +func (w *yamlWalker) account() error { + w.decodeCount++ + if w.aliasDepth > 0 { + w.aliasCount++ + } + + if w.aliasCount > aliasCountThreshold && + w.decodeCount > decodeCountThreshold && + float64(w.aliasCount)/float64(w.decodeCount) > allowedAliasRatio(w.decodeCount) { + return errExcessiveAliasing + } + + return nil +} + // YAMLToJSON converts a YAML document into JSON bytes. // // Note: a YAML document is the output from a [yaml.Marshaler], e.g a pointer to a [yaml.Node]. // // [YAMLToJSON] is typically called after [BytesToYAMLDoc]. func YAMLToJSON(value any) (json.RawMessage, error) { - jm, err := transformData(value) + jm, err := transformData(value, 0) if err != nil { return nil, err } @@ -44,46 +130,73 @@ func BytesToYAMLDoc(data []byte) (any, error) { return &document, nil } -func yamlNode(root *yaml.Node) (any, error) { +func (w *yamlWalker) node(root *yaml.Node, depth int) (any, error) { + if depth > defaultMaxNestingDepth { + return nil, errMaxNestingDepth + } + if err := w.account(); err != nil { + return nil, err + } + switch root.Kind { case yaml.DocumentNode: - return yamlDocument(root) + return w.document(root, depth) case yaml.SequenceNode: - return yamlSequence(root) + return w.sequence(root, depth) case yaml.MappingNode: - return yamlMapping(root) + return w.mapping(root, depth) case yaml.ScalarNode: return yamlScalar(root) case yaml.AliasNode: - return yamlNode(root.Alias) + return w.alias(root, depth) default: return nil, fmt.Errorf("unsupported YAML node type: %v: %w", root.Kind, ErrYAML) } } -func yamlDocument(node *yaml.Node) (any, error) { +// alias resolves an anchor reference, expanding the anchored subtree. It detects cycles +// (an anchor whose expansion transitively references itself) and accounts the expansion +// against the alias-bomb budget via [yamlWalker.aliasDepth]. +func (w *yamlWalker) alias(node *yaml.Node, depth int) (any, error) { + if node.Alias == nil { + return nil, fmt.Errorf("invalid YAML alias node %q: %w", node.Value, ErrYAML) + } + if w.aliases[node.Alias] { + return nil, fmt.Errorf("anchor %q contains itself: %w", node.Value, ErrYAML) + } + + w.aliases[node.Alias] = true + w.aliasDepth++ + out, err := w.node(node.Alias, depth+1) + w.aliasDepth-- + delete(w.aliases, node.Alias) + + return out, err +} + +func (w *yamlWalker) document(node *yaml.Node, depth int) (any, error) { if len(node.Content) != 1 { return nil, fmt.Errorf("unexpected YAML Document node content length: %d: %w", len(node.Content), ErrYAML) } - return yamlNode(node.Content[0]) + return w.node(node.Content[0], depth+1) } -func yamlMapping(node *yaml.Node) (any, error) { +func (w *yamlWalker) mapping(node *yaml.Node, depth int) (any, error) { const sensibleAllocDivider = 2 // nodes concatenate (key,value) sequences m := make(YAMLMapSlice, len(node.Content)/sensibleAllocDivider) - if err := m.UnmarshalYAML(node); err != nil { + if err := m.unmarshalYAML(w, node, depth); err != nil { return nil, err } return m, nil } -func yamlSequence(node *yaml.Node) (any, error) { +func (w *yamlWalker) sequence(node *yaml.Node, depth int) (any, error) { s := make([]any, 0) for i := range len(node.Content) { - v, err := yamlNode(node.Content[i]) + v, err := w.node(node.Content[i], depth+1) if err != nil { return nil, fmt.Errorf("unable to decode YAML sequence value: %w: %w", err, ErrYAML) } @@ -174,12 +287,16 @@ func format(t any) (string, error) { } } -func transformData(input any) (out any, err error) { +func transformData(input any, depth int) (out any, err error) { + if depth > defaultMaxNestingDepth { + return nil, errMaxNestingDepth + } + switch in := input.(type) { case yaml.Node: - return yamlNode(&in) + return newYAMLWalker().node(&in, depth) case *yaml.Node: - return yamlNode(in) + return newYAMLWalker().node(in, depth) case map[any]any: o := make(YAMLMapSlice, 0, len(in)) for ke, va := range in { @@ -188,7 +305,7 @@ func transformData(input any) (out any, err error) { return nil, err } - v, ert := transformData(va) + v, ert := transformData(va, depth+1) if ert != nil { return nil, ert } @@ -200,7 +317,7 @@ func transformData(input any) (out any, err error) { len1 := len(in) o := make([]any, len1) for i := range len1 { - o[i], err = transformData(in[i]) + o[i], err = transformData(in[i], depth+1) if err != nil { return nil, err } diff --git a/vendor/github.com/go-openapi/validate/CONTRIBUTORS.md b/vendor/github.com/go-openapi/validate/CONTRIBUTORS.md index 7b79b765dc3..40d877a1175 100644 --- a/vendor/github.com/go-openapi/validate/CONTRIBUTORS.md +++ b/vendor/github.com/go-openapi/validate/CONTRIBUTORS.md @@ -4,12 +4,12 @@ | Total Contributors | Total Contributions | | --- | --- | -| 31 | 295 | +| 31 | 310 | | Username | All Time Contribution Count | All Commits | | --- | --- | --- | | @casualjim | 169 | | -| @fredbi | 58 | | +| @fredbi | 73 | | | @sttts | 11 | | | @youyuanwu | 9 | | | @keramix | 8 | | @@ -40,4 +40,4 @@ | @dadgar | 1 | | | @elakito | 1 | | - _this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_ + _this file was generated by the [Contributors GitHub Action](https://github.com/github-community-projects/contributors)_ diff --git a/vendor/github.com/go-openapi/validate/README.md b/vendor/github.com/go-openapi/validate/README.md index fec42b7c6ed..b814a2ef126 100644 --- a/vendor/github.com/go-openapi/validate/README.md +++ b/vendor/github.com/go-openapi/validate/README.md @@ -18,12 +18,9 @@ A validator for OpenAPI v2 specifications and JSON schema draft 4. * **2025-12-19** : new community chat on discord * a new discord community channel is available to be notified of changes and support users - * our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31** You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url] -Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url] - ## Status API is stable. @@ -75,9 +72,9 @@ This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE). ## Other documentation * [All-time contributors](./CONTRIBUTORS.md) -* [Contributing guidelines](.github/CONTRIBUTING.md) -* [Maintainers documentation](docs/MAINTAINERS.md) -* [Code style](docs/STYLE.md) +* [Contributing guidelines][contributing-doc-site] +* [Maintainers documentation][maintainers-doc-site] +* [Code style][style-doc-site] ## Cutting a new release @@ -108,11 +105,8 @@ Maintainers can cut a new release by either: [godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/validate [godoc-url]: http://pkg.go.dev/github.com/go-openapi/validate -[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png -[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM -[slack-url]: https://goswagger.slack.com/archives/C04R30YMU [discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue -[discord-url]: https://discord.gg/twZ9BwT3 +[discord-url]: https://discord.gg/FfnFYaC3k5 [license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg @@ -122,3 +116,7 @@ Maintainers can cut a new release by either: [goversion-url]: https://github.com/go-openapi/validate/blob/master/go.mod [top-badge]: https://img.shields.io/github/languages/top/go-openapi/validate [commits-badge]: https://img.shields.io/github/commits-since/go-openapi/validate/latest + +[contributing-doc-site]: https://go-openapi.github.io/doc-site/contributing/contributing/index.html +[maintainers-doc-site]: https://go-openapi.github.io/doc-site/maintainers/index.html +[style-doc-site]: https://go-openapi.github.io/doc-site/contributing/style/index.html diff --git a/vendor/github.com/go-openapi/validate/helpers.go b/vendor/github.com/go-openapi/validate/helpers.go index 8a1a2312830..7cc254e02ea 100644 --- a/vendor/github.com/go-openapi/validate/helpers.go +++ b/vendor/github.com/go-openapi/validate/helpers.go @@ -242,9 +242,9 @@ func (h *paramHelper) resolveParam(path, method, operationID string, param *spec res := new(Result) isRef := param.Ref.String() != "" if s.spec.SpecFilePath() == "" { - err = spec.ExpandParameterWithRoot(param, s.spec.Spec(), nil) + err = spec.ExpandParameterWithOptions(param, s.spec.Spec(), nil, s.schemaOptions.expandOptions("")) } else { - err = spec.ExpandParameter(param, s.spec.SpecFilePath()) + err = spec.ExpandParameterWithOptions(param, nil, nil, s.schemaOptions.expandOptions(s.spec.SpecFilePath())) } if err != nil { // Safeguard // NOTE: we may enter here when the whole parameter is an unresolved $ref @@ -295,9 +295,9 @@ func (r *responseHelper) expandResponseRef( res := new(Result) if s.spec.SpecFilePath() == "" { // there is no physical document to resolve $ref in response - err = spec.ExpandResponseWithRoot(response, s.spec.Spec(), nil) + err = spec.ExpandResponseWithOptions(response, s.spec.Spec(), nil, s.schemaOptions.expandOptions("")) } else { - err = spec.ExpandResponse(response, s.spec.SpecFilePath()) + err = spec.ExpandResponseWithOptions(response, nil, nil, s.schemaOptions.expandOptions(s.spec.SpecFilePath())) } if err != nil { // Safeguard // NOTE: we may enter here when the whole response is an unresolved $ref. diff --git a/vendor/github.com/go-openapi/validate/schema.go b/vendor/github.com/go-openapi/validate/schema.go index b72a47bc331..706b7f5ef67 100644 --- a/vendor/github.com/go-openapi/validate/schema.go +++ b/vendor/github.com/go-openapi/validate/schema.go @@ -63,18 +63,18 @@ func newSchemaValidator(schema *spec.Schema, rootSchema any, root string, format rootSchema = schema } + if opts == nil { + opts = new(SchemaValidatorOptions) + } + if schema.ID != "" || schema.Ref.String() != "" || schema.Ref.IsRoot() { - err := spec.ExpandSchema(schema, rootSchema, nil) + err := spec.ExpandSchemaWithOptions(schema, rootSchema, nil, opts.expandOptions("")) if err != nil { msg := invalidSchemaProvidedMsg(err).Error() panic(msg) } } - if opts == nil { - opts = new(SchemaValidatorOptions) - } - var s *SchemaValidator if opts.recycleValidators { s = pools.poolOfSchemaValidators.BorrowValidator() diff --git a/vendor/github.com/go-openapi/validate/schema_option.go b/vendor/github.com/go-openapi/validate/schema_option.go index 3e1b882ed38..3ca489c0f54 100644 --- a/vendor/github.com/go-openapi/validate/schema_option.go +++ b/vendor/github.com/go-openapi/validate/schema_option.go @@ -3,6 +3,13 @@ package validate +import ( + "encoding/json" + + "github.com/go-openapi/spec" + "github.com/go-openapi/swag/loading" +) + // SchemaValidatorOptions defines optional rules for schema validation. type SchemaValidatorOptions struct { EnableObjectArrayTypeCheck bool @@ -10,6 +17,7 @@ type SchemaValidatorOptions struct { recycleValidators bool recycleResult bool skipSchemataResult bool + pathLoaderWithOptions func(string, ...loading.Option) (json.RawMessage, error) } // Option sets optional rules for schema validation. @@ -60,6 +68,23 @@ func WithSkipSchemataResult(enable bool) Option { } } +// WithPathLoader injects the document loader used to resolve remote and relative $ref while +// validating a schema or specification. It matches the option-aware loader signature of +// github.com/go-openapi/swag/loading (and go-openapi/loads). +// +// This lets validation resolve references through a caller-provided loader instead of the spec +// package's global default. The loader may carry any loading options — a custom HTTP client or +// timeout, authentication or custom headers, an embedded or rooted file system, and so on. +// +// One important use is confining loading of untrusted input: build the loader with loading.WithRoot +// (to confine local reads) and loading.WithHTTPClient (to restrict remote fetches), or use a +// restricted loader from go-openapi/loads. Left unset, the spec package default loader is used. +func WithPathLoader(loader func(string, ...loading.Option) (json.RawMessage, error)) Option { + return func(svo *SchemaValidatorOptions) { + svo.pathLoaderWithOptions = loader + } +} + // Options returns the current set of options. func (svo SchemaValidatorOptions) Options() []Option { return []Option{ @@ -68,5 +93,17 @@ func (svo SchemaValidatorOptions) Options() []Option { WithRecycleValidators(svo.recycleValidators), withRecycleResults(svo.recycleResult), WithSkipSchemataResult(svo.skipSchemataResult), + WithPathLoader(svo.pathLoaderWithOptions), + } +} + +// expandOptions builds the spec expand options for schema/$ref expansion during validation, +// carrying the injected loader (when set) so resolution can be confined. relativeBase is used for +// base-path-relative resolution; it is ignored by [spec.ExpandSchemaWithOptions], which derives the +// base from the root. +func (svo *SchemaValidatorOptions) expandOptions(relativeBase string) *spec.ExpandOptions { + return &spec.ExpandOptions{ + RelativeBase: relativeBase, + PathLoaderWithOptions: svo.pathLoaderWithOptions, } } diff --git a/vendor/github.com/go-openapi/validate/spec.go b/vendor/github.com/go-openapi/validate/spec.go index b85432f92b1..d6a61eae29c 100644 --- a/vendor/github.com/go-openapi/validate/spec.go +++ b/vendor/github.com/go-openapi/validate/spec.go @@ -25,6 +25,9 @@ import ( // // Returns an error flattening in a single standard error, all validation messages. // +// Options are forwarded to the underlying [SpecValidator]; in particular [WithPathLoader] injects a +// confined document loader for validating a specification from an untrusted source. +// // - Proposal for enhancement: $ref should not have siblings // - Proposal for enhancement: make sure documentation reflects all checks and warnings // - Proposal for enhancement: check on discriminators @@ -35,8 +38,8 @@ import ( // - Proposal for enhancement: check on required properties to support anyOf, allOf, oneOf // // NOTE: SecurityScopes are maps: no need to check uniqueness. -func Spec(doc *loads.Document, formats strfmt.Registry) error { - errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats).Validate(doc) +func Spec(doc *loads.Document, formats strfmt.Registry, options ...Option) error { + errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats, options...).Validate(doc) if errs.HasErrors() { return errors.CompositeValidationError(errs.Errors...) } @@ -55,14 +58,20 @@ type SpecValidator struct { } // NewSpecValidator creates a new swagger spec validator instance. -func NewSpecValidator(schema *spec.Schema, formats strfmt.Registry) *SpecValidator { - // schema options that apply to all called validators +// +// Options apply to the schema validators used internally. In particular, [WithPathLoader] injects +// the document loader used to resolve $ref while validating the specification — set a confined +// loader when validating a specification from an untrusted source (see the package "Security" +// notes on [WithPathLoader]). +func NewSpecValidator(schema *spec.Schema, formats strfmt.Registry, options ...Option) *SpecValidator { + // schema options that apply to all called validators: built-in defaults first, then + // caller-supplied options (which may add a loader or override a default). schemaOptions := new(SchemaValidatorOptions) - for _, o := range []Option{ + for _, o := range append([]Option{ SwaggerSchema(true), WithRecycleValidators(true), // withRecycleResults(true), - } { + }, options...) { o(schemaOptions) } @@ -146,7 +155,8 @@ func (s *SpecValidator) Validate(data any) (*Result, *Result) { errs.Merge(s.validateNonEmptyPathParamNames()) // errs.Merge(s.validateRefNoSibling()) // warning only - errs.Merge(s.validateReferenced()) // warning only + errs.Merge(s.validateReferenced()) // warning only + errs.Merge(s.validateDubiousRefs()) // warning only return errs, warnings } @@ -251,7 +261,7 @@ func (s *SpecValidator) validateDuplicatePropertyNames() *Result { func (s *SpecValidator) resolveRef(ref *spec.Ref) (*spec.Schema, error) { if s.spec.SpecFilePath() != "" { - return spec.ResolveRefWithBase(s.spec.Spec(), ref, &spec.ExpandOptions{RelativeBase: s.spec.SpecFilePath()}) + return spec.ResolveRefWithBase(s.spec.Spec(), ref, s.schemaOptions.expandOptions(s.spec.SpecFilePath())) } // NOTE: it looks like with the new spec resolver, this code is now unrecheable return spec.ResolveRef(s.spec.Spec(), ref) @@ -553,8 +563,12 @@ DEFINITIONS: if schema.Required != nil { // Safeguard for _, pn := range schema.Required { red := s.validateRequiredProperties(pn, d, &schema) //#nosec + // NOTE: capture validity before merging: Merge may redeem `red` to the + // pool (wantsRedeemOnMerge), after which reading it races with a concurrent + // BorrowResult().cleared() in another goroutine sharing the global pool. + isValid := red.IsValid() res.Merge(red) - if !red.IsValid() && !s.Options.ContinueOnErrors { + if !isValid && !s.Options.ContinueOnErrors { break DEFINITIONS // there is an error, let's stop that bleeding } } @@ -784,7 +798,10 @@ func (s *SpecValidator) validateReferencesValid() *Result { // NOTE: with default settings, loads.Document.Expanded() // stops on first error. Anyhow, the expand option to continue // on errors fails to report errors at all. - exp, err := s.spec.Expanded() + // + // Pass the injected loader (if any) so whole-spec expansion is confined too. When no loader + // is set, this is a no-op: loads falls back to the document's own loader. + exp, err := s.spec.Expanded(s.schemaOptions.expandOptions("")) if err != nil { res.AddErrors(unresolvedReferencesMsg(err)) } diff --git a/vendor/github.com/go-openapi/validate/spec_messages.go b/vendor/github.com/go-openapi/validate/spec_messages.go index 42ce3602852..eeb8a869518 100644 --- a/vendor/github.com/go-openapi/validate/spec_messages.go +++ b/vendor/github.com/go-openapi/validate/spec_messages.go @@ -177,6 +177,18 @@ const ( // UnusedResponseWarning ... UnusedResponseWarning = "response %q is not used anywhere" + // DubiousAbsoluteRefWarning flags a $ref pointing to an absolute local file location that escapes the + // spec's base path. Absolute local references are legitimate when they stay beneath the base path + // (flattening/expansion introduces such anchors for cyclical $refs), but an absolute reference that + // escapes the base path - or a file:// reference in a spec with no known base - may indicate an + // unsafe or adversarial spec. + DubiousAbsoluteRefWarning = "$ref %q points to an absolute or local file location that escapes the spec's base path: this may be unsafe with adversarial specs" + + // DubiousMultipleHostsWarning flags a spec whose remote $refs resolve to several distinct hosts. + // A single consistent remote host is common and legitimate; references spread across multiple hosts + // may indicate an unsafe or adversarial spec. + DubiousMultipleHostsWarning = "$ref values point to %d distinct remote hosts (%s): a spec referencing multiple hosts may be unsafe" + InvalidObject = "expected an object in %q.%s" ) @@ -404,3 +416,11 @@ func someParametersBrokenMsg(path, method, operationID string) errors.Error { func refShouldNotHaveSiblingsMsg(path, operationID string) errors.Error { return errors.New(errors.CompositeErrorCode, RefShouldNotHaveSiblingsWarning, operationID, path) } + +func dubiousAbsoluteRefMsg(ref string) errors.Error { + return errors.New(errors.CompositeErrorCode, DubiousAbsoluteRefWarning, ref) +} + +func dubiousMultipleHostsMsg(count int, hosts string) errors.Error { + return errors.New(errors.CompositeErrorCode, DubiousMultipleHostsWarning, count, hosts) +} diff --git a/vendor/github.com/go-openapi/validate/spec_ref_warnings.go b/vendor/github.com/go-openapi/validate/spec_ref_warnings.go new file mode 100644 index 00000000000..49c72314c94 --- /dev/null +++ b/vendor/github.com/go-openapi/validate/spec_ref_warnings.go @@ -0,0 +1,209 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package validate + +import ( + "net/url" + "path" + "sort" + "strings" + + "github.com/go-openapi/spec" +) + +// minDistinctHostsToWarn is the number of distinct remote hosts among $refs at or above which +// Rule 2 emits a host-spread warning. A single consistent remote host is legitimate. +const minDistinctHostsToWarn = 2 + +// validateDubiousRefs emits warnings (never errors) when $ref locations match patterns +// that may indicate an unsafe or adversarial spec. It inspects refs as authored, on the +// UNEXPANDED spec, so it must run before expansion flattens them away. +// +// Two rules are applied over s.analyzer.AllRefs(): +// +// - Rule 1 (absolute local escape): a $ref pointing to an absolute local file location +// (file:// scheme, a Unix absolute path, or a Windows drive path such as C:\) is dubious +// UNLESS it stays beneath the spec's base path. Absolute refs beneath the base are +// legitimate: flattening/expansion in go-openapi/spec and analysis introduces absolute +// anchors to resolve cyclical $refs. Relative and fragment-only refs are always exempt. +// +// - Rule 2 (host spread): when remote (http/https, or protocol-relative) refs resolve to +// two or more distinct hosts, a single aggregate warning lists them. A single consistent +// remote host is common and legitimate, so it is not flagged. +// +// All findings are warnings: they do not affect validity (see Result.IsValid). +func (s *SpecValidator) validateDubiousRefs() *Result { + res := pools.poolOfResults.BorrowResult() + + baseDir, hasBase := s.localBaseDir() + + remoteHosts := make(map[string]struct{}) + for _, r := range s.analyzer.AllRefs() { + u := r.GetURL() + if u == nil { // Safeguard: a valid spec always yields parseable refs + continue + } + + // Rule 1: absolute local reference escaping the base path. + if refPath, isLocalAbs := absoluteLocalRefPath(r, u); isLocalAbs { + if !hasBase || !isBeneathBase(refPath, baseDir) { + res.AddWarnings(dubiousAbsoluteRefMsg(r.String())) + } + continue + } + + // Rule 2: gather remote hosts (http/https and protocol-relative //host/...). + if host := remoteRefHost(u); host != "" { + remoteHosts[host] = struct{}{} + } + } + + if len(remoteHosts) >= minDistinctHostsToWarn { + hosts := make([]string, 0, len(remoteHosts)) + for h := range remoteHosts { + hosts = append(hosts, h) + } + sort.Strings(hosts) + res.AddWarnings(dubiousMultipleHostsMsg(len(hosts), strings.Join(hosts, ", "))) + } + + return res +} + +// absoluteLocalRefPath reports whether r is an absolute LOCAL file reference and, if so, +// returns the cleaned path it points to (without scheme/fragment, drive letter lower-cased). +// +// Classification order matters (see the empirical jsonreference flag behavior): +// - file:// scheme is local, including UNC file://host/share (inherently dubious). +// - a non-empty Host with no file scheme means remote (http/https or protocol-relative +// //host/path) - NOT local; handled by Rule 2. This must be checked before the Unix +// branch, because protocol-relative refs also set HasFullFilePath. +// - len(u.Scheme) == 1 is a Windows drive path (C:\ or C:/), whose drive+path land in +// Scheme/Opaque/Path rather than Path. Checked before the Unix branch because C:/x also +// sets HasFullFilePath, and reconstructed from the authored ref string to keep the drive. +// - !r.HasFullURL && r.HasFullFilePath is a plain Unix absolute path (/abs/models.json). +// +// Relative (./x.json) and fragment-only (#/definitions/X) refs return false. +func absoluteLocalRefPath(r spec.Ref, u *url.URL) (string, bool) { + switch { + case r.HasFileScheme: + return fileRefPath(u), true + case u.Host != "": + // Remote (http/https) or protocol-relative //host/path: handled by Rule 2. + return "", false + case len(u.Scheme) == 1: + // Windows drive letter: reconstruct from the authored ref string. + return cleanRefPath(r.String()), true + case !r.HasFullURL && r.HasFullFilePath: + return cleanRefPath(u.Path), true + default: + return "", false + } +} + +// remoteRefHost returns the host of a remote reference (http/https), or of a protocol-relative +// reference (//host/path). It returns "" for local and fragment-only refs. file:// hosts (UNC) +// are deliberately excluded: those are handled as local-absolute refs by Rule 1. +func remoteRefHost(u *url.URL) string { + switch u.Scheme { + case "http", "https": + return u.Host + case "": + // Protocol-relative //host/path: empty scheme but a host is present. + return u.Host + default: + return "" + } +} + +// localBaseDir returns the directory of the spec file, slash-normalized, when the spec was +// loaded from a local path. It returns ok=false when the base is unknown (in-memory spec) or +// remote (http/https), in which case absolute-local refs cannot be proven beneath a base and +// are treated as dubious. +func (s *SpecValidator) localBaseDir() (string, bool) { + specPath := s.spec.SpecFilePath() + if specPath == "" { + return "", false + } + + // Strip a file:// scheme if present; reject remote bases. + if u, err := url.Parse(specPath); err == nil && u.Scheme != "" { + switch { + case u.Scheme == "file": + specPath = u.Path + case len(u.Scheme) == 1: // Windows drive letter, treat as local + // keep specPath as-is (authored path) + default: // http, https, ... : no local base + return "", false + } + } + + return path.Dir(cleanRefPath(specPath)), true +} + +// isBeneathBase reports whether the cleaned target path is located within baseDir, i.e. it does +// not escape baseDir via "..". Comparison is purely lexical on cleaned paths, which is sufficient +// (and cross-platform safe) for a non-fatal warning. Both sides are expected to already be +// cleanRefPath-normalized (slashes, drive-letter case). +func isBeneathBase(target, baseDir string) bool { + if baseDir == "" { + return false + } + if target == baseDir { + return true + } + if !strings.HasSuffix(baseDir, "/") { + baseDir += "/" + } + return strings.HasPrefix(target, baseDir) +} + +// fileRefPath extracts the local path a file:// reference points to, accounting for the way +// Windows file URLs parse: +// - file:///abs/x -> /abs/x (empty host) +// - file:///C:/dir/x -> /c:/dir/x (empty host; drive sits in the path) +// - file://D:/a/x -> d:/a/x (drive letter lands in Host, rejoin it) +// - file://host/share -> /host/share/x (real UNC host kept visible so it cannot match a +// local base and stays flagged as dubious) +func fileRefPath(u *url.URL) string { + switch { + case u.Host == "": + return cleanRefPath(u.Path) + case isDriveHost(u.Host): + // Windows path authored as file://D:/... : the drive landed in Host (e.g. "d:"). + return cleanRefPath(u.Host + u.Path) + default: + // Real remote/UNC host: keep it in the path so it never matches a local base. + return cleanRefPath("//" + u.Host + u.Path) + } +} + +// isDriveHost reports whether a URL host is actually a Windows drive letter (e.g. "d:"), which +// happens when a Windows path is authored as a two-slash file URL: file://D:/path. +func isDriveHost(host string) bool { + h := strings.TrimSuffix(host, ":") + if len(h) != 1 { + return false + } + c := h[0] + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') +} + +// cleanRefPath normalizes a ref or base path for lexical comparison: backslashes to forward +// slashes, path.Clean, and a lower-cased leading Windows drive letter (matching the behavior of +// go-openapi/spec's normalizer). Plain Unix paths are unaffected, preserving case-sensitivity. +func cleanRefPath(p string) string { + p = path.Clean(strings.ReplaceAll(p, `\`, `/`)) + switch { + case len(p) >= 2 && p[1] == ':': + // drive-letter form: C:/dir -> c:/dir + p = strings.ToLower(p[:1]) + p[1:] + case len(p) >= 3 && p[0] == '/' && p[2] == ':': + // slash-prefixed drive form from canonical file:// URLs: /C:/dir -> c:/dir. + // The leading slash is dropped so this matches the base path derived from + // SpecFilePath (which has no leading slash), and the bare-drive form. + p = strings.ToLower(p[1:2]) + p[2:] + } + return p +} diff --git a/vendor/github.com/hashicorp/consul/api/config_entry.go b/vendor/github.com/hashicorp/consul/api/config_entry.go index e82e14749db..84155086295 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry.go @@ -43,6 +43,7 @@ const ( const ( BuiltinAWSLambdaExtension string = "builtin/aws/lambda" BuiltinExtAuthzExtension string = "builtin/ext-authz" + BuiltinExtProcExtension string = "builtin/ext-proc" BuiltinLuaExtension string = "builtin/lua" BuiltinOTELAccessLoggingExtension string = "builtin/otel-access-logging" BuiltinPropertyOverrideExtension string = "builtin/property-override" diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go b/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go index 6397088c9e8..457e4b33b01 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_gateways.go @@ -250,6 +250,15 @@ type APIGatewayConfigEntry struct { // Defaults contains default upstream limits for all route destination services. Defaults *UpstreamLimits `json:",omitempty"` + + // ExtAuthz is the gateway-wide external authorization toggle. It controls the + // default ext_authz posture for every endpoint behind this gateway when the + // builtin/ext-authz EnvoyExtension is applied via service-defaults. When nil + // (omitted) ext_authz is enabled by default; when set with Enabled=false the + // filter defaults to disabled and routes must opt in individually. Per-route + // http-route ExtAuthz filters take precedence over this toggle. + ExtAuthz *APIGatewayExtAuthz `json:",omitempty"` + // Status is the asynchronous status which an APIGateway propagates to the user. Status ConfigEntryStatus @@ -279,6 +288,16 @@ func (g *APIGatewayConfigEntry) GetMeta() map[string]string { return g.Meta } func (g *APIGatewayConfigEntry) GetCreateIndex() uint64 { return g.CreateIndex } func (g *APIGatewayConfigEntry) GetModifyIndex() uint64 { return g.ModifyIndex } +// APIGatewayExtAuthz is the gateway-wide external authorization toggle on an +// APIGatewayConfigEntry. See APIGatewayConfigEntry.ExtAuthz. +type APIGatewayExtAuthz struct { + // Enabled controls the default ext_authz posture for all endpoints behind + // the gateway. When false the ext_authz filter defaults to disabled and + // individual http-route rules must opt in. When the containing ExtAuthz + // block is omitted entirely, ext_authz is enabled by default. + Enabled bool +} + // APIGatewayListener represents an individual listener for an APIGateway type APIGatewayListener struct { // Name is the name of the listener in a given gateway. This must be diff --git a/vendor/github.com/hashicorp/consul/api/config_entry_routes.go b/vendor/github.com/hashicorp/consul/api/config_entry_routes.go index e6a1d6a722c..7f6f142f2cd 100644 --- a/vendor/github.com/hashicorp/consul/api/config_entry_routes.go +++ b/vendor/github.com/hashicorp/consul/api/config_entry_routes.go @@ -207,6 +207,52 @@ type HTTPFilters struct { RetryFilter *RetryFilter TimeoutFilter *TimeoutFilter JWT *JWTFilter + ExtProc []ExtProcFilter + // ExtAuthz controls the ext_authz HTTP filter behaviour for routes on an + // API Gateway that has a builtin/ext-authz EnvoyExtension applied. When set, + // it overrides the gateway-wide ExtAuthz toggle for the matched route: + // Enabled=true forces the ext_authz check to run, Enabled=false skips it. + // When nil, the route inherits the gateway-wide default. Exclusions are + // controlled exclusively at the http-route level. + ExtAuthz *HTTPRouteExtAuthzFilter +} + +// ExtProcFilter provides per-route control of a builtin/ext-proc attachment. +type ExtProcFilter struct { + StatPrefix string `json:",omitempty"` + Mode string `json:",omitempty"` + Overrides *ExtProcOverrides `json:",omitempty"` +} + +// ExtProcOverrides carries per-route overrides applied when Mode is "override". +type ExtProcOverrides struct { + Processing *ExtProcProcessing `json:",omitempty"` + // MessageTimeout string `json:",omitempty"` + // FailureModeAllow *bool `json:",omitempty"` +} + +// ExtProcProcessing configures request and response processing modes. +type ExtProcProcessing struct { + Request *ExtProcProcessingDirection `json:",omitempty"` + Response *ExtProcProcessingDirection `json:",omitempty"` +} + +// ExtProcProcessingDirection configures processing modes for one direction. +type ExtProcProcessingDirection struct { + HeadersMode string `json:",omitempty"` + BodyMode string `json:",omitempty"` + TrailersMode string `json:",omitempty"` + MaxBodyBytes int64 `json:",omitempty"` +} + +// HTTPRouteExtAuthzFilter controls ext_authz filter behaviour at the +// individual http-route rule level. +type HTTPRouteExtAuthzFilter struct { + // Enabled controls whether Envoy runs the ext_authz check for requests + // matched by this rule. Enabled=true force-enables the check (overriding a + // disabled gateway toggle); Enabled=false force-skips it. This takes + // precedence over the gateway-wide ExtAuthz toggle. + Enabled bool } // HTTPResponseFilters specifies a list of filters used to modify a diff --git a/vendor/github.com/hashicorp/go-metrics/compat/armon.go b/vendor/github.com/hashicorp/go-metrics/compat/armon.go new file mode 100644 index 00000000000..6a9e1e59661 --- /dev/null +++ b/vendor/github.com/hashicorp/go-metrics/compat/armon.go @@ -0,0 +1,131 @@ +// Copyright IBM Corp. 2013, 2025 +// SPDX-License-Identifier: MIT + +//go:build armonmetrics || ignore || !hashicorpmetrics + +package metrics + +import ( + "io" + "net/url" + "syscall" + "time" + + "github.com/armon/go-metrics" +) + +const ( + // DefaultSignal is used with DefaultInmemSignal + DefaultSignal = metrics.DefaultSignal +) + +func AddSample(key []string, val float32) { + metrics.AddSample(key, val) +} +func AddSampleWithLabels(key []string, val float32, labels []Label) { + metrics.AddSampleWithLabels(key, val, labels) +} +func EmitKey(key []string, val float32) { + metrics.EmitKey(key, val) +} +func IncrCounter(key []string, val float32) { + metrics.IncrCounter(key, val) +} +func IncrCounterWithLabels(key []string, val float32, labels []Label) { + metrics.IncrCounterWithLabels(key, val, labels) +} +func MeasureSince(key []string, start time.Time) { + metrics.MeasureSince(key, start) +} +func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { + metrics.MeasureSinceWithLabels(key, start, labels) +} +func SetGauge(key []string, val float32) { + metrics.SetGauge(key, val) +} +func SetGaugeWithLabels(key []string, val float32, labels []Label) { + metrics.SetGaugeWithLabels(key, val, labels) +} +func Shutdown() { + metrics.Shutdown() +} +func UpdateFilter(allow, block []string) { + metrics.UpdateFilter(allow, block) +} +func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) { + metrics.UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels) +} + +type AggregateSample = metrics.AggregateSample +type BlackholeSink = metrics.BlackholeSink +type Config = metrics.Config +type Encoder = metrics.Encoder +type FanoutSink = metrics.FanoutSink +type GaugeValue = metrics.GaugeValue +type InmemSignal = metrics.InmemSignal +type InmemSink = metrics.InmemSink +type IntervalMetrics = metrics.IntervalMetrics +type Label = metrics.Label +type MetricSink = metrics.MetricSink +type Metrics = metrics.Metrics +type MetricsSummary = metrics.MetricsSummary +type PointValue = metrics.PointValue +type SampledValue = metrics.SampledValue +type ShutdownSink = metrics.ShutdownSink +type StatsdSink = metrics.StatsdSink +type StatsiteSink = metrics.StatsiteSink + +func DefaultConfig(serviceName string) *Config { + return metrics.DefaultConfig(serviceName) +} + +func DefaultInmemSignal(inmem *InmemSink) *InmemSignal { + return metrics.DefaultInmemSignal(inmem) +} +func NewInmemSignal(inmem *InmemSink, sig syscall.Signal, w io.Writer) *InmemSignal { + return metrics.NewInmemSignal(inmem, sig, w) +} + +func NewInmemSink(interval, retain time.Duration) *InmemSink { + return metrics.NewInmemSink(interval, retain) +} + +func NewIntervalMetrics(intv time.Time) *IntervalMetrics { + return metrics.NewIntervalMetrics(intv) +} + +func NewInmemSinkFromURL(u *url.URL) (MetricSink, error) { + return metrics.NewInmemSinkFromURL(u) +} + +func NewMetricSinkFromURL(urlStr string) (MetricSink, error) { + return metrics.NewMetricSinkFromURL(urlStr) +} + +func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) { + return metrics.NewStatsdSinkFromURL(u) +} + +func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) { + return metrics.NewStatsiteSinkFromURL(u) +} + +func Default() *Metrics { + return metrics.Default() +} + +func New(conf *Config, sink MetricSink) (*Metrics, error) { + return metrics.New(conf, sink) +} + +func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) { + return metrics.NewGlobal(conf, sink) +} + +func NewStatsdSink(addr string) (*StatsdSink, error) { + return metrics.NewStatsdSink(addr) +} + +func NewStatsiteSink(addr string) (*StatsiteSink, error) { + return metrics.NewStatsiteSink(addr) +} diff --git a/vendor/github.com/hashicorp/go-metrics/compat/hashicorp.go b/vendor/github.com/hashicorp/go-metrics/compat/hashicorp.go new file mode 100644 index 00000000000..b1fdc2ffe63 --- /dev/null +++ b/vendor/github.com/hashicorp/go-metrics/compat/hashicorp.go @@ -0,0 +1,141 @@ +// Copyright IBM Corp. 2013, 2026 +// SPDX-License-Identifier: MIT + +//go:build hashicorpmetrics + +package metrics + +import ( + "io" + "net/url" + "syscall" + "time" + + "github.com/hashicorp/go-metrics" +) + +const ( + // DefaultSignal is used with DefaultInmemSignal + DefaultSignal = metrics.DefaultSignal +) + +func AddSample(key []string, val float32) { + metrics.AddSample(key, val) +} +func AddSampleWithLabels(key []string, val float32, labels []Label) { + metrics.AddSampleWithLabels(key, val, labels) +} +func EmitKey(key []string, val float32) { + metrics.EmitKey(key, val) +} +func IncrCounter(key []string, val float32) { + metrics.IncrCounter(key, val) +} +func IncrCounterWithLabels(key []string, val float32, labels []Label) { + metrics.IncrCounterWithLabels(key, val, labels) +} +func MeasureSince(key []string, start time.Time) { + metrics.MeasureSince(key, start) +} +func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { + metrics.MeasureSinceWithLabels(key, start, labels) +} +func SetGauge(key []string, val float32) { + metrics.SetGauge(key, val) +} +func SetGaugeWithLabels(key []string, val float32, labels []Label) { + metrics.SetGaugeWithLabels(key, val, labels) +} +func Shutdown() { + metrics.Shutdown() +} +func UpdateFilter(allow, block []string) { + metrics.UpdateFilter(allow, block) +} +func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) { + metrics.UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels) +} + +type AggregateSample = metrics.AggregateSample +type BlackholeSink = metrics.BlackholeSink +type Config = metrics.Config +type Encoder = metrics.Encoder +type FanoutSink = metrics.FanoutSink +type GaugeValue = metrics.GaugeValue +type InmemSignal = metrics.InmemSignal +type InmemSink = metrics.InmemSink +type IntervalMetrics = metrics.IntervalMetrics +type Label = metrics.Label +type MetricSink = metrics.MetricSink +type Metrics = metrics.Metrics +type MetricsSummary = metrics.MetricsSummary +type PointValue = metrics.PointValue +type SampledValue = metrics.SampledValue +type ShutdownSink = metrics.ShutdownSink +type StatsdSink = metrics.StatsdSink +type StatsiteSink = metrics.StatsiteSink + +func DefaultConfig(serviceName string) *Config { + return metrics.DefaultConfig(serviceName) +} + +func DefaultInmemSignal(inmem *InmemSink) *InmemSignal { + return metrics.DefaultInmemSignal(inmem) +} +func NewInmemSignal(inmem *InmemSink, sig syscall.Signal, w io.Writer) *InmemSignal { + return metrics.NewInmemSignal(inmem, sig, w) +} + +func NewInmemSink(interval, retain time.Duration) *InmemSink { + return metrics.NewInmemSink(interval, retain) +} + +func NewIntervalMetrics(intv time.Time) *IntervalMetrics { + return metrics.NewIntervalMetrics(intv) +} + +func NewInmemSinkFromURL(u *url.URL) (MetricSink, error) { + return metrics.NewInmemSinkFromURL(u) +} + +func NewMetricSinkFromURL(urlStr string) (MetricSink, error) { + return metrics.NewMetricSinkFromURL(urlStr) +} + +func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) { + return metrics.NewStatsdSinkFromURL(u) +} + +func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) { + return metrics.NewStatsiteSinkFromURL(u) +} + +func Default() *Metrics { + return metrics.Default() +} + +func New(conf *Config, sink MetricSink) (*Metrics, error) { + return metrics.New(conf, sink) +} + +func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) { + return metrics.NewGlobal(conf, sink) +} + +type SinkLogger = metrics.SinkLogger + +func NewStatsdSink(addr string) (*StatsdSink, error) { + return metrics.NewStatsdSink(addr) +} + +func NewStatsdSinkWithLogger(addr string, logger SinkLogger) (*StatsdSink, error) { + return metrics.NewStatsdSinkWithLogger(addr, logger) +} + +func NewStatsiteSink(addr string) (*StatsiteSink, error) { + return metrics.NewStatsiteSink(addr) +} + +func NewStatsiteSinkWithLogger(addr string, logger SinkLogger) (*StatsiteSink, error) { + return metrics.NewStatsiteSinkWithLogger(addr, logger) +} diff --git a/vendor/github.com/hashicorp/go-metrics/statsd.go b/vendor/github.com/hashicorp/go-metrics/statsd.go index 8b5f2c6e847..d1a7b3a7738 100644 --- a/vendor/github.com/hashicorp/go-metrics/statsd.go +++ b/vendor/github.com/hashicorp/go-metrics/statsd.go @@ -1,4 +1,4 @@ -// Copyright IBM Corp. 2013, 2025 +// Copyright IBM Corp. 2013, 2026 // SPDX-License-Identifier: MIT package metrics @@ -19,12 +19,22 @@ const ( statsdMaxLen = 1400 ) +// SinkLogger is a minimal structured logging interface that sink implementations +// use to emit operational error messages. It is satisfied by hclog.Logger and +// any other structured logger that provides Warn and Error methods with +// key/value pair arguments. +type SinkLogger interface { + Warn(msg string, args ...any) + Error(msg string, args ...any) +} + // StatsdSink provides a MetricSink that can be used // with a statsite or statsd metrics server. It uses // only UDP packets, while StatsiteSink uses TCP. type StatsdSink struct { addr string metricQueue chan string + logger SinkLogger } // NewStatsdSinkFromURL creates an StatsdSink from a URL. It is used @@ -43,6 +53,47 @@ func NewStatsdSink(addr string) (*StatsdSink, error) { return s, nil } +// NewStatsdSinkWithLogger is used to create a new StatsdSink with a SinkLogger. +// The logger is set before the background flush goroutine starts, ensuring all +// operational errors are routed through it from the first connection attempt. +func NewStatsdSinkWithLogger(addr string, logger SinkLogger) (*StatsdSink, error) { + s := &StatsdSink{ + addr: addr, + metricQueue: make(chan string, 4096), + logger: logger, + } + go s.flushMetrics() + return s, nil +} + +// SetLogger assigns a SinkLogger to the sink. When set, operational errors +// such as connection failures and flush errors are emitted through the provided +// logger instead of the stdlib log package, allowing callers to control the +// log format and destination. +func (s *StatsdSink) SetLogger(logger SinkLogger) { + s.logger = logger +} + +// logWarn emits a warning through the configured SinkLogger when one is set, +// falling back to stdlib log.Printf otherwise. +func (s *StatsdSink) logWarn(msg string, err error) { + if s.logger != nil { + s.logger.Warn(msg, "error", err) + } else { + log.Printf("[WARN] %s Err: %s", msg, err) + } +} + +// logErr emits an error through the configured SinkLogger when one is set, +// falling back to stdlib log.Printf otherwise. +func (s *StatsdSink) logErr(msg string, err error) { + if s.logger != nil { + s.logger.Error(msg, "error", err) + } else { + log.Printf("[ERR] %s Err: %s", msg, err) + } +} + // Close is used to stop flushing to statsd func (s *StatsdSink) Shutdown() { close(s.metricQueue) @@ -139,7 +190,7 @@ CONNECT: // Attempt to connect sock, err = net.Dial("udp", s.addr) if err != nil { - log.Printf("[ERR] Error connecting to statsd! Err: %s", err) + s.logErr("Error connecting to statsd!", err) goto WAIT } @@ -156,7 +207,7 @@ CONNECT: _, err := sock.Write(buf.Bytes()) buf.Reset() if err != nil { - log.Printf("[ERR] Error writing to statsd! Err: %s", err) + s.logErr("Error writing to statsd!", err) goto WAIT } } @@ -172,7 +223,7 @@ CONNECT: _, err := sock.Write(buf.Bytes()) buf.Reset() if err != nil { - log.Printf("[ERR] Error flushing to statsd! Err: %s", err) + s.logErr("Error flushing to statsd!", err) goto WAIT } } diff --git a/vendor/github.com/hashicorp/go-metrics/statsite.go b/vendor/github.com/hashicorp/go-metrics/statsite.go index 1cb4614bad9..ef089344f02 100644 --- a/vendor/github.com/hashicorp/go-metrics/statsite.go +++ b/vendor/github.com/hashicorp/go-metrics/statsite.go @@ -1,4 +1,4 @@ -// Copyright IBM Corp. 2013, 2025 +// Copyright IBM Corp. 2013, 2026 // SPDX-License-Identifier: MIT package metrics @@ -31,6 +31,7 @@ func NewStatsiteSinkFromURL(u *url.URL) (MetricSink, error) { type StatsiteSink struct { addr string metricQueue chan string + logger SinkLogger } // NewStatsiteSink is used to create a new StatsiteSink @@ -43,6 +44,47 @@ func NewStatsiteSink(addr string) (*StatsiteSink, error) { return s, nil } +// NewStatsiteSinkWithLogger is used to create a new StatsiteSink with a SinkLogger. +// The logger is set before the background flush goroutine starts, ensuring all +// operational errors are routed through it from the first connection attempt. +func NewStatsiteSinkWithLogger(addr string, logger SinkLogger) (*StatsiteSink, error) { + s := &StatsiteSink{ + addr: addr, + metricQueue: make(chan string, 4096), + logger: logger, + } + go s.flushMetrics() + return s, nil +} + +// SetLogger assigns a SinkLogger to the sink. When set, operational errors +// such as connection failures and flush errors are emitted through the provided +// logger instead of the stdlib log package, allowing callers to control the +// log format and destination. +func (s *StatsiteSink) SetLogger(logger SinkLogger) { + s.logger = logger +} + +// logWarn emits a warning through the configured SinkLogger when one is set, +// falling back to stdlib log.Printf otherwise. +func (s *StatsiteSink) logWarn(msg string, err error) { + if s.logger != nil { + s.logger.Warn(msg, "error", err) + } else { + log.Printf("[WARN] %s Err: %s", msg, err) + } +} + +// logErr emits an error through the configured SinkLogger when one is set, +// falling back to stdlib log.Printf otherwise. +func (s *StatsiteSink) logErr(msg string, err error) { + if s.logger != nil { + s.logger.Error(msg, "error", err) + } else { + log.Printf("[ERR] %s Err: %s", msg, err) + } +} + // Close is used to stop flushing to statsite func (s *StatsiteSink) Shutdown() { close(s.metricQueue) @@ -137,7 +179,7 @@ CONNECT: // Attempt to connect sock, err = net.Dial("tcp", s.addr) if err != nil { - log.Printf("[ERR] Error connecting to statsite! Err: %s", err) + s.logErr("Error connecting to statsite!", err) goto WAIT } @@ -155,12 +197,12 @@ CONNECT: // Try to send to statsite _, err := buffered.Write([]byte(metric)) if err != nil { - log.Printf("[ERR] Error writing to statsite! Err: %s", err) + s.logErr("Error writing to statsite!", err) goto WAIT } case <-ticker.C: if err := buffered.Flush(); err != nil { - log.Printf("[ERR] Error flushing to statsite! Err: %s", err) + s.logErr("Error flushing to statsite!", err) goto WAIT } } diff --git a/vendor/github.com/hashicorp/serf/LICENSE b/vendor/github.com/hashicorp/serf/LICENSE index c33dcc7c928..bfbd0aa577d 100644 --- a/vendor/github.com/hashicorp/serf/LICENSE +++ b/vendor/github.com/hashicorp/serf/LICENSE @@ -1,3 +1,5 @@ +Copyright IBM Corp. 2013, 2026 + Mozilla Public License, version 2.0 1. Definitions diff --git a/vendor/github.com/hashicorp/serf/coordinate/client.go b/vendor/github.com/hashicorp/serf/coordinate/client.go index 32124a73a20..d940987b2b9 100644 --- a/vendor/github.com/hashicorp/serf/coordinate/client.go +++ b/vendor/github.com/hashicorp/serf/coordinate/client.go @@ -1,3 +1,6 @@ +// Copyright IBM Corp. 2013, 2026 +// SPDX-License-Identifier: MPL-2.0 + package coordinate import ( @@ -7,7 +10,7 @@ import ( "sync" "time" - "github.com/armon/go-metrics" + metrics "github.com/hashicorp/go-metrics/compat" ) // Client manages the estimated network coordinate for a given node, and adjusts @@ -52,7 +55,7 @@ type ClientStats struct { // NewClient creates a new Client and verifies the configuration is valid. func NewClient(config *Config) (*Client, error) { - if !(config.Dimensionality > 0) { + if config.Dimensionality == 0 { return nil, fmt.Errorf("dimensionality must be >0") } diff --git a/vendor/github.com/hashicorp/serf/coordinate/config.go b/vendor/github.com/hashicorp/serf/coordinate/config.go index 09c0cafe830..0adcac24451 100644 --- a/vendor/github.com/hashicorp/serf/coordinate/config.go +++ b/vendor/github.com/hashicorp/serf/coordinate/config.go @@ -1,7 +1,12 @@ +// Copyright IBM Corp. 2013, 2026 +// SPDX-License-Identifier: MPL-2.0 + package coordinate import ( - "github.com/armon/go-metrics" + "math/rand" + + metrics "github.com/hashicorp/go-metrics/compat" ) // Config is used to set the parameters of the Vivaldi-based coordinate mapping @@ -11,12 +16,17 @@ import ( // here: // // [1] Dabek, Frank, et al. "Vivaldi: A decentralized network coordinate system." -// ACM SIGCOMM Computer Communication Review. Vol. 34. No. 4. ACM, 2004. +// +// ACM SIGCOMM Computer Communication Review. Vol. 34. No. 4. ACM, 2004. +// // [2] Ledlie, Jonathan, Paul Gardner, and Margo I. Seltzer. "Network Coordinates -// in the Wild." NSDI. Vol. 7. 2007. +// +// in the Wild." NSDI. Vol. 7. 2007. +// // [3] Lee, Sanghwan, et al. "On suitability of Euclidean embedding for -// host-based network coordinate systems." Networking, IEEE/ACM Transactions -// on 18.1 (2010): 27-40. +// +// host-based network coordinate systems." Networking, IEEE/ACM Transactions +// on 18.1 (2010): 27-40. type Config struct { // The dimensionality of the coordinate system. As discussed in [2], more // dimensions improves the accuracy of the estimates up to a point. Per [2] @@ -59,6 +69,8 @@ type Config struct { // metricLabels is the slice of labels to put on all emitted metrics MetricLabels []metrics.Label + + rand *rand.Rand } // DefaultConfig returns a Config that has some default values suitable for @@ -73,5 +85,6 @@ func DefaultConfig() *Config { HeightMin: 10.0e-6, LatencyFilterSize: 3, GravityRho: 150.0, + rand: nil, } } diff --git a/vendor/github.com/hashicorp/serf/coordinate/coordinate.go b/vendor/github.com/hashicorp/serf/coordinate/coordinate.go index fbe792c90d4..09aae3d111f 100644 --- a/vendor/github.com/hashicorp/serf/coordinate/coordinate.go +++ b/vendor/github.com/hashicorp/serf/coordinate/coordinate.go @@ -1,3 +1,6 @@ +// Copyright IBM Corp. 2013, 2026 +// SPDX-License-Identifier: MPL-2.0 + package coordinate import ( @@ -107,7 +110,7 @@ func (c *Coordinate) ApplyForce(config *Config, force float64, other *Coordinate } ret := c.Clone() - unit, mag := unitVectorAt(c.Vec, other.Vec) + unit, mag := unitVectorAt(config.rand, c.Vec, other.Vec) ret.Vec = add(ret.Vec, mul(unit, force)) if mag > zeroThreshold { ret.Height = (ret.Height+other.Height)*force/mag + ret.Height @@ -179,7 +182,7 @@ func magnitude(vec []float64) float64 { // unitVectorAt returns a unit vector pointing at vec1 from vec2. If the two // positions are the same then a random unit vector is returned. We also return // the distance between the points for use in the later height calculation. -func unitVectorAt(vec1 []float64, vec2 []float64) ([]float64, float64) { +func unitVectorAt(rng *rand.Rand, vec1 []float64, vec2 []float64) ([]float64, float64) { ret := diff(vec1, vec2) // If the coordinates aren't on top of each other we can normalize. @@ -189,7 +192,11 @@ func unitVectorAt(vec1 []float64, vec2 []float64) ([]float64, float64) { // Otherwise, just return a random unit vector. for i := range ret { - ret[i] = rand.Float64() - 0.5 + if rng != nil { + ret[i] = rng.Float64() - 0.5 + } else { + ret[i] = rand.Float64() - 0.5 + } } if mag := magnitude(ret); mag > zeroThreshold { return mul(ret, 1.0/mag), 0.0 diff --git a/vendor/github.com/hashicorp/serf/coordinate/phantom.go b/vendor/github.com/hashicorp/serf/coordinate/phantom.go index 66da4e2e92e..4dcdbb66222 100644 --- a/vendor/github.com/hashicorp/serf/coordinate/phantom.go +++ b/vendor/github.com/hashicorp/serf/coordinate/phantom.go @@ -1,3 +1,6 @@ +// Copyright IBM Corp. 2013, 2026 +// SPDX-License-Identifier: MPL-2.0 + package coordinate import ( @@ -30,7 +33,7 @@ func GenerateLine(nodes int, spacing time.Duration) [][]time.Duration { truth[i] = make([]time.Duration, nodes) } - for i := 0; i < nodes; i++ { + for i := range nodes { for j := i + 1; j < nodes; j++ { rtt := time.Duration(j-i) * spacing truth[i][j], truth[j][i] = rtt, rtt @@ -48,7 +51,7 @@ func GenerateGrid(nodes int, spacing time.Duration) [][]time.Duration { } n := int(math.Sqrt(float64(nodes))) - for i := 0; i < nodes; i++ { + for i := range nodes { for j := i + 1; j < nodes; j++ { x1, y1 := float64(i%n), float64(i/n) x2, y2 := float64(j%n), float64(j/n) @@ -72,7 +75,7 @@ func GenerateSplit(nodes int, lan time.Duration, wan time.Duration) [][]time.Dur } split := nodes / 2 - for i := 0; i < nodes; i++ { + for i := range nodes { for j := i + 1; j < nodes; j++ { rtt := lan if (i <= split && j > split) || (i > split && j <= split) { @@ -94,7 +97,7 @@ func GenerateCircle(nodes int, radius time.Duration) [][]time.Duration { truth[i] = make([]time.Duration, nodes) } - for i := 0; i < nodes; i++ { + for i := range nodes { for j := i + 1; j < nodes; j++ { var rtt time.Duration if i == 0 { @@ -118,16 +121,16 @@ func GenerateCircle(nodes int, radius time.Duration) [][]time.Duration { // distributed delays, with the given mean and deviation. The RNG is re-seeded // so you always get the same matrix for a given size. func GenerateRandom(nodes int, mean time.Duration, deviation time.Duration) [][]time.Duration { - rand.Seed(1) + rng := rand.New(rand.NewSource(1)) truth := make([][]time.Duration, nodes) for i := range truth { truth[i] = make([]time.Duration, nodes) } - for i := 0; i < nodes; i++ { + for i := range nodes { for j := i + 1; j < nodes; j++ { - rttSeconds := rand.NormFloat64()*deviation.Seconds() + mean.Seconds() + rttSeconds := rng.NormFloat64()*deviation.Seconds() + mean.Seconds() rtt := time.Duration(rttSeconds * secondsToNanoseconds) truth[i][j], truth[j][i] = rtt, rtt } @@ -142,16 +145,16 @@ func GenerateRandom(nodes int, mean time.Duration, deviation time.Duration) [][] // underlying algorithm which will use random numbers for position vectors when // starting out with everything at the origin). func Simulate(clients []*Client, truth [][]time.Duration, cycles int) { - rand.Seed(1) + rng := rand.New(rand.NewSource(1)) nodes := len(clients) - for cycle := 0; cycle < cycles; cycle++ { + for range cycles { for i := range clients { - if j := rand.Intn(nodes); j != i { + if j := rng.Intn(nodes); j != i { c := clients[j].GetCoordinate() rtt := truth[i][j] node := fmt.Sprintf("node_%d", j) - clients[i].Update(node, c, rtt) + _, _ = clients[i].Update(node, c, rtt) } } } @@ -168,9 +171,12 @@ type Stats struct { // distances and compares them with the given truth matrix, returning summary // stats. func Evaluate(clients []*Client, truth [][]time.Duration) (stats Stats) { + if len(clients) <= 1 { + return + } nodes := len(clients) count := 0 - for i := 0; i < nodes; i++ { + for i := range nodes { for j := i + 1; j < nodes; j++ { est := clients[i].DistanceTo(clients[j].GetCoordinate()).Seconds() actual := truth[i][j].Seconds() diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index fb023f2cf21..0e9f170d012 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -27,6 +27,18 @@ Use the links above for more information on each. # changelog +* Jul 1st, 2026 [1.19.0](https://github.com/klauspost/compress/releases/tag/v1.19.0) + * zstd: Add true concurrent stream encodingin https://github.com/klauspost/compress/pull/1136 + * zstd: arm64 decoder asm by @lizthegrey in https://github.com/klauspost/compress/pull/1160 + * flate: Add inflate checkpoints in https://github.com/klauspost/compress/pull/1154 + * zstd: avoid unused BuildDict encoder allocation by @snissn in https://github.com/klauspost/compress/pull/1147 + * snappy/s2: Limit length of varint in `decodedLen` by @eustas in https://github.com/klauspost/compress/pull/1148 + * gzhttp: match qvalue parameter case-insensitively (RFC 7231) by @z9z in https://github.com/klauspost/compress/pull/1149 + * zip: add NameDecoder callback for legacy encoding rewrite by @SAY-5 in https://github.com/klauspost/compress/pull/1150 + * huff0: Allow building tables from histogram in https://github.com/klauspost/compress/pull/1155 + * huff0: Allow building table from oversized histogram in https://github.com/klauspost/compress/pull/1156 + * s2sx: Clean symlink targets in https://github.com/klauspost/compress/pull/1163 + * Feb 9th, 2026 [1.18.4](https://github.com/klauspost/compress/releases/tag/v1.18.4) * gzhttp: Add zstandard to server handler wrapper https://github.com/klauspost/compress/pull/1121 * zstd: Add ResetWithOptions to encoder/decoder https://github.com/klauspost/compress/pull/1122 diff --git a/vendor/github.com/klauspost/compress/flate/dict_decoder.go b/vendor/github.com/klauspost/compress/flate/dict_decoder.go index cb855abc4ba..37861cf6afb 100644 --- a/vendor/github.com/klauspost/compress/flate/dict_decoder.go +++ b/vendor/github.com/klauspost/compress/flate/dict_decoder.go @@ -28,9 +28,10 @@ type dictDecoder struct { hist []byte // Sliding window history // Invariant: 0 <= rdPos <= wrPos <= len(hist) - wrPos int // Current output position in buffer - rdPos int // Have emitted hist[:rdPos] already - full bool // Has a full window length been written yet? + wrPos int // Current output position in buffer + rdPos int // Have emitted hist[:rdPos] already + flushed int64 // Total bytes returned by readFlush since init + full bool // Has a full window length been written yet? } // init initializes dictDecoder to have a sliding window dictionary of the given @@ -167,11 +168,22 @@ loop: return dstPos - dstBase } +// appendWindow appends the current sliding window (up to len(hist) most recent +// bytes, oldest first) to dst. +func (dd *dictDecoder) appendWindow(dst []byte) []byte { + if dd.full { + dst = append(dst, dd.hist[dd.wrPos:]...) + return append(dst, dd.hist[:dd.wrPos]...) + } + return append(dst, dd.hist[:dd.wrPos]...) +} + // readFlush returns a slice of the historical buffer that is ready to be // emitted to the user. The data returned by readFlush must be fully consumed // before calling any other dictDecoder methods. func (dd *dictDecoder) readFlush() []byte { toRead := dd.hist[dd.rdPos:dd.wrPos] + dd.flushed += int64(len(toRead)) dd.rdPos = dd.wrPos if dd.wrPos == len(dd.hist) { dd.wrPos, dd.rdPos = 0, 0 @@ -179,3 +191,9 @@ func (dd *dictDecoder) readFlush() []byte { } return toRead } + +// decoded reports the total number of bytes written into the dictionary since +// init (i.e. excluding any preset dict bytes). +func (dd *dictDecoder) decoded() int64 { + return dd.flushed + int64(dd.wrPos-dd.rdPos) +} diff --git a/vendor/github.com/klauspost/compress/flate/inflate.go b/vendor/github.com/klauspost/compress/flate/inflate.go index 6e90126db03..39dd683b2dd 100644 --- a/vendor/github.com/klauspost/compress/flate/inflate.go +++ b/vendor/github.com/klauspost/compress/flate/inflate.go @@ -342,6 +342,11 @@ type decompressor struct { final bool flushMode flushMode + cb func(InflateCheckpoint) + cp InflateCheckpoint + hasCP bool // WithResumeFrom was supplied + uncOffset int64 // baseline uncompressed offset (from a resume checkpoint) + cpBuf []byte } func (f *decompressor) nextBlock() { @@ -676,6 +681,18 @@ func (f *decompressor) finishBlock() { f.toRead = f.dict.readFlush() } + if f.cb != nil { + bitPos := f.roffset*8 - int64(f.nb) + f.cpBuf = f.dict.appendWindow(f.cpBuf[:0]) + f.cb(InflateCheckpoint{ + UncompressedOffset: f.uncOffset + f.dict.decoded(), + CompressedOffset: bitPos / 8, + Final: f.final, + BitOffset: uint8(bitPos & 7), + Window: f.cpBuf, + }) + } + f.step = nextBlock } @@ -806,6 +823,45 @@ func (f *decompressor) Reset(r io.Reader, dict []byte) error { return nil } +// ResetCP will adjust the input to the provided checkpoint. +// It is assumed the input stream is forwarded to cp.CompressedOffset. +func (f *decompressor) ResetCP(r io.Reader, cp InflateCheckpoint) error { + *f = decompressor{ + r: makeReader(r), + bits: f.bits, + codebits: f.codebits, + h1: f.h1, + h2: f.h2, + dict: f.dict, + step: nextBlock, + cpBuf: f.cpBuf, + } + return f.applyCP(cp) +} + +// applyCP seeds the decompressor state from a resume checkpoint: +// loads the sliding window, sets the absolute compressed/uncompressed +// offsets, and skips cp.BitOffset bits into the first input byte so +// the next decode aligns with the start of a deflate block. +func (f *decompressor) applyCP(cp InflateCheckpoint) error { + f.dict.init(maxMatchOffset, cp.Window) + f.roffset = cp.CompressedOffset + f.uncOffset = cp.UncompressedOffset + f.final = cp.Final + f.b = 0 + f.nb = 0 + if cp.BitOffset > 0 { + c, err := f.r.ReadByte() + if err != nil { + return noEOF(err) + } + f.roffset++ + f.b = uint32(c) >> cp.BitOffset + f.nb = 8 - uint(cp.BitOffset) + } + return nil +} + type ReaderOpt func(*decompressor) // WithPartialBlock tells decompressor to return after each block, @@ -823,6 +879,36 @@ func WithDict(dict []byte) ReaderOpt { } } +// InflateCheckpoint provides a resumable checkpoint for inflate. +type InflateCheckpoint struct { + UncompressedOffset int64 // Byte offset in the decompressed stream + CompressedOffset int64 // Byte offset in the compressed stream + Final bool // True if this is the final block + BitOffset uint8 // 0-7 bits + Window []byte // 32KB sliding window dictionary +} + +// WithEobCallback will call the provided function after each block +// with the current gzip checkpoint. +// After returning the provided window can no longer be referenced. +// The callback will not be triggered after a block is marked "final". +// The callback is not retained after Reset. +func WithEobCallback(cb func(InflateCheckpoint)) ReaderOpt { + return func(f *decompressor) { + f.cb = cb + } +} + +// WithResumeFrom will adjust the input to the provided checkpoint. +// It is assumed the input stream is forwarded to the provided offset. +// The checkpoint is removed when Reset is called. +func WithResumeFrom(cp InflateCheckpoint) ReaderOpt { + return func(f *decompressor) { + f.cp = cp + f.hasCP = true + } +} + // NewReaderOpts returns new reader with provided options func NewReaderOpts(r io.Reader, opts ...ReaderOpt) io.ReadCloser { fixedHuffmanDecoderInit() @@ -838,6 +924,12 @@ func NewReaderOpts(r io.Reader, opts ...ReaderOpt) io.ReadCloser { opt(&f) } + if f.hasCP { + if err := f.applyCP(f.cp); err != nil { + f.err = err + } + } + return &f } diff --git a/vendor/github.com/klauspost/compress/flate/inflate_gen.go b/vendor/github.com/klauspost/compress/flate/inflate_gen.go index 2b2f993f753..e80f1965609 100644 --- a/vendor/github.com/klauspost/compress/flate/inflate_gen.go +++ b/vendor/github.com/klauspost/compress/flate/inflate_gen.go @@ -10,6 +10,15 @@ import ( "strings" ) +func peekBufio(fr *bufio.Reader) ([]byte, error) { + if fr.Buffered() == 0 { + if _, err := fr.Peek(1); err != nil && fr.Buffered() == 0 { + return nil, err + } + } + return fr.Peek(fr.Buffered()) +} + // Decode a single Huffman block from f. // hl and hd are the Huffman states for the lit/length values // and the distance values, respectively. If hd == nil, using the @@ -527,6 +536,8 @@ func (f *decompressor) huffmanBufioReader() { // but is smart enough to keep local variables in registers, so use nb and b, // inline call to moreBits and reassign b,nb back to f on return. fnb, fb, dict := f.nb, f.b, &f.dict + pbuf, _ := fr.Peek(fr.Buffered()) + pos := 0 switch f.stepState { case stateInit: @@ -548,12 +559,19 @@ readLiteral: n := uint(f.hl.maxRead) for { for fnb < n { - c, err := fr.ReadByte() - if err != nil { - f.b, f.nb = fb, fnb - f.err = noEOF(err) - return + if pos >= len(pbuf) { + fr.Discard(pos) + var err error + pbuf, err = peekBufio(fr) + pos = 0 + if len(pbuf) == 0 { + f.b, f.nb = fb, fnb + f.err = noEOF(err) + return + } } + c := pbuf[pos] + pos++ f.roffset++ fb |= uint32(c) << (fnb & regSizeMaskUint32) fnb += 8 @@ -566,6 +584,7 @@ readLiteral: } if n <= fnb { if n == 0 { + fr.Discard(pos) f.b, f.nb = fb, fnb if debugDecode { fmt.Println("huffsym: n==0") @@ -586,6 +605,7 @@ readLiteral: case v < 256: dict.writeByte(byte(v)) if dict.availWrite() == 0 { + fr.Discard(pos) f.toRead = dict.readFlush() f.step = huffmanBufioReader f.stepState = stateInit @@ -594,6 +614,7 @@ readLiteral: } goto readLiteral case v == 256: + fr.Discard(pos) f.b, f.nb = fb, fnb f.finishBlock() return @@ -605,15 +626,22 @@ readLiteral: length = int(val.length) + 3 n := uint(val.extra) for fnb < n { - c, err := fr.ReadByte() - if err != nil { - f.b, f.nb = fb, fnb - if debugDecode { - fmt.Println("morebits n>0:", err) + if pos >= len(pbuf) { + fr.Discard(pos) + var err error + pbuf, err = peekBufio(fr) + pos = 0 + if len(pbuf) == 0 { + f.b, f.nb = fb, fnb + if debugDecode { + fmt.Println("morebits n>0:", err) + } + f.err = err + return } - f.err = err - return } + c := pbuf[pos] + pos++ f.roffset++ fb |= uint32(c) << (fnb & regSizeMaskUint32) fnb += 8 @@ -622,6 +650,7 @@ readLiteral: fb >>= n & regSizeMaskUint32 fnb -= n default: + fr.Discard(pos) if debugDecode { fmt.Println(v, ">= maxNumLit") } @@ -633,15 +662,22 @@ readLiteral: var dist uint32 if f.hd == nil { for fnb < 5 { - c, err := fr.ReadByte() - if err != nil { - f.b, f.nb = fb, fnb - if debugDecode { - fmt.Println("morebits f.nb<5:", err) + if pos >= len(pbuf) { + fr.Discard(pos) + var err error + pbuf, err = peekBufio(fr) + pos = 0 + if len(pbuf) == 0 { + f.b, f.nb = fb, fnb + if debugDecode { + fmt.Println("morebits f.nb<5:", err) + } + f.err = err + return } - f.err = err - return } + c := pbuf[pos] + pos++ f.roffset++ fb |= uint32(c) << (fnb & regSizeMaskUint32) fnb += 8 @@ -660,12 +696,19 @@ readLiteral: // inline call to moreBits and reassign b,nb back to f on return. for { for fnb < n { - c, err := fr.ReadByte() - if err != nil { - f.b, f.nb = fb, fnb - f.err = noEOF(err) - return + if pos >= len(pbuf) { + fr.Discard(pos) + var err error + pbuf, err = peekBufio(fr) + pos = 0 + if len(pbuf) == 0 { + f.b, f.nb = fb, fnb + f.err = noEOF(err) + return + } } + c := pbuf[pos] + pos++ f.roffset++ fb |= uint32(c) << (fnb & regSizeMaskUint32) fnb += 8 @@ -678,6 +721,7 @@ readLiteral: } if n <= fnb { if n == 0 { + fr.Discard(pos) f.b, f.nb = fb, fnb if debugDecode { fmt.Println("huffsym: n==0") @@ -701,15 +745,22 @@ readLiteral: // have 1 bit in bottom of dist, need nb more. extra := (dist & 1) << (nb & regSizeMaskUint32) for fnb < nb { - c, err := fr.ReadByte() - if err != nil { - f.b, f.nb = fb, fnb - if debugDecode { - fmt.Println("morebits f.nb= len(pbuf) { + fr.Discard(pos) + var err error + pbuf, err = peekBufio(fr) + pos = 0 + if len(pbuf) == 0 { + f.b, f.nb = fb, fnb + if debugDecode { + fmt.Println("morebits f.nb uint32(dict.histSize()) { + fr.Discard(pos) f.b, f.nb = fb, fnb if debugDecode { fmt.Println("dist > dict.histSize():", dist, dict.histSize()) @@ -752,6 +805,7 @@ copyHistory: f.copyLen -= cnt if dict.availWrite() == 0 || f.copyLen > 0 { + fr.Discard(pos) f.toRead = dict.readFlush() f.step = huffmanBufioReader // We need to continue this work f.stepState = stateDict diff --git a/vendor/github.com/klauspost/compress/gzhttp/compress.go b/vendor/github.com/klauspost/compress/gzhttp/compress.go index 0f84b28ec83..da5048ef240 100644 --- a/vendor/github.com/klauspost/compress/gzhttp/compress.go +++ b/vendor/github.com/klauspost/compress/gzhttp/compress.go @@ -1158,8 +1158,8 @@ func parseCoding(s string) (coding string, qvalue float64, err error) { if n == 0 { coding = strings.ToLower(part) - } else if after, ok := strings.CutPrefix(part, "q="); ok { - qvalue, err = strconv.ParseFloat(after, 64) + } else if len(part) >= 2 && strings.EqualFold(part[:2], "q=") { + qvalue, err = strconv.ParseFloat(part[2:], 64) if qvalue < 0.0 { qvalue = 0.0 diff --git a/vendor/github.com/klauspost/compress/huff0/build_table.go b/vendor/github.com/klauspost/compress/huff0/build_table.go new file mode 100644 index 00000000000..e3757c87e0f --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/build_table.go @@ -0,0 +1,168 @@ +package huff0 + +import "errors" + +// BuildCTable builds a Huffman compression table from a precomputed symbol +// histogram and installs it as the previous (reuse) table on s. +// +// After this call: +// - EstimateSize/CanUseTable can probe the table against other histograms. +// - Compress1X/Compress4X with Reuse = ReusePolicyMust will encode without +// emitting a new table header. +// - TransferCTable can hand the table to a sibling Scratch. +// +// count[i] is the number of occurrences of symbol i. The histogram must have +// at least 2 distinct non-zero symbols; ErrUseRLE is returned for a single +// symbol and an error is returned for an empty histogram. +func (s *Scratch) BuildCTable(count *[256]uint32) error { + if s == nil { + return errors.New("huff0: BuildCTable on nil Scratch") + } + if count == nil { + return errors.New("huff0: nil count passed to BuildCTable") + } + var err error + s, err = s.prepare(nil) + if err != nil { + return err + } + s.count = *count + var total, maxCount int + var symLen uint16 + for i, v := range s.count { + total += int(v) + if int(v) > maxCount { + maxCount = int(v) + } + if v != 0 { + symLen = uint16(i) + 1 + } + } + if total == 0 { + return errors.New("huff0: empty histogram") + } + if symLen < 2 || maxCount == total { + return ErrUseRLE + } + // huff0's internal rank table assumes total ≤ BlockSizeMax (it uses + // highBit32(count+1) + 1 as a rank index into a fixed-size array). + // Histograms summed across multiple blocks can exceed that; scale the + // counts down preserving the distribution. Non-zero entries round up so + // rare symbols stay representable. + if total > BlockSizeMax { + shift := uint(0) + for total>>shift > BlockSizeMax { + shift++ + } + round := uint32(1<> shift + if scaled == 0 { + scaled = 1 + } + s.count[i] = scaled + newTotal += int(scaled) + if int(scaled) > newMax { + newMax = int(scaled) + } + } + total = newTotal + maxCount = newMax + if maxCount == total { + return ErrUseRLE + } + } + s.symbolLen = symLen + s.maxCount = maxCount + s.srcLen = total + if err := s.buildCTable(); err != nil { + return err + } + if cap(s.prevTable) < len(s.cTable) { + s.prevTable = make(cTable, 0, maxSymbolValue+1) + } + s.prevTable = s.prevTable[:len(s.cTable)] + copy(s.prevTable, s.cTable) + s.prevTableLog = s.actualTableLog + // Force the next Compress* to recount from real input. + s.clearCount = true + s.maxCount = 0 + return nil +} + +// EstimateSize returns an estimated compressed payload size in bytes for the +// supplied histogram using the table currently stored in prevTable. It returns +// -1 when the table cannot encode every non-zero symbol of hist (i.e. when +// CanUseTable would return false). The estimate excludes the table header. +func (s *Scratch) EstimateSize(hist *[256]uint32) int { + if s == nil || hist == nil || len(s.prevTable) == 0 { + return -1 + } + pt := s.prevTable + nbBits := uint32(7) + for i, v := range hist { + if v == 0 { + continue + } + if i >= len(pt) || pt[i].nBits == 0 { + return -1 + } + nbBits += uint32(pt[i].nBits) * v + } + return int(nbBits >> 3) +} + +// CanUseTable reports whether the table in prevTable can encode every +// non-zero symbol present in hist. +func (s *Scratch) CanUseTable(hist *[256]uint32) bool { + if s == nil || hist == nil || len(s.prevTable) == 0 { + return false + } + pt := s.prevTable + for i, v := range hist { + if v == 0 { + continue + } + if i >= len(pt) || pt[i].nBits == 0 { + return false + } + } + return true +} + +// AppendTable serializes the table currently stored in prevTable (e.g. as +// installed by BuildCTable or carried over from a previous Compress call) +// into a self-delimiting zstd-style header and appends it to dst. The +// returned slice can be parsed back by ReadTable. +func (s *Scratch) AppendTable(dst []byte) ([]byte, error) { + if s == nil || len(s.prevTable) == 0 { + return dst, errors.New("huff0: AppendTable with empty table") + } + // cTable.write reads s.actualTableLog, s.symbolLen, s.huffWeight, s.fse + // and writes into s.Out. Save/restore Out so we don't disturb in-flight + // compression buffers. + saveOut := s.Out + saveTL := s.actualTableLog + saveSL := s.symbolLen + if s.fse == nil { + // Lazily init in case AppendTable is called on a fresh Scratch. + if _, err := s.prepare(nil); err != nil { + return dst, err + } + saveOut = s.Out + } + s.Out = s.Out[:0] + s.actualTableLog = s.prevTableLog + s.symbolLen = uint16(len(s.prevTable)) + if err := s.prevTable.write(s); err != nil { + s.Out, s.actualTableLog, s.symbolLen = saveOut, saveTL, saveSL + return dst, err + } + dst = append(dst, s.Out...) + s.Out, s.actualTableLog, s.symbolLen = saveOut, saveTL, saveSL + return dst, nil +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index 2d6ef64be15..7035d656d99 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -1,222 +1,49 @@ //go:build amd64 && !appengine && !noasm && gc -// This file contains the specialisation of Decoder.Decompress4X -// and Decoder.Decompress1X that use an asm implementation of thir main loops. +// amd64 stubs and dispatch for the asm loops used by decompress_asm.go. package huff0 import ( - "errors" - "fmt" - "github.com/klauspost/compress/internal/cpuinfo" ) -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress4x_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog > 8. // //go:noescape func decompress4x_main_loop_amd64(ctx *decompress4xContext) -// decompress4x_8b_loop_x86 is an x86 assembler implementation +// decompress4x_8b_main_loop_amd64 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. // //go:noescape func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) -// fallback8BitSize is the size where using Go version is faster. -const fallback8BitSize = 800 - -type decompress4xContext struct { - pbr *[4]bitReaderShifted - peekBits uint8 - out *byte - dstEvery int - tbl *dEntrySingle - decoded int - limit *byte -} - -// Decompress4X will decompress a 4X encoded stream. -// The length of the supplied input must match the end of a block exactly. -// The *capacity* of the dst slice must match the destination size of -// the uncompressed data exactly. -func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - if len(src) < 6+(4*1) { - return nil, errors.New("input too small") - } - - use8BitTables := d.actualTableLog <= 8 - if cap(dst) < fallback8BitSize && use8BitTables { - return d.decompress4X8bit(dst, src) - } - - var br [4]bitReaderShifted - // Decode "jump table" - start := 6 - for i := range 3 { - length := int(src[i*2]) | (int(src[i*2+1]) << 8) - if start+length >= len(src) { - return nil, errors.New("truncated input (or invalid offset)") - } - err := br[i].init(src[start : start+length]) - if err != nil { - return nil, err - } - start += length - } - err := br[3].init(src[start:]) - if err != nil { - return nil, err - } - - // destination, offset to match first output - dstSize := cap(dst) - dst = dst[:dstSize] - out := dst - dstEvery := (dstSize + 3) / 4 - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - single := d.dt.single[:tlSize] - - var decoded int - - if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { - ctx := decompress4xContext{ - pbr: &br, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - out: &out[0], - dstEvery: dstEvery, - tbl: &single[0], - limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. - } - if use8BitTables { - decompress4x_8b_main_loop_amd64(&ctx) - } else { - decompress4x_main_loop_amd64(&ctx) - } - - decoded = ctx.decoded - out = out[decoded/4:] - } - - // Decode remaining. - remainBytes := dstEvery - (decoded / 4) - for i := range br { - offset := dstEvery * i - endsAt := min(offset+remainBytes, len(out)) - br := &br[i] - bitsLeft := br.remaining() - for bitsLeft > 0 { - br.fill() - if offset >= endsAt { - return nil, errors.New("corruption detected: stream overrun 4") - } - - // Read value and increment offset. - val := br.peekBitsFast(d.actualTableLog) - v := single[val&tlMask].entry - nBits := uint8(v) - br.advance(nBits) - bitsLeft -= uint(nBits) - out[offset] = uint8(v >> 8) - offset++ - } - if offset != endsAt { - return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) - } - decoded += offset - dstEvery*i - err = br.close() - if err != nil { - return nil, err - } - } - if dstSize != decoded { - return nil, errors.New("corruption detected: short output block") - } - return dst, nil -} - -// decompress4x_main_loop_x86 is an x86 assembler implementation +// decompress1x_main_loop_amd64 is an x86 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_amd64(ctx *decompress1xContext) -// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation +// decompress1x_main_loop_bmi2 is an x86 with BMI2 assembler implementation // of Decompress1X when tablelog > 8. // //go:noescape func decompress1x_main_loop_bmi2(ctx *decompress1xContext) -type decompress1xContext struct { - pbr *bitReaderShifted - peekBits uint8 - out *byte - outCap int - tbl *dEntrySingle - decoded int +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_amd64(ctx) } -// Error reported by asm implementations -const error_max_decoded_size_exeeded = -1 - -// Decompress1X will decompress a 1X encoded stream. -// The cap of the output buffer will be the maximum decompressed size. -// The length of the supplied input must match the end of a block exactly. -func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - var br bitReaderShifted - err := br.init(src) - if err != nil { - return dst, err - } - maxDecodedSize := cap(dst) - dst = dst[:maxDecodedSize] - - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - - if maxDecodedSize >= 4 { - ctx := decompress1xContext{ - pbr: &br, - out: &dst[0], - outCap: maxDecodedSize, - peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() - tbl: &d.dt.single[0], - } - - if cpuinfo.HasBMI2() { - decompress1x_main_loop_bmi2(&ctx) - } else { - decompress1x_main_loop_amd64(&ctx) - } - if ctx.decoded == error_max_decoded_size_exeeded { - return nil, ErrMaxDecodedSizeExceeded - } - - dst = dst[:ctx.decoded] - } +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_amd64(ctx) +} - // br < 8, so uint8 is fine - bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead - for bitsLeft > 0 { - br.fill() - if len(dst) >= maxDecodedSize { - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] - nBits := uint8(v.entry) - br.advance(nBits) - bitsLeft -= nBits - dst = append(dst, uint8(v.entry>>8)) +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + if cpuinfo.HasBMI2() { + decompress1x_main_loop_bmi2(ctx) + } else { + decompress1x_main_loop_amd64(ctx) } - return dst, br.close() } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index c4c7ab2d1fe..c5d4a710a09 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,6 +1,6 @@ -// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. -//go:build amd64 && !appengine && !noasm && gc +//go:build !appengine && !noasm && gc // func decompress4x_main_loop_amd64(ctx *decompress4xContext) TEXT ·decompress4x_main_loop_amd64(SB), $0-8 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go new file mode 100644 index 00000000000..8ba3c810e60 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.go @@ -0,0 +1,37 @@ +//go:build arm64 && !appengine && !noasm && gc + +// arm64 stubs and dispatch for the asm loops used by decompress_asm.go. +// The asm (decompress_arm64.s) is generated by the avo arm64 lowering +// printer from the same source as the amd64 asm; see _generate/gen.go. +package huff0 + +// decompress4x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog > 8. +// +//go:noescape +func decompress4x_main_loop_arm64(ctx *decompress4xContext) + +// decompress4x_8b_main_loop_arm64 is an arm64 assembler implementation +// of Decompress4X when tablelog <= 8 which decodes 4 entries +// per loop. +// +//go:noescape +func decompress4x_8b_main_loop_arm64(ctx *decompress4xContext) + +// decompress1x_main_loop_arm64 is an arm64 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_arm64(ctx *decompress1xContext) + +func decompress4x_main_loop_asm(ctx *decompress4xContext) { + decompress4x_main_loop_arm64(ctx) +} + +func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) { + decompress4x_8b_main_loop_arm64(ctx) +} + +func decompress1x_main_loop_asm(ctx *decompress1xContext) { + decompress1x_main_loop_arm64(ctx) +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s new file mode 100644 index 00000000000..e16012721a1 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_arm64.s @@ -0,0 +1,851 @@ +// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && !appengine && !noasm && gc + +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R0 + MOVBU 8(R0), R6 + MOVD 16(R0), R3 + MOVD 48(R0), R5 + MOVD 24(R0), R7 + MOVD 32(R0), R8 + MOVD (R0), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD (R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 24(R9) + ORR R12, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVH R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 48(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 72(R9) + ORR R12, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 96(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 120(R9) + ORR R12, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R0 + SUB $0x20, R11, R11 + SUB $0x04, R0, R0 + MOVD 144(R9), R12 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R12, R0, R15 + MOVWU (R15), R12 + MOVD R11, R1 + LSL R1, R12, R12 + MOVD R0, 168(R9) + ORR R12, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R0 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R6, R1 + MOVD R10, R12 + LSR R1, R12, R12 + + // v1 := table[val1&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v1.entry)) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // these two writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + ADD R7<<1, R7, R1 + ADD R1, R3, R15 + MOVH R0, (R15) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x02, R3, R3 + AND $0xff, R2, R15 + AND $0xff, R2, R16 + TST R16, R15 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_arm64(SB), $0-8 + // Preload values + MOVD ctx+0(FP), R1 + MOVBU 8(R1), R6 + MOVD 16(R1), R3 + MOVD 48(R1), R5 + MOVD 24(R1), R7 + MOVD 32(R1), R8 + MOVD (R1), R9 + + // Main loop +main_loop: + MOVD $0, R2 + CMP R5, R3 + CSET GE, R16 + BFI $0, R16, $8, R2 + + // br0.fillFast32() + MOVD 32(R9), R10 + MOVBU 40(R9), R11 + CMP $0x20, R11 + BLS skip_fill0 + MOVD 24(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD (R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 24(R9) + ORR R13, R10, R10 + + // exhausted += (br0.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br0.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br0.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVW R0, (R3) + + // update the bitreader structure + MOVD R10, 32(R9) + MOVB R11, 40(R9) + + // br1.fillFast32() + MOVD 80(R9), R10 + MOVBU 88(R9), R11 + CMP $0x20, R11 + BLS skip_fill1 + MOVD 72(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 48(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 72(R9) + ORR R13, R10, R10 + + // exhausted += (br1.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br1.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br1.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 80(R9) + MOVB R11, 88(R9) + + // br2.fillFast32() + MOVD 128(R9), R10 + MOVBU 136(R9), R11 + CMP $0x20, R11 + BLS skip_fill2 + MOVD 120(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 96(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 120(R9) + ORR R13, R10, R10 + + // exhausted += (br2.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br2.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br2.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 128(R9) + MOVB R11, 136(R9) + + // br3.fillFast32() + MOVD 176(R9), R10 + MOVBU 184(R9), R11 + CMP $0x20, R11 + BLS skip_fill3 + MOVD 168(R9), R12 + SUB $0x20, R11, R11 + SUB $0x04, R12, R12 + MOVD 144(R9), R13 + + // b.value |= uint64(low) << (b.bitsRead & 63) + ADD R13, R12, R15 + MOVWU (R15), R13 + MOVD R11, R1 + LSL R1, R13, R13 + MOVD R12, 168(R9) + ORR R13, R10, R10 + + // exhausted += (br3.off < 4) + CMP $0x04, R12 + CSINC HS, R2, R2, R16 + BFI $0, R16, $8, R2 + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v0 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v0.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val1 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v1 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v1.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // val2 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v2 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v2.entry) + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + + // val3 := br3.peekTopBits(peekBits) + MOVD R10, R12 + MOVD R6, R1 + LSR R1, R12, R12 + + // v3 := table[val0&mask] + ADD R12<<1, R8, R15 + MOVHU (R15), R1 + + // br3.advance(uint8(v3.entry) + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + LSL R1, R10, R10 + ADD R1, R11, R15 + BFI $0, R15, $8, R11 + REVW R0, R0 + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + ADD R7<<1, R7, R1 + ADD R1, R3, R15 + MOVW R0, (R15) + + // update the bitreader structure + MOVD R10, 176(R9) + MOVB R11, 184(R9) + ADD $0x04, R3, R3 + AND $0xff, R2, R15 + AND $0xff, R2, R16 + TST R16, R15 + BEQ main_loop + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R3, R3 + LSL $0x02, R3, R3 + MOVD R3, 40(R0) + RET + +// func decompress1x_main_loop_amd64(ctx *decompress1xContext) +TEXT ·decompress1x_main_loop_arm64(SB), $0-8 + MOVD ctx+0(FP), R1 + MOVD 16(R1), R2 + MOVD 24(R1), R3 + CMP $0x04, R3 + BLO error_max_decoded_size_exceeded + ADD R3, R2, R3 + MOVD (R1), R5 + MOVD (R5), R7 + MOVD 24(R5), R8 + MOVD 32(R5), R9 + MOVBU 40(R5), R10 + MOVD 32(R1), R5 + MOVBU 8(R1), R6 + JMP loop_condition + +main_loop: + // Check if we have room for 4 bytes in the output buffer + ADD $4, R2, R1 + CMP R3, R1 + BGE error_max_decoded_size_exceeded + + // Decode 4 values + CMP $0x20, R10 + BLT bitReader_fillFast_1_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + ADD R8, R7, R15 + MOVWU (R15), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_1_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + CMP $0x20, R10 + BLT bitReader_fillFast_2_end + SUB $0x20, R10, R10 + SUB $0x04, R8, R8 + ADD R8, R7, R15 + MOVWU (R15), R11 + MOVD R10, R1 + LSL R1, R11, R11 + ORR R11, R9, R9 + +bitReader_fillFast_2_end: + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $8, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + MOVD R6, R1 + MOVD R9, R11 + LSR R1, R11, R11 + ADD R11<<1, R5, R15 + MOVHU (R15), R1 + UBFX $8, R1, $8, R16 + BFI $0, R16, $8, R0 + MOVBU R1, R1 + ADD R1, R10, R10 + LSL R1, R9, R9 + REVW R0, R0 + + // Store the decoded values + MOVW R0, (R2) + ADD $0x04, R2, R2 + +loop_condition: + CMP $0x08, R8 + BGE main_loop + + // Update ctx structure + MOVD ctx+0(FP), R0 + MOVD 16(R0), R16 + SUB R16, R2, R2 + MOVD R2, 40(R0) + MOVD (R0), R0 + MOVD R8, 24(R0) + MOVD R9, 32(R0) + MOVB R10, 40(R0) + RET + + // Report error +error_max_decoded_size_exceeded: + MOVD ctx+0(FP), R0 + MOVD $-1, R1 + MOVD R1, 40(R0) + RET + +// skipped decompress1x_main_loop_bmi2 (generic twin preferred on arm64) diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_asm.go b/vendor/github.com/klauspost/compress/huff0/decompress_asm.go new file mode 100644 index 00000000000..4854dd43653 --- /dev/null +++ b/vendor/github.com/klauspost/compress/huff0/decompress_asm.go @@ -0,0 +1,193 @@ +//go:build (amd64 || arm64) && !appengine && !noasm && gc + +// This file contains the specialisation of Decoder.Decompress4X +// and Decoder.Decompress1X that use an asm implementation of their main loops. +// The asm function stubs and any per-arch dispatch live in decompress_amd64.go +// and decompress_arm64.go. +package huff0 + +import ( + "errors" + "fmt" +) + +// fallback8BitSize is the size where using Go version is faster. +const fallback8BitSize = 800 + +type decompress4xContext struct { + pbr *[4]bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + +// Decompress4X will decompress a 4X encoded stream. +// The length of the supplied input must match the end of a block exactly. +// The *capacity* of the dst slice must match the destination size of +// the uncompressed data exactly. +func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + if len(src) < 6+(4*1) { + return nil, errors.New("input too small") + } + + use8BitTables := d.actualTableLog <= 8 + if cap(dst) < fallback8BitSize && use8BitTables { + return d.decompress4X8bit(dst, src) + } + + var br [4]bitReaderShifted + // Decode "jump table" + start := 6 + for i := range 3 { + length := int(src[i*2]) | (int(src[i*2+1]) << 8) + if start+length >= len(src) { + return nil, errors.New("truncated input (or invalid offset)") + } + err := br[i].init(src[start : start+length]) + if err != nil { + return nil, err + } + start += length + } + err := br[3].init(src[start:]) + if err != nil { + return nil, err + } + + // destination, offset to match first output + dstSize := cap(dst) + dst = dst[:dstSize] + out := dst + dstEvery := (dstSize + 3) / 4 + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + single := d.dt.single[:tlSize] + + var decoded int + + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr: &br, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. + } + if use8BitTables { + decompress4x_8b_main_loop_asm(&ctx) + } else { + decompress4x_main_loop_asm(&ctx) + } + + decoded = ctx.decoded + out = out[decoded/4:] + } + + // Decode remaining. + remainBytes := dstEvery - (decoded / 4) + for i := range br { + offset := dstEvery * i + endsAt := min(offset+remainBytes, len(out)) + br := &br[i] + bitsLeft := br.remaining() + for bitsLeft > 0 { + br.fill() + if offset >= endsAt { + return nil, errors.New("corruption detected: stream overrun 4") + } + + // Read value and increment offset. + val := br.peekBitsFast(d.actualTableLog) + v := single[val&tlMask].entry + nBits := uint8(v) + br.advance(nBits) + bitsLeft -= uint(nBits) + out[offset] = uint8(v >> 8) + offset++ + } + if offset != endsAt { + return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) + } + decoded += offset - dstEvery*i + err = br.close() + if err != nil { + return nil, err + } + } + if dstSize != decoded { + return nil, errors.New("corruption detected: short output block") + } + return dst, nil +} + +type decompress1xContext struct { + pbr *bitReaderShifted + peekBits uint8 + out *byte + outCap int + tbl *dEntrySingle + decoded int +} + +// Error reported by asm implementations +const error_max_decoded_size_exeeded = -1 + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:maxDecodedSize] + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + + if maxDecodedSize >= 4 { + ctx := decompress1xContext{ + pbr: &br, + out: &dst[0], + outCap: maxDecodedSize, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + tbl: &d.dt.single[0], + } + + decompress1x_main_loop_asm(&ctx) + if ctx.decoded == error_max_decoded_size_exeeded { + return nil, ErrMaxDecodedSizeExceeded + } + + dst = dst[:ctx.decoded] + } + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if len(dst) >= maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 61039232224..e1bca5c686e 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm // This file contains a generic implementation of Decoder.Decompress4X. package huff0 diff --git a/vendor/github.com/klauspost/compress/internal/snapref/decode.go b/vendor/github.com/klauspost/compress/internal/snapref/decode.go index a2c82fcd226..584b7574b20 100644 --- a/vendor/github.com/klauspost/compress/internal/snapref/decode.go +++ b/vendor/github.com/klauspost/compress/internal/snapref/decode.go @@ -31,7 +31,7 @@ func DecodedLen(src []byte) (int, error) { // that the length header occupied. func decodedLen(src []byte) (blockLen, headerLen int, err error) { v, n := binary.Uvarint(src) - if n <= 0 || v > 0xffffffff { + if n <= 0 || n > 5 || v > 0xffffffff { return 0, 0, ErrCorrupt } diff --git a/vendor/github.com/klauspost/compress/s2/decode.go b/vendor/github.com/klauspost/compress/s2/decode.go index 264ffd0a9b4..17abb515a59 100644 --- a/vendor/github.com/klauspost/compress/s2/decode.go +++ b/vendor/github.com/klauspost/compress/s2/decode.go @@ -35,7 +35,7 @@ func DecodedLen(src []byte) (int, error) { // that the length header occupied. func decodedLen(src []byte) (blockLen, headerLen int, err error) { v, n := binary.Uvarint(src) - if n <= 0 || v > 0xffffffff { + if n <= 0 || n > 5 || v > 0xffffffff { return 0, 0, ErrCorrupt } diff --git a/vendor/github.com/klauspost/compress/s2/encode_all.go b/vendor/github.com/klauspost/compress/s2/encode_all.go index 9d12c44f38a..794ec8a6874 100644 --- a/vendor/github.com/klauspost/compress/s2/encode_all.go +++ b/vendor/github.com/klauspost/compress/s2/encode_all.go @@ -981,7 +981,7 @@ searchDict: cv = load64(src, s) continue } - } else if uint32(cv>>(checkRep*8)) == load32(src, s-repeat+checkRep) { + } else if repeat > 0 && uint32(cv>>(checkRep*8)) == load32(src, s-repeat+checkRep) { base := s + checkRep // Extend back for i := base - repeat; base > nextEmit && i > 0 && src[i-1] == src[base-1]; { diff --git a/vendor/github.com/klauspost/compress/s2/hashtable_pool.go b/vendor/github.com/klauspost/compress/s2/hashtable_pool.go index bc7cabd5c5c..ec972132b57 100644 --- a/vendor/github.com/klauspost/compress/s2/hashtable_pool.go +++ b/vendor/github.com/klauspost/compress/s2/hashtable_pool.go @@ -25,7 +25,7 @@ type betterTables struct { sTable [betterShortTableSize]uint32 } -var betterTablePool = sync.Pool{New: func() interface{} { return &betterTables{} }} +var betterTablePool = sync.Pool{New: func() any { return &betterTables{} }} // betterSnappyTables holds better-snappy compression hash tables. type betterSnappyTables struct { @@ -33,7 +33,7 @@ type betterSnappyTables struct { sTable [betterShortTableSize]uint32 } -var betterSnappyTablePool = sync.Pool{New: func() interface{} { return &betterSnappyTables{} }} +var betterSnappyTablePool = sync.Pool{New: func() any { return &betterSnappyTables{} }} // bestTables holds best compression hash tables. type bestTables struct { @@ -41,7 +41,7 @@ type bestTables struct { sTable [bestShortTableSize]uint64 } -var bestTablePool = sync.Pool{New: func() interface{} { return &bestTables{} }} +var bestTablePool = sync.Pool{New: func() any { return &bestTables{} }} // getBetterTables gets a zeroed betterTables from the pool. func getBetterTables() *betterTables { diff --git a/vendor/github.com/klauspost/compress/s2/reader.go b/vendor/github.com/klauspost/compress/s2/reader.go index 4d01c4190cc..17443e2c146 100644 --- a/vendor/github.com/klauspost/compress/s2/reader.go +++ b/vendor/github.com/klauspost/compress/s2/reader.go @@ -216,13 +216,18 @@ func (r *Reader) skippable(tmp []byte, n int, allowEOF bool, id uint8) (ok bool) return r.err == nil } if rs, ok := r.r.(io.ReadSeeker); ok { - _, err := rs.Seek(int64(n), io.SeekCurrent) - if err == nil { - return true - } - if err == io.ErrUnexpectedEOF || (r.err == io.EOF && !allowEOF) { - r.err = ErrCorrupt - return false + if cur, err := rs.Seek(0, io.SeekCurrent); err == nil { + if end, err := rs.Seek(0, io.SeekEnd); err == nil { + if cur+int64(n) <= end { + if _, err := rs.Seek(cur+int64(n), io.SeekStart); err == nil { + return true + } + } + if _, err := rs.Seek(cur, io.SeekStart); err != nil { + r.err = ErrCorrupt + return false + } + } } } for n > 0 { diff --git a/vendor/github.com/klauspost/compress/snappy/decode_strict.go b/vendor/github.com/klauspost/compress/snappy/decode_strict.go new file mode 100644 index 00000000000..6c28bcbbbc9 --- /dev/null +++ b/vendor/github.com/klauspost/compress/snappy/decode_strict.go @@ -0,0 +1,130 @@ +// Copyright 2011 The Snappy-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 snappy + +import "encoding/binary" + +// DecodeStrict returns the decoded form of src, like Decode. +// +// Unlike Decode, which delegates to the s2 decoder and accepts the s2 +// "repeat last offset" extension (a copy whose encoded offset is 0), +// DecodeStrict uses a strict standard-Snappy block decoder. Offset 0 is not +// valid in the standard Snappy block format, so such a copy is rejected with +// ErrCorrupt. This makes DecodeStrict match github.com/golang/snappy and the +// C++ reference decoder, at the cost of being slower than Decode. +// +// The returned slice may be a sub-slice of dst if dst was large enough to +// hold the entire decoded block. Otherwise, a newly allocated slice will be +// returned. +// +// The dst and src must not overlap. It is valid to pass a nil dst. +// +// DecodeStrict handles the Snappy block format, not the Snappy stream format. +func DecodeStrict(dst, src []byte) ([]byte, error) { + v, n := binary.Uvarint(src) + if n <= 0 || n > 5 || v > 0xffffffff { + return nil, ErrCorrupt + } + const wordSize = 32 << (^uint(0) >> 32 & 1) + if wordSize == 32 && v > 0x7fffffff { + return nil, ErrTooLarge + } + dLen := int(v) + if dLen <= cap(dst) { + dst = dst[:dLen] + } else { + dst = make([]byte, dLen) + } + if decodeStrict(dst, src[n:]) != 0 { + return nil, ErrCorrupt + } + return dst, nil +} + +func decodeStrict(dst, src []byte) int { + var d, s, offset, length int + for s < len(src) { + switch src[s] & 0x03 { + case 0x00: + x := uint32(src[s] >> 2) + switch { + case x < 60: + s++ + case x == 60: + s += 2 + if uint(s) > uint(len(src)) { + return 1 + } + x = uint32(src[s-1]) + case x == 61: + s += 3 + if uint(s) > uint(len(src)) { + return 1 + } + x = uint32(src[s-2]) | uint32(src[s-1])<<8 + case x == 62: + s += 4 + if uint(s) > uint(len(src)) { + return 1 + } + x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16 + case x == 63: + s += 5 + if uint(s) > uint(len(src)) { + return 1 + } + x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24 + } + length = int(x) + 1 + if length <= 0 || length > len(dst)-d || length > len(src)-s { + return 1 + } + copy(dst[d:], src[s:s+length]) + d += length + s += length + continue + case 0x01: + s += 2 + if uint(s) > uint(len(src)) { + return 1 + } + length = 4 + int(src[s-2])>>2&0x7 + offset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1])) + case 0x02: + s += 3 + if uint(s) > uint(len(src)) { + return 1 + } + length = 1 + int(src[s-3])>>2 + offset = int(uint32(src[s-2]) | uint32(src[s-1])<<8) + case 0x03: + s += 5 + if uint(s) > uint(len(src)) { + return 1 + } + length = 1 + int(src[s-5])>>2 + offset = int(uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24) + } + if offset <= 0 || d < offset || length > len(dst)-d { + return 1 + } + if offset >= length { + copy(dst[d:d+length], dst[d-offset:]) + d += length + continue + } + a := dst[d : d+length] + b := dst[d-offset:] + b = b[:len(a)] + for i := range a { + a[i] = b[i] + } + d += length + } + if d != len(dst) { + return 1 + } + return 0 +} diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index c11d7fa28e3..a5aeeaed06f 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -75,14 +75,47 @@ The above is fine for big encodes. However, whenever possible try to *reuse* the To reuse the encoder, you can use the `Reset(io.Writer)` function to change to another output. This will allow the encoder to reuse all resources and avoid wasteful allocations. -Currently stream encoding has 'light' concurrency, meaning up to 2 goroutines can be working on part -of a stream. This is independent of the `WithEncoderConcurrency(n)`, but that is likely to change +By default, stream encoding has 'light' concurrency, meaning up to 2 goroutines can be working on part +of a stream. This is independent of the `WithEncoderConcurrency(n)`, but that is likely to change in the future. So if you want to limit concurrency for future updates, specify the concurrency you would like. If you would like stream encoding to be done without spawning async goroutines, use `WithEncoderConcurrency(1)` which will compress input as each block is completed, blocking on writes until each has completed. +#### Parallel Stream Compression + +For maximum throughput on large streams, use `WithConcurrentBlocks(true)` together with +`WithEncoderConcurrency(n)` where n is the number of CPU cores you want to use. +This splits the input into large sections (jobs) that are compressed simultaneously by multiple goroutines, +similar to how the C zstd library does multithreaded compression. + +```Go +enc, err := zstd.NewWriter(out, + zstd.WithEncoderLevel(zstd.SpeedDefault), + zstd.WithEncoderConcurrency(runtime.GOMAXPROCS(0)), + zstd.WithConcurrentBlocks(true), +) +``` + +Each non-first job receives an overlap prefix from the previous job for match context, +so compression ratio is only marginally affected. Output is flushed in order, +producing a valid single-frame zstd stream. + +Benchmark on 1.8GB GOB stream (AMD Ryzen 9 9950X): + +| Level | 1 thread | 4 threads | 16 threads | 1T ratio | 16T ratio | +|---------|:----------:|:------------------:|:-------------------:|:--------:|:---------:| +| fastest | 783 MB/s | 2950 MB/s (3.8×) | 6939 MB/s (8.9×) | 12.24% | 12.26% | +| default | 728 MB/s | 2533 MB/s (3.5×) | 5340 MB/s (7.3×) | 10.67% | 10.68% | +| better | 434 MB/s | 1105 MB/s (2.5×) | 2206 MB/s (5.1×) | 9.14% | 9.21% | +| best | 129 MB/s | 367 MB/s (2.8×) | 884 MB/s (6.8×) | 8.48% | 8.63% | + +Notes: +* Not compatible with dictionary encoding. +* `Flush()` dispatches the current partial job, so latency-sensitive callers can force output. +* `EncodeAll` is unaffected — it uses its own concurrency via the encoder pool. + You can specify your desired compression level using `WithEncoderLevel()` option. Currently only pre-defined compression settings can be specified. diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 2329e996f86..51f9da03875 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -400,8 +400,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err } } var err error - // Use our out buffer. - huff.MaxDecodedSize = litRegenSize + // Decoder.Decompress* uses cap(dst) for the size limit. Do not write + // MaxDecodedSize on hist.huffTree: with a trained dictionary that + // pointer aliases the shared dict.litEnc and concurrent DecodeAll races. if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) } else { @@ -673,10 +674,6 @@ func (b *blockDec) executeSequences(hist *history) error { hbytes := hist.b if len(hbytes) > hist.windowSize { hbytes = hbytes[len(hbytes)-hist.windowSize:] - // We do not need history anymore. - if hist.dict != nil { - hist.dict.content = nil - } } hist.decoders.windowSize = hist.windowSize hist.decoders.out = b.dst[:0] diff --git a/vendor/github.com/klauspost/compress/zstd/dict.go b/vendor/github.com/klauspost/compress/zstd/dict.go index 2ffbfdf379e..67f40e79149 100644 --- a/vendor/github.com/klauspost/compress/zstd/dict.go +++ b/vendor/github.com/klauspost/compress/zstd/dict.go @@ -230,7 +230,7 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { } block := blockEnc{lowMem: false} block.init() - enc := encoder(&bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(maxMatchLen), bufferReset: math.MaxInt32 - int32(maxMatchLen*2), lowMem: false}}) + var enc encoder if o.Level != 0 { eOpts := encoderOptions{ level: o.Level, @@ -242,6 +242,7 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { enc = eOpts.encoder() } else { o.Level = SpeedBestCompression + enc = encoder(&bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(maxMatchLen), bufferReset: math.MaxInt32 - int32(maxMatchLen*2), lowMem: false}}) } var ( remain [256]int @@ -295,40 +296,81 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if offset > 3 { newOffsets[offset-3]++ } else { - newOffsets[uint32(o.Offsets[offset-1])]++ + // Repeat codes reference the training Offsets. Skip unset + // (zero) entries so they are not ranked as real offsets. + prev := o.Offsets[offset-1] + if prev > 0 { + newOffsets[uint32(prev)]++ + } } } } // Find most used offsets. var sortedOffsets []uint32 for k := range newOffsets { + if k == 0 { + continue + } sortedOffsets = append(sortedOffsets, k) } sort.Slice(sortedOffsets, func(i, j int) bool { a, b := sortedOffsets[i], sortedOffsets[j] - if a == b { + ca, cb := newOffsets[a], newOffsets[b] + if ca == cb { // Prefer the longer offset - return sortedOffsets[i] > sortedOffsets[j] + return a > b } - return newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]] + return ca > cb }) - if len(sortedOffsets) > 3 { - if debug { - print("Offsets:") - for i, v := range sortedOffsets { - if i > 20 { - break - } - printf("[%d: %d],", v, newOffsets[v]) + if debug { + print("Offsets:") + for i, v := range sortedOffsets { + if i > 20 { + break } - println("") + printf("[%d: %d],", v, newOffsets[v]) + } + println("") + } + // Dictionary recent-offsets must be three positive values within the + // history. Ranked matches may be fewer (or empty when only unset + // repeat codes were seen), so fill remaining slots with defaults. + used := make(map[int]bool, 3) + var finalOffsets [3]int + nOff := 0 + for _, v := range sortedOffsets { + iv := int(v) + if iv <= 0 || iv > len(hist) || used[iv] { + continue + } + finalOffsets[nOff] = iv + used[iv] = true + nOff++ + if nOff == 3 { + break } - - sortedOffsets = sortedOffsets[:3] } - for i, v := range sortedOffsets { - o.Offsets[i] = int(v) + for _, def := range []int{1, 4, 8} { + if nOff == 3 { + break + } + if def <= len(hist) && !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + for def := 1; nOff < 3 && def <= len(hist); def++ { + if !used[def] { + finalOffsets[nOff] = def + used[def] = true + nOff++ + } + } + if nOff < 3 { + return nil, fmt.Errorf("could not determine 3 valid dictionary offsets (history size %d)", len(hist)) } + o.Offsets = finalOffsets if debug { println("New repeat offsets", o.Offsets) } @@ -336,6 +378,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { if nUsed == 0 || seqs == 0 { return nil, fmt.Errorf("%d blocks, %d sequences found", nUsed, seqs) } + if litTotal == 0 { + return nil, errors.New("0 literals found") + } if debug { println("Sequences:", seqs, "Blocks:", nUsed, "Literals:", litTotal) } @@ -516,11 +561,10 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1]))) out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2]))) out.Write(hist) + if _, err := loadDict(out.Bytes()); err != nil { + return nil, fmt.Errorf("built dictionary failed validation: %w", err) + } if debug { - _, err := loadDict(out.Bytes()) - if err != nil { - panic(err) - } i, err := InspectDictionary(out.Bytes()) if err != nil { panic(err) diff --git a/vendor/github.com/klauspost/compress/zstd/enc_base.go b/vendor/github.com/klauspost/compress/zstd/enc_base.go index c4de134a7a4..c4fea575d6b 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_base.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_base.go @@ -128,6 +128,34 @@ func (e *fastBase) matchlen(s, t int32, src []byte) int32 { return int32(matchLen(src[s:], src[t:])) } +// resetBasePrefix resets the encoder state and loads prefix as initial history. +// This is used for parallel job encoding where non-first jobs need overlap context. +// Rep offsets are set to defaults [1,4,8] (invalidated, matching C behavior). +func (e *fastBase) resetBasePrefix(prefix []byte) { + if e.blk == nil { + e.blk = &blockEnc{lowMem: e.lowMem} + e.blk.init() + } else { + e.blk.reset(nil) + } + e.blk.initNewEncode() + if e.crc == nil { + e.crc = xxhash.New() + } else { + e.crc.Reset() + } + e.blk.dictLitEnc = nil + e.ensureHist(len(prefix) + maxCompressedBlockSize) + // Bump cur so old table entries fall outside the window. + // When cur >= bufferReset, leave it; the first Encode call + // will shift/clear tables, preserving valid prefix entries. + if e.cur < e.bufferReset { + e.cur += e.maxMatchOff + int32(len(e.hist)) + } + e.hist = e.hist[:0] + e.hist = append(e.hist, prefix...) +} + // Reset the encoding table. func (e *fastBase) resetBase(d *dict, singleBlock bool) { if e.blk == nil { diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go index 851799322bd..c71382dde65 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_best.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go @@ -551,3 +551,18 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) { // Reset table to initial state copy(e.table[:], e.dictTable) } + +func (e *bestFastEncoder) ResetPrefix(prefix []byte) { + e.resetBasePrefix(prefix) + if len(prefix) < 8 { + return + } + end := e.cur + int32(len(prefix)) - 8 + for i := e.cur; i < end; i++ { + cv := load6432(prefix, i-e.cur) + h := hashLen(cv, bestLongTableBits, bestLongLen) + e.longTable[h] = prevEntry{offset: i, prev: e.longTable[h].offset} + h0 := hashLen(cv, bestShortTableBits, bestShortLen) + e.table[h0] = prevEntry{offset: i, prev: e.table[h0].offset} + } +} diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go index 3305f09248c..523d57f3ad6 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_better.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go @@ -1096,6 +1096,20 @@ func (e *betterFastEncoder) Reset(d *dict, singleBlock bool) { } } +func (e *betterFastEncoder) ResetPrefix(prefix []byte) { + e.resetBasePrefix(prefix) + if len(prefix) < 8 { + return + } + end := e.cur + int32(len(prefix)) - 8 + for i := e.cur; i < end; i += 2 { + cv := load6432(prefix, i-e.cur) + h := hashLen(cv, betterLongTableBits, betterLongLen) + e.longTable[h] = prevEntry{offset: i, prev: e.longTable[h].offset} + e.table[hashLen(cv>>8, betterShortTableBits, betterShortLen)] = tableEntry{val: uint32(cv >> 8), offset: i + 1} + } +} + // ResetDict will reset and set a dictionary if not nil func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) { e.resetBase(d, singleBlock) @@ -1229,6 +1243,10 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) { e.allDirty = false } +func (e *betterFastEncoderDict) ResetPrefix([]byte) { + panic("ResetPrefix not supported for dict encoders") +} + func (e *betterFastEncoderDict) markLongShardDirty(entryNum uint32) { e.longTableShardDirty[entryNum/betterLongTableShardSize] = true } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go index 2fb6da112bc..712ba7ab582 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go @@ -1037,6 +1037,18 @@ func (e *doubleFastEncoder) Reset(d *dict, singleBlock bool) { } } +func (e *doubleFastEncoder) ResetPrefix(prefix []byte) { + e.fastEncoder.ResetPrefix(prefix) + if len(prefix) < 8 { + return + } + end := e.cur + int32(len(prefix)) - 8 + for i := e.cur + 1; i < end; i += 2 { + cv := load6432(prefix, i-e.cur) + e.longTable[hashLen(cv, dFastLongTableBits, dFastLongLen)] = tableEntry{val: uint32(cv), offset: i} + } +} + // ResetDict will reset and set a dictionary if not nil func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { allDirty := e.allDirty @@ -1102,6 +1114,10 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { } } +func (e *doubleFastEncoderDict) ResetPrefix([]byte) { + panic("ResetPrefix not supported for dict encoders") +} + func (e *doubleFastEncoderDict) markLongShardDirty(entryNum uint32) { e.longTableShardDirty[entryNum/dLongTableShardSize] = true } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go index 5e104f1a482..06045e24630 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go @@ -797,6 +797,19 @@ func (e *fastEncoder) Reset(d *dict, singleBlock bool) { } } +func (e *fastEncoder) ResetPrefix(prefix []byte) { + e.resetBasePrefix(prefix) + if len(prefix) < 8 { + return + } + end := e.cur + int32(len(prefix)) - 8 + // Index every 4th + for i := e.cur + 1; i < end; i += 4 { + cv := load6432(prefix, i-e.cur) + e.table[hashLen(cv, tableBits, tableFastHashLen)] = tableEntry{val: uint32(cv), offset: i} + } +} + // ResetDict will reset and set a dictionary if not nil func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { e.resetBase(d, singleBlock) @@ -866,6 +879,10 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { e.allDirty = false } +func (e *fastEncoderDict) ResetPrefix([]byte) { + panic("ResetPrefix not supported for dict encoders") +} + func (e *fastEncoderDict) markAllShardsDirty() { e.allDirty = true } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_jobs.go b/vendor/github.com/klauspost/compress/zstd/enc_jobs.go new file mode 100644 index 00000000000..95ce67ac05a --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/enc_jobs.go @@ -0,0 +1,352 @@ +// Copyright 2019+ Klaus Post. All rights reserved. +// License information can be found in the LICENSE file. +// Based on work by Yann Collet, released under BSD License. + +package zstd + +import ( + "fmt" + rdebug "runtime/debug" + "sync" +) + +type encJob struct { + prefix []byte // overlap from previous job (nil for first) + input []byte // job's own input data (swapped from filling) + last bool // last block of last job gets last=true + output []byte // compressed blocks (filled by worker) + err error // encoding error + done chan struct{} // closed when complete +} + +type jobState struct { + jobSize int + overlapSize int + filling []byte // accumulates input up to jobSize + nextPrefix []byte // overlap prefix prepared for the next dispatched job + + jobSeq int // next job sequence number + + jobCh chan *encJob // dispatch to workers + resultCh chan *encJob // ordered results to flusher + + workerWg sync.WaitGroup + flusherWg sync.WaitGroup + + mu sync.Mutex + flushedSeq int // last flushed sequence number + cond *sync.Cond + + flusherErr error + started bool + + inputPool sync.Pool // *[]byte buffers of jobSize cap + outputPool sync.Pool // *[]byte buffers for compressed output + overlapPool sync.Pool // *[]byte buffers for overlap prefixes +} + +func (e *Encoder) startJobWorkers() { + js := &e.state.jobs + n := e.o.concurrent + js.jobCh = make(chan *encJob, n) + js.resultCh = make(chan *encJob, n) + js.flushedSeq = 0 + js.cond = sync.NewCond(&js.mu) + + // Workers borrow encoders from the shared e.encoders pool per-job. + // Ensure the pool is initialized before any worker tries to borrow. + e.init.Do(e.initialize) + + for range n { + js.workerWg.Add(1) + go e.jobWorker() + } + js.flusherWg.Add(1) + go e.jobFlusher() + js.started = true +} + +func (e *Encoder) jobWorker() { + js := &e.state.jobs + defer js.workerWg.Done() + for job := range js.jobCh { + enc := <-e.encoders + e.compressJob(enc, job) + e.encoders <- enc + close(job.done) + } +} + +func (e *Encoder) compressJob(enc encoder, job *encJob) { + defer func() { + if r := recover(); r != nil { + job.err = fmt.Errorf("panic in parallel job: %v", r) + rdebug.PrintStack() + } + }() + + if len(job.prefix) > 0 { + enc.ResetPrefix(job.prefix) + } else { + enc.Reset(nil, false) + } + + data := job.input + if len(data) == 0 && job.last { + blk := enc.Block() + blk.reset(nil) + blk.last = true + blk.encodeRaw(nil) + job.output = append(job.output, blk.output...) + return + } + + blk := enc.Block() + for len(data) > 0 { + todo := data + if len(todo) > e.o.blockSize { + todo = todo[:e.o.blockSize] + } + data = data[len(todo):] + + blk.pushOffsets() + enc.Encode(blk, todo) + blk.last = len(data) == 0 && job.last + + err := blk.encode(todo, e.o.noEntropy, !e.o.allLitEntropy) + if err != nil { + job.err = err + return + } + job.output = append(job.output, blk.output...) + blk.reset(nil) + } +} + +func (js *jobState) getInputBuf(size int) []byte { + if v := js.inputPool.Get(); v != nil { + bp := v.(*[]byte) + b := *bp + if cap(b) >= size { + return b[:0] + } + } + return make([]byte, 0, size) +} + +func (js *jobState) putInputBuf(b []byte) { + if cap(b) > 0 { + b = b[:0] + js.inputPool.Put(&b) + } +} + +func (js *jobState) getOutputBuf(size int) []byte { + if v := js.outputPool.Get(); v != nil { + bp := v.(*[]byte) + b := *bp + if cap(b) >= size { + return b[:0] + } + } + return make([]byte, 0, size) +} + +func (js *jobState) putOutputBuf(b []byte) { + if cap(b) > 0 { + b = b[:0] + js.outputPool.Put(&b) + } +} + +func (js *jobState) getOverlapBuf(size int) []byte { + if v := js.overlapPool.Get(); v != nil { + bp := v.(*[]byte) + b := *bp + if cap(b) >= size { + return b[:size] + } + } + return make([]byte, size) +} + +func (js *jobState) putOverlapBuf(b []byte) { + if cap(b) > 0 { + b = b[:0] + js.overlapPool.Put(&b) + } +} + +func (e *Encoder) jobFlusher() { + js := &e.state.jobs + defer js.flusherWg.Done() + for job := range js.resultCh { + <-job.done + // Worker has fully exited compressJob, so the prefix is no longer + // in use. Return it to the pool regardless of outcome. + if job.prefix != nil { + js.putOverlapBuf(job.prefix) + job.prefix = nil + } + if job.err != nil { + js.mu.Lock() + js.flusherErr = job.err + js.cond.Broadcast() + js.mu.Unlock() + for range js.resultCh { + } + return + } + if len(job.output) > 0 { + _, err := e.state.w.Write(job.output) + if err != nil { + js.mu.Lock() + js.flusherErr = err + js.cond.Broadcast() + js.mu.Unlock() + for range js.resultCh { + } + return + } + e.state.nWritten += int64(len(job.output)) + } + // Return buffers to pools. + js.putInputBuf(job.input) + js.putOutputBuf(job.output) + job.input = nil + job.output = nil + + js.mu.Lock() + js.flushedSeq++ + js.cond.Broadcast() + js.mu.Unlock() + } +} + +func (e *Encoder) shutdownJobWorkers() { + js := &e.state.jobs + if !js.started { + return + } + close(js.jobCh) + js.workerWg.Wait() + close(js.resultCh) + js.flusherWg.Wait() + js.started = false +} + +// waitAllJobs blocks until all dispatched jobs have been flushed. +func (e *Encoder) waitAllJobs() { + js := &e.state.jobs + if !js.started { + return + } + js.mu.Lock() + for js.flushedSeq < js.jobSeq && js.flusherErr == nil { + js.cond.Wait() + } + js.mu.Unlock() +} + +func (e *Encoder) dispatchJob(final bool) error { + s := &e.state + js := &s.jobs + + js.mu.Lock() + fErr := js.flusherErr + js.mu.Unlock() + if fErr != nil { + return fErr + } + + if !s.headerWritten { + // Single-block optimization: fall through to encodeAll path. + if final && len(js.filling) > 0 && len(js.filling) <= e.o.blockSize { + s.current = e.encodeAll(s.encoder, js.filling, s.current[:0]) + var n2 int + n2, s.err = s.w.Write(s.current) + if s.err != nil { + return s.err + } + s.nWritten += int64(n2) + s.nInput += int64(len(js.filling)) + s.current = s.current[:0] + js.filling = js.filling[:0] + s.headerWritten = true + s.fullFrameWritten = true + s.eofWritten = true + return nil + } + if final && len(js.filling) == 0 && !e.o.fullZero { + s.headerWritten = true + s.fullFrameWritten = true + s.eofWritten = true + return nil + } + + var tmp [maxHeaderSize]byte + fh := frameHeader{ + ContentSize: uint64(s.frameContentSize), + WindowSize: uint32(s.encoder.WindowSize(s.frameContentSize)), + SingleSegment: false, + Checksum: e.o.crc, + DictID: 0, + } + dst := fh.appendTo(tmp[:0]) + var n2 int + n2, s.err = s.w.Write(dst) + if s.err != nil { + return s.err + } + s.nWritten += int64(n2) + s.headerWritten = true + } + + if len(js.filling) == 0 && !final { + return nil + } + + if !js.started { + e.startJobWorkers() + } + + // Estimate output size for pooled buffer. + outputEst := max(len(js.filling)/2, 512) + + job := &encJob{ + last: final, + done: make(chan struct{}), + output: js.getOutputBuf(outputEst), + } + + // Each job owns its prefix slice; the flusher returns it to the pool + // after <-job.done, so workers and dispatch never share a buffer. + if js.nextPrefix != nil { + job.prefix = js.nextPrefix + js.nextPrefix = nil + } + + // Build the next job's prefix from the tail of this job's input. + if !final && len(js.filling) > 0 { + overlapLen := min(js.overlapSize, len(js.filling)) + np := js.getOverlapBuf(overlapLen) + copy(np, js.filling[len(js.filling)-overlapLen:]) + js.nextPrefix = np + } + + // Swap filling buffer into job — zero-copy for the input data. + job.input = js.filling + js.filling = js.getInputBuf(js.jobSize) + + s.nInput += int64(len(job.input)) + js.jobSeq++ + + if final { + s.eofWritten = true + } + + js.resultCh <- job + js.jobCh <- job + + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go index 0f2a00a0033..6ee96d8730c 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder.go @@ -38,6 +38,7 @@ type encoder interface { WindowSize(size int64) int32 UseBlock(*blockEnc) Reset(d *dict, singleBlock bool) + ResetPrefix(prefix []byte) } type encoderState struct { @@ -60,6 +61,9 @@ type encoderState struct { wg sync.WaitGroup // This waitgroup indicates we have a block encoding/writing. wWg sync.WaitGroup + + // Parallel job state (used when concurrentBlocks is enabled). + jobs jobState } // NewWriter will create a new Zstandard encoder. @@ -74,6 +78,9 @@ func NewWriter(w io.Writer, opts ...EOption) (*Encoder, error) { return nil, err } } + if e.o.concurrentBlocks && (e.o.dict != nil || e.o.concurrent <= 1) { + e.o.concurrentBlocks = false + } if w != nil { e.Reset(w) } @@ -95,12 +102,31 @@ func (e *Encoder) initialize() { // as a new, independent stream. func (e *Encoder) Reset(w io.Writer) { s := &e.state + + if e.o.concurrentBlocks { + e.shutdownJobWorkers() + js := &s.jobs + js.jobSize = e.o.jobSize() + js.overlapSize = e.o.overlapSize() + // js.filling is allocated lazily on first Write/ReadFrom so callers + // that only use EncodeAll don't pay the (up to ~32 MB) jobSize cost. + js.filling = js.filling[:0] + if js.nextPrefix != nil { + js.putOverlapBuf(js.nextPrefix) + js.nextPrefix = nil + } + js.jobSeq = 0 + js.flushedSeq = 0 + js.flusherErr = nil + js.started = false + } + s.wg.Wait() s.wWg.Wait() if cap(s.filling) == 0 { s.filling = make([]byte, 0, e.o.blockSize) } - if e.o.concurrent > 1 { + if e.o.concurrent > 1 && !e.o.concurrentBlocks { if cap(s.current) == 0 { s.current = make([]byte, 0, e.o.blockSize) } @@ -145,6 +171,9 @@ func (e *Encoder) ResetWithOptions(w io.Writer, opts ...EOption) error { } } hasDict := e.o.dict != nil + if e.o.concurrentBlocks && hasDict { + e.o.concurrentBlocks = false + } if hadDict != hasDict { // Dict presence changed — encoder type must be recreated. e.state.encoder = nil @@ -176,6 +205,49 @@ func (e *Encoder) Write(p []byte) (n int, err error) { if s.eofWritten { return 0, ErrEncoderClosed } + if e.o.concurrentBlocks { + return e.writeJobs(p) + } + return e.writeBlocks(p) +} + +func (e *Encoder) writeJobs(p []byte) (n int, err error) { + s := &e.state + js := &s.jobs + jobSize := js.jobSize + if cap(js.filling) == 0 && len(p) > 0 { + js.filling = make([]byte, 0, jobSize) + } + for len(p) > 0 { + if len(p)+len(js.filling) < jobSize { + if e.o.crc { + _, _ = s.encoder.CRC().Write(p) + } + js.filling = append(js.filling, p...) + return n + len(p), nil + } + add := p + if len(p)+len(js.filling) > jobSize { + add = add[:jobSize-len(js.filling)] + } + if e.o.crc { + _, _ = s.encoder.CRC().Write(add) + } + js.filling = append(js.filling, add...) + p = p[len(add):] + n += len(add) + if len(js.filling) < jobSize { + return n, nil + } + if err := e.dispatchJob(false); err != nil { + return n, err + } + } + return n, nil +} + +func (e *Encoder) writeBlocks(p []byte) (n int, err error) { + s := &e.state for len(p) > 0 { if len(p)+len(s.filling) < e.o.blockSize { if e.o.crc { @@ -374,6 +446,10 @@ func (e *Encoder) ReadFrom(r io.Reader) (n int64, err error) { println("Using ReadFrom") } + if e.o.concurrentBlocks { + return e.readFromJobs(r) + } + // Flush any current writes. if len(e.state.filling) > 0 { if err := e.nextBlock(false); err != nil { @@ -387,7 +463,6 @@ func (e *Encoder) ReadFrom(r io.Reader) (n int64, err error) { if e.o.crc { _, _ = e.state.encoder.CRC().Write(src[:n2]) } - // src is now the unfilled part... src = src[n2:] n += int64(n2) switch err { @@ -420,15 +495,63 @@ func (e *Encoder) ReadFrom(r io.Reader) (n int64, err error) { } } +func (e *Encoder) readFromJobs(r io.Reader) (n int64, err error) { + js := &e.state.jobs + jobSize := js.jobSize + + // Flush any current filling. + if len(js.filling) > 0 { + if err := e.dispatchJob(false); err != nil { + return 0, err + } + } + + if cap(js.filling) < jobSize { + js.filling = make([]byte, 0, jobSize) + } + js.filling = js.filling[:jobSize] + src := js.filling + for { + n2, err := r.Read(src) + if e.o.crc { + _, _ = e.state.encoder.CRC().Write(src[:n2]) + } + src = src[n2:] + n += int64(n2) + switch err { + case io.EOF: + js.filling = js.filling[:len(js.filling)-len(src)] + return n, nil + case nil: + default: + e.state.err = err + return n, err + } + if len(src) > 0 { + continue + } + if err = e.dispatchJob(false); err != nil { + return n, err + } + if cap(js.filling) < jobSize { + js.filling = make([]byte, 0, jobSize) + } + js.filling = js.filling[:jobSize] + src = js.filling + } +} + // Flush will send the currently written data to output // and block until everything has been written. // This should only be used on rare occasions where pushing the currently queued data is critical. func (e *Encoder) Flush() error { s := &e.state + if e.o.concurrentBlocks { + return e.flushJobs() + } if len(s.filling) > 0 { err := e.nextBlock(false) if err != nil { - // Ignore Flush after Close. if errors.Is(s.err, ErrEncoderClosed) { return nil } @@ -438,7 +561,6 @@ func (e *Encoder) Flush() error { s.wg.Wait() s.wWg.Wait() if s.err != nil { - // Ignore Flush after Close. if errors.Is(s.err, ErrEncoderClosed) { return nil } @@ -447,6 +569,20 @@ func (e *Encoder) Flush() error { return s.writeErr } +func (e *Encoder) flushJobs() error { + js := &e.state.jobs + if len(js.filling) > 0 { + if err := e.dispatchJob(false); err != nil { + return err + } + } + e.waitAllJobs() + js.mu.Lock() + fErr := js.flusherErr + js.mu.Unlock() + return fErr +} + // Close will flush the final output and close the stream. // The function will block until everything has been written. // The Encoder can still be re-used after calling this. @@ -455,12 +591,16 @@ func (e *Encoder) Close() error { if s.encoder == nil { return nil } + if e.o.concurrentBlocks { + return e.closeJobs() + } if s.w == nil { if len(s.filling) == 0 && !s.headerWritten && !s.eofWritten && s.nInput == 0 { return nil } return errors.New("zstd: encoder has no writer") } + err := e.nextBlock(true) if err != nil { if errors.Is(s.err, ErrEncoderClosed) { @@ -511,6 +651,68 @@ func (e *Encoder) Close() error { return s.err } +func (e *Encoder) closeJobs() error { + s := &e.state + js := &s.jobs + + if errors.Is(s.err, ErrEncoderClosed) { + return nil + } + + if s.w == nil { + if len(js.filling) == 0 && !s.headerWritten && !s.eofWritten && s.nInput == 0 { + return nil + } + return errors.New("zstd: encoder has no writer") + } + + if err := e.dispatchJob(true); err != nil { + e.shutdownJobWorkers() + if errors.Is(s.err, ErrEncoderClosed) { + return nil + } + return err + } + + if s.frameContentSize > 0 && s.nInput != s.frameContentSize { + e.shutdownJobWorkers() + return fmt.Errorf("frame content size %d given, but %d bytes was written", s.frameContentSize, s.nInput) + } + + if s.fullFrameWritten { + e.shutdownJobWorkers() + s.err = ErrEncoderClosed + return nil + } + + e.shutdownJobWorkers() + if js.flusherErr != nil { + return js.flusherErr + } + + // Write CRC + if e.o.crc { + var tmp [4]byte + _, s.err = s.w.Write(s.encoder.AppendCRC(tmp[:0])) + s.nWritten += 4 + } + + // Add padding + if s.err == nil && e.o.pad > 0 { + add := calcSkippableFrame(s.nWritten, int64(e.o.pad)) + frame, err := skippableFrame(js.filling[:0], add, rand.Reader) + if err != nil { + return err + } + _, s.err = s.w.Write(frame) + } + if s.err == nil { + s.err = ErrEncoderClosed + return nil + } + return s.err +} + // EncodeAll will encode all input in src and append it to dst. // This function can be called concurrently, but each call will only run on a single goroutine. // If empty input is given, nothing is returned, unless WithZeroFrames is specified. diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go index e217be0a17a..a8081496739 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go @@ -14,22 +14,23 @@ type EOption func(*encoderOptions) error // options retains accumulated state of multiple options. type encoderOptions struct { - resetOpt bool - concurrent int - level EncoderLevel - single *bool - pad int - blockSize int - windowSize int - crc bool - fullZero bool - noEntropy bool - allLitEntropy bool - customWindow bool - customALEntropy bool - customBlockSize bool - lowMem bool - dict *dict + resetOpt bool + concurrent int + level EncoderLevel + single *bool + pad int + blockSize int + windowSize int + crc bool + fullZero bool + noEntropy bool + allLitEntropy bool + customWindow bool + customALEntropy bool + customBlockSize bool + lowMem bool + dict *dict + concurrentBlocks bool } func (o *encoderOptions) setDefault() { @@ -333,6 +334,42 @@ func WithLowerEncoderMem(b bool) EOption { } } +// WithConcurrentBlocks enables job-based parallel compression for streams. +// When enabled and concurrent > 1, input is split into large sections (jobs) +// that are compressed simultaneously by multiple goroutines. +// Each non-first job receives an overlap prefix from the previous job for match context. +// Output is flushed in order, producing a valid single-frame zstd stream. +// +// Currently disabled when used with dictionary encoding. +// Cannot be changed with ResetWithOptions. +func WithConcurrentBlocks(b bool) EOption { + return func(o *encoderOptions) error { + if o.resetOpt && b != o.concurrentBlocks { + return errors.New("WithConcurrentBlocks cannot be changed on Reset") + } + o.concurrentBlocks = b + return nil + } +} + +// jobSize returns the input section size per parallel job. +func (o *encoderOptions) jobSize() int { + s := max(o.windowSize*4, 512<<10) + return s +} + +// overlapSize returns the overlap prefix size for parallel jobs. +func (o *encoderOptions) overlapSize() int { + switch o.level { + case SpeedBestCompression: + return o.windowSize / 2 + case SpeedBetterCompression: + return o.windowSize / 4 + default: + return o.windowSize / 8 + } +} + // WithEncoderDict allows to register a dictionary that will be used for the encode. // // The slice dict must be in the [dictionary format] produced by diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s index bcde3986953..deeadc49eb0 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s @@ -1,4 +1,4 @@ -// Code generated by command: go run gen_fse.go -out ../fse_decoder_amd64.s -pkg=zstd. DO NOT EDIT. +// Code generated by command: go run gen_fse.go -out ../fse_decoder.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. //go:build !appengine && !noasm && gc && !noasm diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s b/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s new file mode 100644 index 00000000000..77ee3913f05 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s @@ -0,0 +1,153 @@ +// Code generated by command: go run gen_fse.go -out ../fse_decoder.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && !appengine && !noasm && gc && !noasm + +// func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int +TEXT ·buildDtable_asm(SB), $0-24 + MOVD ctx+8(FP), R1 + MOVD s+0(FP), R6 + + // Load values + MOVBU 4098(R6), R2 + MOVD $0, R0 + MOVD $1, R16 + LSL R2, R16, R16 + ORR R16, R0, R0 + MOVD (R1), R3 + MOVD 16(R1), R5 + SUB $1, R0, R7 + MOVD 8(R1), R1 + MOVHU 4096(R6), R6 + + // End load values + // Init, lay down lowprob symbols + MOVD $0, R8 + JMP init_main_loop_condition + +init_main_loop: + ADD R8<<1, R1, R15 + MOVH (R15), R9 + AND $0xffff, R9, R15 + MOVD $-1, R16 + AND $0xffff, R16, R16 + CMP R16, R15 + BNE do_not_update_high_threshold + ADD R7<<3, R5, R15 + MOVB R8, 1(R15) + SUB $1, R7, R7 + MOVD $0x0000000000000001, R9 + +do_not_update_high_threshold: + ADD R8<<1, R3, R15 + MOVH R9, (R15) + ADD $1, R8, R8 + +init_main_loop_condition: + CMP R6, R8 + BLT init_main_loop + + // Spread symbols + // Calculate table step + MOVD R0, R8 + LSR $0x01, R8, R8 + MOVD R0, R9 + LSR $0x03, R9, R9 + ADD R9, R8, R8 + ADD $3, R8, R8 + + // Fill add bits values + SUB $1, R0, R9 + MOVD $0, R10 + MOVD $0, R11 + JMP spread_main_loop_condition + +spread_main_loop: + MOVD $0, R12 + ADD R11<<1, R1, R15 + MOVH (R15), R13 + JMP spread_inner_loop_condition + +spread_inner_loop: + ADD R10<<3, R5, R15 + MOVB R11, 1(R15) + +adjust_position: + ADD R8, R10, R10 + AND R9, R10, R10 + CMP R7, R10 + BGT adjust_position + ADD $1, R12, R12 + +spread_inner_loop_condition: + CMP R13, R12 + BLT spread_inner_loop + ADD $1, R11, R11 + +spread_main_loop_condition: + CMP R6, R11 + BLT spread_main_loop + TST R10, R10 + BEQ spread_check_ok + MOVD ctx+8(FP), R0 + MOVD R10, 24(R0) + MOVD $+1, R16 + MOVD R16, ret+16(FP) + RET + +spread_check_ok: + // Build Decoding table + MOVD $0, R6 + +build_table_main_table: + ADD R6<<3, R5, R15 + MOVBU 1(R15), R1 + ADD R1<<1, R3, R15 + MOVHU (R15), R7 + ADD $1, R7, R8 + ADD R1<<1, R3, R15 + MOVH R8, (R15) + MOVD R7, R8 + CLZ R8, R16 + MOVD $63, R8 + SUB R16, R8, R8 + MOVD R2, R1 + SUB R8, R1, R1 + LSL R1, R7, R7 + SUB R0, R7, R7 + ADD R6<<3, R5, R15 + MOVB R1, (R15) + ADD R6<<3, R5, R15 + MOVH R7, 2(R15) + CMP R0, R7 + BLE build_table_check1_ok + MOVD ctx+8(FP), R1 + MOVD R7, 24(R1) + MOVD R0, 32(R1) + MOVD $+2, R16 + MOVD R16, ret+16(FP) + RET + +build_table_check1_ok: + AND $0xff, R1, R15 + AND $0xff, R1, R16 + TST R16, R15 + BNE build_table_check2_ok + AND $0xffff, R7, R15 + AND $0xffff, R6, R16 + CMP R16, R15 + BNE build_table_check2_ok + MOVD ctx+8(FP), R0 + MOVD R7, 24(R0) + MOVD R6, 32(R0) + MOVD $+3, R16 + MOVD R16, ret+16(FP) + RET + +build_table_check2_ok: + ADD $1, R6, R6 + CMP R0, R6 + BLT build_table_main_table + MOVD $+0, R16 + MOVD R16, ret+16(FP) + RET diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_asm.go similarity index 81% rename from vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go rename to vendor/github.com/klauspost/compress/zstd/fse_decoder_asm.go index b8c8607b5df..4ffc7e3c9fd 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_asm.go @@ -1,4 +1,4 @@ -//go:build amd64 && !appengine && !noasm && gc +//go:build (amd64 || arm64) && !appengine && !noasm && gc package zstd @@ -6,6 +6,10 @@ import ( "fmt" ) +// buildDtable_asm is generated by _generate/gen_fse.go and lowered to each +// architecture (amd64 by goasm, arm64 by the avo arm64 lowering printer). The +// Go side is identical across architectures, so it lives here. + type buildDtableAsmContext struct { // inputs stateTable *uint16 @@ -18,7 +22,7 @@ type buildDtableAsmContext struct { errParam2 uint64 } -// buildDtable_asm is an x86 assembly implementation of fseDecoder.buildDtable. +// buildDtable_asm is an assembly implementation of fseDecoder.buildDtable. // Function returns non-zero exit code on error. // //go:noescape diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go index 2138f8091a9..38fd2ccb2a9 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm package zstd diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go index 18c3703ddc9..1281da885c5 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go @@ -3,321 +3,83 @@ package zstd import ( - "fmt" - "io" - "github.com/klauspost/compress/internal/cpuinfo" ) -type decodeSyncAsmContext struct { - llTable []decSymbol - mlTable []decSymbol - ofTable []decSymbol - llState uint64 - mlState uint64 - ofState uint64 - iteration int - litRemain int - out []byte - outPosition int - literals []byte - litPosition int - history []byte - windowSize int - ll int // set on error (not for all errors, please refer to _generate/gen.go) - ml int // set on error (not for all errors, please refer to _generate/gen.go) - mo int // set on error (not for all errors, please refer to _generate/gen.go) -} +// The shared decode/decodeSync/executeSimple wrappers and context structs live +// in seqdec_asm.go; this file only declares the amd64 asm routines and the +// dispatch helpers that pick the BMI2 / non-BMI2 (and 56-bit / safe) variant. -// sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm. +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. // // Please refer to seqdec_generic.go for the reference implementation. // //go:noescape -func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int -// sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions. +// sequenceDecs_decode_56_amd64 implements the main loop of sequenceDecs in x86 asm. // //go:noescape -func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int -// sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer. +// sequenceDecs_decode_bmi2 implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. // //go:noescape -func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int -// sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer. +// sequenceDecs_decode_56_bmi2 implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. // //go:noescape -func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int - -// decode sequences from the stream with the provided history but without a dictionary. -func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { - if len(s.dict) > 0 { - return false, nil - } - if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSize { - return false, nil - } - - // FIXME: Using unsafe memory copies leads to rare, random crashes - // with fuzz testing. It is therefore disabled for now. - const useSafe = true - /* - useSafe := false - if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { - useSafe = true - } - if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { - useSafe = true - } - if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { - useSafe = true - } - */ - - br := s.br - - maxBlockSize := min(s.windowSize, maxCompressedBlockSize) - - ctx := decodeSyncAsmContext{ - llTable: s.litLengths.fse.dt[:maxTablesize], - mlTable: s.matchLengths.fse.dt[:maxTablesize], - ofTable: s.offsets.fse.dt[:maxTablesize], - llState: uint64(s.litLengths.state.state), - mlState: uint64(s.matchLengths.state.state), - ofState: uint64(s.offsets.state.state), - iteration: s.nSeqs - 1, - litRemain: len(s.literals), - out: s.out, - outPosition: len(s.out), - literals: s.literals, - windowSize: s.windowSize, - history: hist, - } - - s.seqSize = 0 - startSize := len(s.out) +func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int - var errCode int +// decodeAsm runs the sequenceDecs decode loop, choosing the BMI2 / 56-bit variant. +func decodeAsm(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext, lte56bits bool) int { if cpuinfo.HasBMI2() { - if useSafe { - errCode = sequenceDecs_decodeSync_safe_bmi2(s, br, &ctx) - } else { - errCode = sequenceDecs_decodeSync_bmi2(s, br, &ctx) - } - } else { - if useSafe { - errCode = sequenceDecs_decodeSync_safe_amd64(s, br, &ctx) - } else { - errCode = sequenceDecs_decodeSync_amd64(s, br, &ctx) - } - } - switch errCode { - case noError: - break - - case errorMatchLenOfsMismatch: - return true, fmt.Errorf("zero matchoff and matchlen (%d) > 0", ctx.ml) - - case errorMatchLenTooBig: - return true, fmt.Errorf("match len (%d) bigger than max allowed length", ctx.ml) - - case errorMatchOffTooBig: - return true, fmt.Errorf("match offset (%d) bigger than current history (%d)", - ctx.mo, ctx.outPosition+len(hist)-startSize) - - case errorNotEnoughLiterals: - return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", - ctx.ll, ctx.litRemain+ctx.ll) - - case errorOverread: - return true, io.ErrUnexpectedEOF - - case errorNotEnoughSpace: - size := ctx.outPosition + ctx.ll + ctx.ml - if debugDecoder { - println("msl:", s.maxSyncLen, "cap", cap(s.out), "bef:", startSize, "sz:", size-startSize, "mbs:", maxBlockSize, "outsz:", cap(s.out)-startSize) + if lte56bits { + return sequenceDecs_decode_56_bmi2(s, br, ctx) } - return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) - - default: - return true, fmt.Errorf("sequenceDecs_decode returned erroneous code %d", errCode) - } - - s.seqSize += ctx.litRemain - if s.seqSize > maxBlockSize { - return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + return sequenceDecs_decode_bmi2(s, br, ctx) } - err := br.close() - if err != nil { - printf("Closing sequences: %v, %+v\n", err, *br) - return true, err + if lte56bits { + return sequenceDecs_decode_56_amd64(s, br, ctx) } - - s.literals = s.literals[ctx.litPosition:] - t := ctx.outPosition - s.out = s.out[:t] - - // Add final literals - s.out = append(s.out, s.literals...) - if debugDecoder { - t += len(s.literals) - if t != len(s.out) { - panic(fmt.Errorf("length mismatch, want %d, got %d", len(s.out), t)) - } - } - - return true, nil + return sequenceDecs_decode_amd64(s, br, ctx) } -// -------------------------------------------------------------------------------- - -type decodeAsmContext struct { - llTable []decSymbol - mlTable []decSymbol - ofTable []decSymbol - llState uint64 - mlState uint64 - ofState uint64 - iteration int - seqs []seqVals - litRemain int -} - -const noError = 0 - -// error reported when mo == 0 && ml > 0 -const errorMatchLenOfsMismatch = 1 - -// error reported when ml > maxMatchLen -const errorMatchLenTooBig = 2 - -// error reported when mo > available history or mo > s.windowSize -const errorMatchOffTooBig = 3 - -// error reported when the sum of literal lengths exeeceds the literal buffer size -const errorNotEnoughLiterals = 4 - -// error reported when capacity of `out` is too small -const errorNotEnoughSpace = 5 - -// error reported when bits are overread. -const errorOverread = 6 - -// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. +// sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm. // // Please refer to seqdec_generic.go for the reference implementation. // //go:noescape -func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int -// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. -// -// Please refer to seqdec_generic.go for the reference implementation. +// sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions. // //go:noescape -func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int -// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer. // //go:noescape -func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int -// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer. // //go:noescape -func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int - -// decode sequences from the stream without the provided history. -func (s *sequenceDecs) decode(seqs []seqVals) error { - br := s.br - - maxBlockSize := min(s.windowSize, maxCompressedBlockSize) - - ctx := decodeAsmContext{ - llTable: s.litLengths.fse.dt[:maxTablesize], - mlTable: s.matchLengths.fse.dt[:maxTablesize], - ofTable: s.offsets.fse.dt[:maxTablesize], - llState: uint64(s.litLengths.state.state), - mlState: uint64(s.matchLengths.state.state), - ofState: uint64(s.offsets.state.state), - seqs: seqs, - iteration: len(seqs) - 1, - litRemain: len(s.literals), - } - - if debugDecoder { - println("decode: decoding", len(seqs), "sequences", br.remain(), "bits remain on stream") - } +func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int - s.seqSize = 0 - lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56 - var errCode int +// decodeSyncAsm runs the decodeSync loop, choosing the BMI2 / safe variant. +func decodeSyncAsm(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext, safe bool) int { if cpuinfo.HasBMI2() { - if lte56bits { - errCode = sequenceDecs_decode_56_bmi2(s, br, &ctx) - } else { - errCode = sequenceDecs_decode_bmi2(s, br, &ctx) - } - } else { - if lte56bits { - errCode = sequenceDecs_decode_56_amd64(s, br, &ctx) - } else { - errCode = sequenceDecs_decode_amd64(s, br, &ctx) + if safe { + return sequenceDecs_decodeSync_safe_bmi2(s, br, ctx) } + return sequenceDecs_decodeSync_bmi2(s, br, ctx) } - if errCode != 0 { - i := len(seqs) - ctx.iteration - 1 - switch errCode { - case errorMatchLenOfsMismatch: - ml := ctx.seqs[i].ml - return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) - - case errorMatchLenTooBig: - ml := ctx.seqs[i].ml - return fmt.Errorf("match len (%d) bigger than max allowed length", ml) - - case errorNotEnoughLiterals: - ll := ctx.seqs[i].ll - return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll) - case errorOverread: - return io.ErrUnexpectedEOF - } - - return fmt.Errorf("sequenceDecs_decode_amd64 returned erroneous code %d", errCode) + if safe { + return sequenceDecs_decodeSync_safe_amd64(s, br, ctx) } - - if ctx.litRemain < 0 { - return fmt.Errorf("literal count is too big: total available %d, total requested %d", - len(s.literals), len(s.literals)-ctx.litRemain) - } - - s.seqSize += ctx.litRemain - if s.seqSize > maxBlockSize { - return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) - } - if debugDecoder { - println("decode: ", br.remain(), "bits remain on stream. code:", errCode) - } - err := br.close() - if err != nil { - printf("Closing sequences: %v, %+v\n", err, *br) - } - return err -} - -// -------------------------------------------------------------------------------- - -type executeAsmContext struct { - seqs []seqVals - seqIndex int - out []byte - history []byte - literals []byte - outPosition int - litPosition int - windowSize int + return sequenceDecs_decodeSync_amd64(s, br, ctx) } // sequenceDecs_executeSimple_amd64 implements the main loop of sequenceDecs.executeSimple in x86 asm. @@ -334,54 +96,10 @@ func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool //go:noescape func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool -// executeSimple handles cases when dictionary is not used. -func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error { - // Ensure we have enough output size... - if len(s.out)+s.seqSize+compressedBlockOverAlloc > cap(s.out) { - addBytes := s.seqSize + len(s.out) + compressedBlockOverAlloc - s.out = append(s.out, make([]byte, addBytes)...) - s.out = s.out[:len(s.out)-addBytes] - } - - if debugDecoder { - printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize) - } - - var t = len(s.out) - out := s.out[:t+s.seqSize] - - ctx := executeAsmContext{ - seqs: seqs, - seqIndex: 0, - out: out, - history: hist, - outPosition: t, - litPosition: 0, - literals: s.literals, - windowSize: s.windowSize, +// executeSimpleAsm runs the executeSimple loop, choosing the safe variant. +func executeSimpleAsm(ctx *executeAsmContext, safe bool) bool { + if safe { + return sequenceDecs_executeSimple_safe_amd64(ctx) } - var ok bool - if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { - ok = sequenceDecs_executeSimple_safe_amd64(&ctx) - } else { - ok = sequenceDecs_executeSimple_amd64(&ctx) - } - if !ok { - return fmt.Errorf("match offset (%d) bigger than current history (%d)", - seqs[ctx.seqIndex].mo, ctx.outPosition+len(hist)) - } - s.literals = s.literals[ctx.litPosition:] - t = ctx.outPosition - - // Add final literals - copy(out[t:], s.literals) - if debugDecoder { - t += len(s.literals) - if t != len(out) { - panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize)) - } - } - s.out = out - - return nil + return sequenceDecs_executeSimple_amd64(ctx) } diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index a708ca6d3d9..4d3188ff49b 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -1,4 +1,4 @@ -// Code generated by command: go run gen.go -out ../seqdec_amd64.s -pkg=zstd. DO NOT EDIT. +// Code generated by command: go run gen.go -out ../seqdec.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. //go:build !appengine && !noasm && gc && !noasm @@ -2081,7 +2081,7 @@ sequenceDecs_decodeSync_amd64_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (AX)(R13*1), R14 + LEAQ 16(AX)(R13*1), R14 ADDQ R10, R14 CMPQ R14, 32(SP) JA error_not_enough_space @@ -2601,7 +2601,7 @@ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: MOVQ 16(SP), R13 // Check if we have enough space in s.out - LEAQ (CX)(R13*1), R14 + LEAQ 16(CX)(R13*1), R14 ADDQ R9, R14 CMPQ R14, 32(SP) JA error_not_enough_space diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.go b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.go new file mode 100644 index 00000000000..5ad262acff0 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.go @@ -0,0 +1,70 @@ +//go:build arm64 && !appengine && !noasm && gc + +package zstd + +// The shared decode/decodeSync/executeSimple wrappers and context structs live +// in seqdec_asm.go; this file only declares the arm64 asm routines (generated +// by the avo arm64 lowering printer) and the dispatch helpers. arm64 has no +// BMI2, so each helper selects only between the 56-bit / safe variants. + +// sequenceDecs_decode_arm64 implements the main loop of sequenceDecs in arm64 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decode_arm64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode_56_arm64 implements the main loop of sequenceDecs in arm64 asm. +// +//go:noescape +func sequenceDecs_decode_56_arm64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// decodeAsm runs the sequenceDecs decode loop, choosing the 56-bit variant. +func decodeAsm(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext, lte56bits bool) int { + if lte56bits { + return sequenceDecs_decode_56_arm64(s, br, ctx) + } + return sequenceDecs_decode_arm64(s, br, ctx) +} + +// sequenceDecs_decodeSync_arm64 implements the main loop of sequenceDecs.decodeSync in arm64 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decodeSync_arm64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_safe_arm64 does the same as above, but does not write more than output buffer. +// +//go:noescape +func sequenceDecs_decodeSync_safe_arm64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// decodeSyncAsm runs the decodeSync loop, choosing the safe variant. +func decodeSyncAsm(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext, safe bool) int { + if safe { + return sequenceDecs_decodeSync_safe_arm64(s, br, ctx) + } + return sequenceDecs_decodeSync_arm64(s, br, ctx) +} + +// sequenceDecs_executeSimple_arm64 implements the main loop of sequenceDecs.executeSimple in arm64 asm. +// +// Returns false if a match offset is too big. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_executeSimple_arm64(ctx *executeAsmContext) bool + +// Same as above, but with safe memcopies +// +//go:noescape +func sequenceDecs_executeSimple_safe_arm64(ctx *executeAsmContext) bool + +// executeSimpleAsm runs the executeSimple loop, choosing the safe variant. +func executeSimpleAsm(ctx *executeAsmContext, safe bool) bool { + if safe { + return sequenceDecs_executeSimple_safe_arm64(ctx) + } + return sequenceDecs_executeSimple_arm64(ctx) +} diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s new file mode 100644 index 00000000000..6f54ef21ba1 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s @@ -0,0 +1,2750 @@ +// Code generated by command: go run gen.go -out ../seqdec.s -arch amd64,arm64 -pkg=zstd. DO NOT EDIT. +// EXPERIMENTAL arm64 output lowered from an amd64 avo program. + +//go:build arm64 && !appengine && !noasm && gc && !noasm + +// func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: CMOV +TEXT ·sequenceDecs_decode_arm64(SB), $8-32 + MOVD br+8(FP), R1 + MOVD 24(R1), R2 + MOVBU 40(R1), R3 + MOVD (R1), R0 + MOVD 32(R1), R5 + ADD R5, R0, R0 + MOVD R0, 8(RSP) + MOVD ctx+16(FP), R0 + MOVD 72(R0), R6 + MOVD 80(R0), R7 + MOVD 88(R0), R8 + MOVD 104(R0), R9 + MOVD s+0(FP), R0 + MOVD 144(R0), R10 + MOVD 152(R0), R11 + MOVD 160(R0), R12 + +sequenceDecs_decode_amd64_main_loop: + MOVD 8(RSP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMP $0x08, R5 + BLT sequenceDecs_decode_amd64_fill_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R13, R13 + MOVD (R13), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decode_amd64_fill_end + +sequenceDecs_decode_amd64_fill_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decode_amd64_fill_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decode_amd64_fill_end + LSL $0x08, R2, R2 + SUB $0x01, R13, R13 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R13), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decode_amd64_fill_byte_by_byte + +sequenceDecs_decode_amd64_fill_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decode_amd64_fill_end: + // Update offset + MOVD R8, R0 + MOVD R3, R1 + MOVD R2, R14 + LSL R1, R14, R14 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decode_amd64_of_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decode_amd64_of_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decode_amd64_of_update_zero + NEG R1, R1 + LSR R1, R14, R14 + ADD R14, R0, R0 + +sequenceDecs_decode_amd64_of_update_zero: + MOVD R0, 16(R9) + + // Update match length + MOVD R7, R0 + MOVD R3, R1 + MOVD R2, R14 + LSL R1, R14, R14 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decode_amd64_ml_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decode_amd64_ml_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decode_amd64_ml_update_zero + NEG R1, R1 + LSR R1, R14, R14 + ADD R14, R0, R0 + +sequenceDecs_decode_amd64_ml_update_zero: + MOVD R0, 8(R9) + + // Fill bitreader to have enough for the remaining + CMP $0x08, R5 + BLT sequenceDecs_decode_amd64_fill_2_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R13, R13 + MOVD (R13), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decode_amd64_fill_2_end + +sequenceDecs_decode_amd64_fill_2_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decode_amd64_fill_2_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decode_amd64_fill_2_end + LSL $0x08, R2, R2 + SUB $0x01, R13, R13 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R13), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decode_amd64_fill_2_byte_by_byte + +sequenceDecs_decode_amd64_fill_2_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decode_amd64_fill_2_end: + // Update literal length + MOVD R6, R0 + MOVD R3, R1 + MOVD R2, R14 + LSL R1, R14, R14 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decode_amd64_ll_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decode_amd64_ll_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decode_amd64_ll_update_zero + NEG R1, R1 + LSR R1, R14, R14 + ADD R14, R0, R0 + +sequenceDecs_decode_amd64_ll_update_zero: + MOVD R0, (R9) + + // Fill bitreader for state updates + MOVD R13, 8(RSP) + MOVD R8, R0 + LSR $0x08, R0, R0 + MOVBU R0, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decode_amd64_skip_update + + // Update Literal Length State + MOVBU R6, R13 + LSRW $0x10, R6, R6 + ADD R13, R3, R1 + MOVD R2, R14 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R14, R14 + MOVD $0x00000001, R4 + BFI $0, R13, $8, R1 + LSLW R1, R4, R4 + SUBW $1, R4, R4 + AND R4, R14, R14 + ADD R14, R6, R6 + + // Load ctx.llTable + MOVD ctx+16(FP), R1 + MOVD (R1), R1 + ADD R6<<3, R1, R15 + MOVD (R15), R6 + + // Update Match Length State + MOVBU R7, R13 + LSRW $0x10, R7, R7 + ADD R13, R3, R1 + MOVD R2, R14 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R14, R14 + MOVD $0x00000001, R4 + BFI $0, R13, $8, R1 + LSLW R1, R4, R4 + SUBW $1, R4, R4 + AND R4, R14, R14 + ADD R14, R7, R7 + + // Load ctx.mlTable + MOVD ctx+16(FP), R1 + MOVD 24(R1), R1 + ADD R7<<3, R1, R15 + MOVD (R15), R7 + + // Update Offset State + MOVBU R8, R13 + LSRW $0x10, R8, R8 + ADD R13, R3, R1 + MOVD R2, R14 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R14, R14 + MOVD $0x00000001, R4 + BFI $0, R13, $8, R1 + LSLW R1, R4, R4 + SUBW $1, R4, R4 + AND R4, R14, R14 + ADD R14, R8, R8 + + // Load ctx.ofTable + MOVD ctx+16(FP), R1 + MOVD 48(R1), R1 + ADD R8<<3, R1, R15 + MOVD (R15), R8 + +sequenceDecs_decode_amd64_skip_update: + // Adjust offset + MOVD 16(R9), R1 + CMP $0x01, R0 + BLS sequenceDecs_decode_amd64_adjust_offsetB_1_or_0 + MOVD R11, R12 + MOVD R10, R11 + MOVD R1, R10 + JMP sequenceDecs_decode_amd64_after_adjust + +sequenceDecs_decode_amd64_adjust_offsetB_1_or_0: + MOVD (R9), R16 + CMP $0x00000000, R16 + BNE sequenceDecs_decode_amd64_adjust_offset_maybezero + ADD $1, R1, R1 + JMP sequenceDecs_decode_amd64_adjust_offset_nonzero + +sequenceDecs_decode_amd64_adjust_offset_maybezero: + TST R1, R1 + BNE sequenceDecs_decode_amd64_adjust_offset_nonzero + MOVD R10, R1 + JMP sequenceDecs_decode_amd64_after_adjust + +sequenceDecs_decode_amd64_adjust_offset_nonzero: + CMP $0x01, R1 + BLO sequenceDecs_decode_amd64_adjust_zero + BEQ sequenceDecs_decode_amd64_adjust_one + CMP $0x02, R1 + BHI sequenceDecs_decode_amd64_adjust_three + JMP sequenceDecs_decode_amd64_adjust_two + +sequenceDecs_decode_amd64_adjust_zero: + MOVD R10, R0 + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_one: + MOVD R11, R0 + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_two: + MOVD R12, R0 + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_three: + SUB $1, R10, R0 + +sequenceDecs_decode_amd64_adjust_test_temp_valid: + TST R0, R0 + BNE sequenceDecs_decode_amd64_adjust_temp_valid + MOVD $0x00000001, R0 + +sequenceDecs_decode_amd64_adjust_temp_valid: + CMP $0x01, R1 + CSEL NE, R11, R12, R12 + MOVD R10, R11 + MOVD R0, R10 + MOVD R0, R1 + +sequenceDecs_decode_amd64_after_adjust: + MOVD R1, 16(R9) + + // Check values + MOVD 8(R9), R0 + MOVD (R9), R13 + ADD R13, R0, R14 + MOVD s+0(FP), R4 + MOVD 256(R4), R16 + ADD R14, R16, R16 + MOVD R16, 256(R4) + MOVD ctx+16(FP), R14 + MOVD 128(R14), R16 + SUBS R13, R16, R16 + MOVD R16, 128(R14) + BMI error_not_enough_literals + CMP $0x00020002, R0 + BHI sequenceDecs_decode_amd64_error_match_len_too_big + TST R1, R1 + BNE sequenceDecs_decode_amd64_match_len_ofs_ok + TST R0, R0 + BNE sequenceDecs_decode_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decode_amd64_match_len_ofs_ok: + ADD $0x18, R9, R9 + MOVD ctx+16(FP), R0 + MOVD 96(R0), R16 + SUBS $1, R16, R16 + MOVD R16, 96(R0) + BPL sequenceDecs_decode_amd64_main_loop + MOVD s+0(FP), R0 + MOVD R10, 144(R0) + MOVD R11, 152(R0) + MOVD R12, 160(R0) + MOVD br+8(FP), R0 + MOVD R2, 24(R0) + MOVB R3, 40(R0) + MOVD R5, 32(R0) + + // Return success + MOVD $0x00000000, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_amd64_error_match_len_ofs_mismatch: + MOVD $0x00000001, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_amd64_error_match_len_too_big: + MOVD $0x00000002, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match offset too long error + MOVD $0x00000003, R16 + MOVD R16, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVD $0x00000004, R16 + MOVD R16, ret+24(FP) + RET + + // Return with overread error +error_overread: + MOVD $0x00000006, R16 + MOVD R16, ret+24(FP) + RET + +// func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: CMOV +TEXT ·sequenceDecs_decode_56_arm64(SB), $8-32 + MOVD br+8(FP), R1 + MOVD 24(R1), R2 + MOVBU 40(R1), R3 + MOVD (R1), R0 + MOVD 32(R1), R5 + ADD R5, R0, R0 + MOVD R0, 8(RSP) + MOVD ctx+16(FP), R0 + MOVD 72(R0), R6 + MOVD 80(R0), R7 + MOVD 88(R0), R8 + MOVD 104(R0), R9 + MOVD s+0(FP), R0 + MOVD 144(R0), R10 + MOVD 152(R0), R11 + MOVD 160(R0), R12 + +sequenceDecs_decode_56_amd64_main_loop: + MOVD 8(RSP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMP $0x08, R5 + BLT sequenceDecs_decode_56_amd64_fill_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R13, R13 + MOVD (R13), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decode_56_amd64_fill_end + +sequenceDecs_decode_56_amd64_fill_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decode_56_amd64_fill_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decode_56_amd64_fill_end + LSL $0x08, R2, R2 + SUB $0x01, R13, R13 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R13), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decode_56_amd64_fill_byte_by_byte + +sequenceDecs_decode_56_amd64_fill_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decode_56_amd64_fill_end: + // Update offset + MOVD R8, R0 + MOVD R3, R1 + MOVD R2, R14 + LSL R1, R14, R14 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decode_56_amd64_of_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decode_56_amd64_of_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decode_56_amd64_of_update_zero + NEG R1, R1 + LSR R1, R14, R14 + ADD R14, R0, R0 + +sequenceDecs_decode_56_amd64_of_update_zero: + MOVD R0, 16(R9) + + // Update match length + MOVD R7, R0 + MOVD R3, R1 + MOVD R2, R14 + LSL R1, R14, R14 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decode_56_amd64_ml_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decode_56_amd64_ml_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decode_56_amd64_ml_update_zero + NEG R1, R1 + LSR R1, R14, R14 + ADD R14, R0, R0 + +sequenceDecs_decode_56_amd64_ml_update_zero: + MOVD R0, 8(R9) + + // Update literal length + MOVD R6, R0 + MOVD R3, R1 + MOVD R2, R14 + LSL R1, R14, R14 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decode_56_amd64_ll_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decode_56_amd64_ll_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decode_56_amd64_ll_update_zero + NEG R1, R1 + LSR R1, R14, R14 + ADD R14, R0, R0 + +sequenceDecs_decode_56_amd64_ll_update_zero: + MOVD R0, (R9) + + // Fill bitreader for state updates + MOVD R13, 8(RSP) + MOVD R8, R0 + LSR $0x08, R0, R0 + MOVBU R0, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decode_56_amd64_skip_update + + // Update Literal Length State + MOVBU R6, R13 + LSRW $0x10, R6, R6 + ADD R13, R3, R1 + MOVD R2, R14 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R14, R14 + MOVD $0x00000001, R4 + BFI $0, R13, $8, R1 + LSLW R1, R4, R4 + SUBW $1, R4, R4 + AND R4, R14, R14 + ADD R14, R6, R6 + + // Load ctx.llTable + MOVD ctx+16(FP), R1 + MOVD (R1), R1 + ADD R6<<3, R1, R15 + MOVD (R15), R6 + + // Update Match Length State + MOVBU R7, R13 + LSRW $0x10, R7, R7 + ADD R13, R3, R1 + MOVD R2, R14 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R14, R14 + MOVD $0x00000001, R4 + BFI $0, R13, $8, R1 + LSLW R1, R4, R4 + SUBW $1, R4, R4 + AND R4, R14, R14 + ADD R14, R7, R7 + + // Load ctx.mlTable + MOVD ctx+16(FP), R1 + MOVD 24(R1), R1 + ADD R7<<3, R1, R15 + MOVD (R15), R7 + + // Update Offset State + MOVBU R8, R13 + LSRW $0x10, R8, R8 + ADD R13, R3, R1 + MOVD R2, R14 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R14, R14 + MOVD $0x00000001, R4 + BFI $0, R13, $8, R1 + LSLW R1, R4, R4 + SUBW $1, R4, R4 + AND R4, R14, R14 + ADD R14, R8, R8 + + // Load ctx.ofTable + MOVD ctx+16(FP), R1 + MOVD 48(R1), R1 + ADD R8<<3, R1, R15 + MOVD (R15), R8 + +sequenceDecs_decode_56_amd64_skip_update: + // Adjust offset + MOVD 16(R9), R1 + CMP $0x01, R0 + BLS sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0 + MOVD R11, R12 + MOVD R10, R11 + MOVD R1, R10 + JMP sequenceDecs_decode_56_amd64_after_adjust + +sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0: + MOVD (R9), R16 + CMP $0x00000000, R16 + BNE sequenceDecs_decode_56_amd64_adjust_offset_maybezero + ADD $1, R1, R1 + JMP sequenceDecs_decode_56_amd64_adjust_offset_nonzero + +sequenceDecs_decode_56_amd64_adjust_offset_maybezero: + TST R1, R1 + BNE sequenceDecs_decode_56_amd64_adjust_offset_nonzero + MOVD R10, R1 + JMP sequenceDecs_decode_56_amd64_after_adjust + +sequenceDecs_decode_56_amd64_adjust_offset_nonzero: + CMP $0x01, R1 + BLO sequenceDecs_decode_56_amd64_adjust_zero + BEQ sequenceDecs_decode_56_amd64_adjust_one + CMP $0x02, R1 + BHI sequenceDecs_decode_56_amd64_adjust_three + JMP sequenceDecs_decode_56_amd64_adjust_two + +sequenceDecs_decode_56_amd64_adjust_zero: + MOVD R10, R0 + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_one: + MOVD R11, R0 + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_two: + MOVD R12, R0 + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_three: + SUB $1, R10, R0 + +sequenceDecs_decode_56_amd64_adjust_test_temp_valid: + TST R0, R0 + BNE sequenceDecs_decode_56_amd64_adjust_temp_valid + MOVD $0x00000001, R0 + +sequenceDecs_decode_56_amd64_adjust_temp_valid: + CMP $0x01, R1 + CSEL NE, R11, R12, R12 + MOVD R10, R11 + MOVD R0, R10 + MOVD R0, R1 + +sequenceDecs_decode_56_amd64_after_adjust: + MOVD R1, 16(R9) + + // Check values + MOVD 8(R9), R0 + MOVD (R9), R13 + ADD R13, R0, R14 + MOVD s+0(FP), R4 + MOVD 256(R4), R16 + ADD R14, R16, R16 + MOVD R16, 256(R4) + MOVD ctx+16(FP), R14 + MOVD 128(R14), R16 + SUBS R13, R16, R16 + MOVD R16, 128(R14) + BMI error_not_enough_literals + CMP $0x00020002, R0 + BHI sequenceDecs_decode_56_amd64_error_match_len_too_big + TST R1, R1 + BNE sequenceDecs_decode_56_amd64_match_len_ofs_ok + TST R0, R0 + BNE sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decode_56_amd64_match_len_ofs_ok: + ADD $0x18, R9, R9 + MOVD ctx+16(FP), R0 + MOVD 96(R0), R16 + SUBS $1, R16, R16 + MOVD R16, 96(R0) + BPL sequenceDecs_decode_56_amd64_main_loop + MOVD s+0(FP), R0 + MOVD R10, 144(R0) + MOVD R11, 152(R0) + MOVD R12, 160(R0) + MOVD br+8(FP), R0 + MOVD R2, 24(R0) + MOVB R3, 40(R0) + MOVD R5, 32(R0) + + // Return success + MOVD $0x00000000, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch: + MOVD $0x00000001, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_56_amd64_error_match_len_too_big: + MOVD $0x00000002, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match offset too long error + MOVD $0x00000003, R16 + MOVD R16, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVD $0x00000004, R16 + MOVD R16, ret+24(FP) + RET + + // Return with overread error +error_overread: + MOVD $0x00000006, R16 + MOVD R16, ret+24(FP) + RET + +// skipped sequenceDecs_decode_bmi2 (generic twin preferred on arm64) + +// skipped sequenceDecs_decode_56_bmi2 (generic twin preferred on arm64) + +// func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool +// Requires: SSE +TEXT ·sequenceDecs_executeSimple_arm64(SB), $8-9 + MOVD ctx+0(FP), R9 + MOVD 8(R9), R1 + TST R1, R1 + BEQ empty_seqs + MOVD (R9), R0 + MOVD 24(R9), R2 + MOVD 32(R9), R3 + MOVD 80(R9), R5 + MOVD 104(R9), R6 + MOVD 120(R9), R7 + MOVD 56(R9), R8 + MOVD 64(R9), R9 + ADD R9, R8, R8 + + // seqsBase += 24 * seqIndex + ADD R2<<1, R2, R10 + LSL $0x03, R10, R10 + ADD R10, R0, R0 + + // outBase += outPosition + ADD R6, R3, R3 + +main_loop: + MOVD (R0), R10 + MOVD 16(R0), R11 + MOVD 8(R0), R12 + + // Copy literals + TST R10, R10 + BEQ check_offset + MOVD $0, R13 + +copy_1: + ADD R13, R5, R15 + VLD1 (R15), [V0.B16] + ADD R13, R3, R15 + VST1 [V0.B16], (R15) + ADD $0x10, R13, R13 + CMP R10, R13 + BLO copy_1 + ADD R10, R5, R5 + ADD R10, R3, R3 + ADD R10, R6, R6 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + ADD R9, R6, R10 + CMP R10, R11 + BGT error_match_off_too_big + CMP R7, R11 + BGT error_match_off_too_big + + // Copy match from history + MOVD R11, R10 + SUBS R6, R10, R10 + BLS copy_match + MOVD R8, R13 + SUB R10, R13, R13 + CMP R10, R12 + BGT copy_all_from_history + MOVD R12, R10 + SUBS $0x10, R10, R10 + BLO copy_4_small + +copy_4_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R10, R10 + BHS copy_4_loop + ADD R10, R13, R13 + ADD $16, R13, R13 + ADD R10, R3, R3 + ADD $16, R3, R3 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R3, R15 + VST1 [V0.B16], (R15) + JMP copy_4_end + +copy_4_small: + CMP $0x03, R12 + BEQ copy_4_move_3 + CMP $0x08, R12 + BLO copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end + +copy_4_move_4through7: + MOVWU (R13), R10 + ADD R12, R13, R15 + MOVWU -4(R15), R11 + MOVW R10, (R3) + ADD R12, R3, R15 + MOVW R11, -4(R15) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end + +copy_4_move_8through16: + MOVD (R13), R10 + ADD R12, R13, R15 + MOVD -8(R15), R11 + MOVD R10, (R3) + ADD R12, R3, R15 + MOVD R11, -8(R15) + ADD R12, R13, R13 + ADD R12, R3, R3 + +copy_4_end: + ADD R12, R6, R6 + ADD $0x18, R0, R0 + ADD $1, R2, R2 + CMP R1, R2 + BLO main_loop + JMP loop_finished + +copy_all_from_history: + MOVD R10, R14 + SUBS $0x10, R14, R14 + BLO copy_5_small + +copy_5_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R3, R3 + ADD $16, R3, R3 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R3, R15 + VST1 [V0.B16], (R15) + JMP copy_5_end + +copy_5_small: + CMP $0x03, R10 + BEQ copy_5_move_3 + BLO copy_5_move_1or2 + CMP $0x08, R10 + BLO copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end + +copy_5_move_3: + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end + +copy_5_move_4through7: + MOVWU (R13), R14 + ADD R10, R13, R15 + MOVWU -4(R15), R4 + MOVW R14, (R3) + ADD R10, R3, R15 + MOVW R4, -4(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end + +copy_5_move_8through16: + MOVD (R13), R14 + ADD R10, R13, R15 + MOVD -8(R15), R4 + MOVD R14, (R3) + ADD R10, R3, R15 + MOVD R4, -8(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + +copy_5_end: + ADD R10, R6, R6 + SUB R10, R12, R12 + + // Copy match from the current buffer +copy_match: + MOVD R3, R10 + SUB R11, R10, R10 + + // ml <= mo + CMP R11, R12 + BHI copy_overlapping_match + + // Copy non-overlapping match + ADD R12, R6, R6 + MOVD R3, R11 + ADD R12, R3, R3 + +copy_2: + VLD1 (R10), [V0.B16] + VST1 [V0.B16], (R11) + ADD $0x10, R10, R10 + ADD $0x10, R11, R11 + SUBS $0x10, R12, R12 + BHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADD R12, R6, R6 + +copy_slow_3: + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 + +handle_loop: + ADD $0x18, R0, R0 + ADD $1, R2, R2 + CMP R1, R2 + BLO main_loop + +loop_finished: + // Return value + MOVD $0x01, R16 + MOVB R16, ret+8(FP) + + // Update the context + MOVD ctx+0(FP), R0 + MOVD R2, 24(R0) + MOVD R6, 104(R0) + MOVD 80(R0), R16 + SUB R16, R5, R5 + MOVD R5, 112(R0) + RET + +error_match_off_too_big: + // Return value + MOVD $0x00, R16 + MOVB R16, ret+8(FP) + + // Update the context + MOVD ctx+0(FP), R0 + MOVD R2, 24(R0) + MOVD R6, 104(R0) + MOVD 80(R0), R16 + SUB R16, R5, R5 + MOVD R5, 112(R0) + RET + +empty_seqs: + // Return value + MOVD $0x01, R16 + MOVB R16, ret+8(FP) + RET + +// func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool +// Requires: SSE +TEXT ·sequenceDecs_executeSimple_safe_arm64(SB), $8-9 + MOVD ctx+0(FP), R9 + MOVD 8(R9), R1 + TST R1, R1 + BEQ empty_seqs + MOVD (R9), R0 + MOVD 24(R9), R2 + MOVD 32(R9), R3 + MOVD 80(R9), R5 + MOVD 104(R9), R6 + MOVD 120(R9), R7 + MOVD 56(R9), R8 + MOVD 64(R9), R9 + ADD R9, R8, R8 + + // seqsBase += 24 * seqIndex + ADD R2<<1, R2, R10 + LSL $0x03, R10, R10 + ADD R10, R0, R0 + + // outBase += outPosition + ADD R6, R3, R3 + +main_loop: + MOVD (R0), R10 + MOVD 16(R0), R11 + MOVD 8(R0), R12 + + // Copy literals + TST R10, R10 + BEQ check_offset + MOVD R10, R13 + SUBS $0x10, R13, R13 + BLO copy_1_small + +copy_1_loop: + VLD1 (R5), [V0.B16] + VST1 [V0.B16], (R3) + ADD $0x10, R5, R5 + ADD $0x10, R3, R3 + SUBS $0x10, R13, R13 + BHS copy_1_loop + ADD R13, R5, R5 + ADD $16, R5, R5 + ADD R13, R3, R3 + ADD $16, R3, R3 + ADD $-16, R5, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R3, R15 + VST1 [V0.B16], (R15) + JMP copy_1_end + +copy_1_small: + CMP $0x03, R10 + BEQ copy_1_move_3 + BLO copy_1_move_1or2 + CMP $0x08, R10 + BLO copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVBU (R5), R16 + BFI $0, R16, $8, R13 + ADD R10, R5, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R3) + ADD R10, R3, R15 + MOVB R14, -1(R15) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end + +copy_1_move_3: + MOVHU (R5), R13 + MOVBU 2(R5), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R3) + MOVB R14, 2(R3) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end + +copy_1_move_4through7: + MOVWU (R5), R13 + ADD R10, R5, R15 + MOVWU -4(R15), R14 + MOVW R13, (R3) + ADD R10, R3, R15 + MOVW R14, -4(R15) + ADD R10, R5, R5 + ADD R10, R3, R3 + JMP copy_1_end + +copy_1_move_8through16: + MOVD (R5), R13 + ADD R10, R5, R15 + MOVD -8(R15), R14 + MOVD R13, (R3) + ADD R10, R3, R15 + MOVD R14, -8(R15) + ADD R10, R5, R5 + ADD R10, R3, R3 + +copy_1_end: + ADD R10, R6, R6 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + ADD R9, R6, R10 + CMP R10, R11 + BGT error_match_off_too_big + CMP R7, R11 + BGT error_match_off_too_big + + // Copy match from history + MOVD R11, R10 + SUBS R6, R10, R10 + BLS copy_match + MOVD R8, R13 + SUB R10, R13, R13 + CMP R10, R12 + BGT copy_all_from_history + MOVD R12, R10 + SUBS $0x10, R10, R10 + BLO copy_4_small + +copy_4_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R10, R10 + BHS copy_4_loop + ADD R10, R13, R13 + ADD $16, R13, R13 + ADD R10, R3, R3 + ADD $16, R3, R3 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R3, R15 + VST1 [V0.B16], (R15) + JMP copy_4_end + +copy_4_small: + CMP $0x03, R12 + BEQ copy_4_move_3 + CMP $0x08, R12 + BLO copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVHU (R13), R10 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R11 + MOVH R10, (R3) + MOVB R11, 2(R3) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end + +copy_4_move_4through7: + MOVWU (R13), R10 + ADD R12, R13, R15 + MOVWU -4(R15), R11 + MOVW R10, (R3) + ADD R12, R3, R15 + MOVW R11, -4(R15) + ADD R12, R13, R13 + ADD R12, R3, R3 + JMP copy_4_end + +copy_4_move_8through16: + MOVD (R13), R10 + ADD R12, R13, R15 + MOVD -8(R15), R11 + MOVD R10, (R3) + ADD R12, R3, R15 + MOVD R11, -8(R15) + ADD R12, R13, R13 + ADD R12, R3, R3 + +copy_4_end: + ADD R12, R6, R6 + ADD $0x18, R0, R0 + ADD $1, R2, R2 + CMP R1, R2 + BLO main_loop + JMP loop_finished + +copy_all_from_history: + MOVD R10, R14 + SUBS $0x10, R14, R14 + BLO copy_5_small + +copy_5_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R3) + ADD $0x10, R13, R13 + ADD $0x10, R3, R3 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R3, R3 + ADD $16, R3, R3 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R3, R15 + VST1 [V0.B16], (R15) + JMP copy_5_end + +copy_5_small: + CMP $0x03, R10 + BEQ copy_5_move_3 + BLO copy_5_move_1or2 + CMP $0x08, R10 + BLO copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R10, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R3) + ADD R10, R3, R15 + MOVB R4, -1(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end + +copy_5_move_3: + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R3) + MOVB R4, 2(R3) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end + +copy_5_move_4through7: + MOVWU (R13), R14 + ADD R10, R13, R15 + MOVWU -4(R15), R4 + MOVW R14, (R3) + ADD R10, R3, R15 + MOVW R4, -4(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + JMP copy_5_end + +copy_5_move_8through16: + MOVD (R13), R14 + ADD R10, R13, R15 + MOVD -8(R15), R4 + MOVD R14, (R3) + ADD R10, R3, R15 + MOVD R4, -8(R15) + ADD R10, R13, R13 + ADD R10, R3, R3 + +copy_5_end: + ADD R10, R6, R6 + SUB R10, R12, R12 + + // Copy match from the current buffer +copy_match: + MOVD R3, R10 + SUB R11, R10, R10 + + // ml <= mo + CMP R11, R12 + BHI copy_overlapping_match + + // Copy non-overlapping match + ADD R12, R6, R6 + MOVD R12, R11 + SUBS $0x10, R11, R11 + BLO copy_2_small + +copy_2_loop: + VLD1 (R10), [V0.B16] + VST1 [V0.B16], (R3) + ADD $0x10, R10, R10 + ADD $0x10, R3, R3 + SUBS $0x10, R11, R11 + BHS copy_2_loop + ADD R11, R10, R10 + ADD $16, R10, R10 + ADD R11, R3, R3 + ADD $16, R3, R3 + ADD $-16, R10, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R3, R15 + VST1 [V0.B16], (R15) + JMP copy_2_end + +copy_2_small: + CMP $0x03, R12 + BEQ copy_2_move_3 + BLO copy_2_move_1or2 + CMP $0x08, R12 + BLO copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + ADD R12, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R11, (R3) + ADD R12, R3, R15 + MOVB R13, -1(R15) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end + +copy_2_move_3: + MOVHU (R10), R11 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R13 + MOVH R11, (R3) + MOVB R13, 2(R3) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end + +copy_2_move_4through7: + MOVWU (R10), R11 + ADD R12, R10, R15 + MOVWU -4(R15), R13 + MOVW R11, (R3) + ADD R12, R3, R15 + MOVW R13, -4(R15) + ADD R12, R10, R10 + ADD R12, R3, R3 + JMP copy_2_end + +copy_2_move_8through16: + MOVD (R10), R11 + ADD R12, R10, R15 + MOVD -8(R15), R13 + MOVD R11, (R3) + ADD R12, R3, R15 + MOVD R13, -8(R15) + ADD R12, R10, R10 + ADD R12, R3, R3 + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADD R12, R6, R6 + +copy_slow_3: + MOVBU (R10), R16 + BFI $0, R16, $8, R11 + MOVB R11, (R3) + ADD $1, R10, R10 + ADD $1, R3, R3 + SUBS $1, R12, R12 + BNE copy_slow_3 + +handle_loop: + ADD $0x18, R0, R0 + ADD $1, R2, R2 + CMP R1, R2 + BLO main_loop + +loop_finished: + // Return value + MOVD $0x01, R16 + MOVB R16, ret+8(FP) + + // Update the context + MOVD ctx+0(FP), R0 + MOVD R2, 24(R0) + MOVD R6, 104(R0) + MOVD 80(R0), R16 + SUB R16, R5, R5 + MOVD R5, 112(R0) + RET + +error_match_off_too_big: + // Return value + MOVD $0x00, R16 + MOVB R16, ret+8(FP) + + // Update the context + MOVD ctx+0(FP), R0 + MOVD R2, 24(R0) + MOVD R6, 104(R0) + MOVD 80(R0), R16 + SUB R16, R5, R5 + MOVD R5, 112(R0) + RET + +empty_seqs: + // Return value + MOVD $0x01, R16 + MOVB R16, ret+8(FP) + RET + +// func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: CMOV, SSE +TEXT ·sequenceDecs_decodeSync_arm64(SB), $64-32 + MOVD br+8(FP), R1 + MOVD 24(R1), R2 + MOVBU 40(R1), R3 + MOVD (R1), R0 + MOVD 32(R1), R5 + ADD R5, R0, R0 + MOVD R0, 8(RSP) + MOVD ctx+16(FP), R0 + MOVD 72(R0), R6 + MOVD 80(R0), R7 + MOVD 88(R0), R8 + MOVD $0, R1 + MOVD R1, 16(RSP) + MOVD R1, 24(RSP) + MOVD R1, 32(RSP) + MOVD 112(R0), R9 + MOVD 128(R0), R1 + MOVD R1, 40(RSP) + MOVD 144(R0), R10 + MOVD 136(R0), R11 + MOVD 200(R0), R1 + MOVD R1, 64(RSP) + MOVD 176(R0), R1 + MOVD R1, 56(RSP) + MOVD 184(R0), R0 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 + ADD R0, R16, R16 + MOVD R16, 56(RSP) + + // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) + MOVD 40(RSP), R16 + ADD R9, R16, R16 + MOVD R16, 40(RSP) + + // outBase += outPosition + ADD R11, R9, R9 + +sequenceDecs_decodeSync_amd64_main_loop: + MOVD 8(RSP), R12 + + // Fill bitreader to have enough for the offset and match length. + CMP $0x08, R5 + BLT sequenceDecs_decodeSync_amd64_fill_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R12, R12 + MOVD (R12), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decodeSync_amd64_fill_end + +sequenceDecs_decodeSync_amd64_fill_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decodeSync_amd64_fill_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decodeSync_amd64_fill_end + LSL $0x08, R2, R2 + SUB $0x01, R12, R12 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R12), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decodeSync_amd64_fill_byte_by_byte + +sequenceDecs_decodeSync_amd64_fill_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decodeSync_amd64_fill_end: + // Update offset + MOVD R8, R0 + MOVD R3, R1 + MOVD R2, R13 + LSL R1, R13, R13 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decodeSync_amd64_of_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decodeSync_amd64_of_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decodeSync_amd64_of_update_zero + NEG R1, R1 + LSR R1, R13, R13 + ADD R13, R0, R0 + +sequenceDecs_decodeSync_amd64_of_update_zero: + MOVD R0, 16(RSP) + + // Update match length + MOVD R7, R0 + MOVD R3, R1 + MOVD R2, R13 + LSL R1, R13, R13 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decodeSync_amd64_ml_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decodeSync_amd64_ml_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decodeSync_amd64_ml_update_zero + NEG R1, R1 + LSR R1, R13, R13 + ADD R13, R0, R0 + +sequenceDecs_decodeSync_amd64_ml_update_zero: + MOVD R0, 24(RSP) + + // Fill bitreader to have enough for the remaining + CMP $0x08, R5 + BLT sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R12, R12 + MOVD (R12), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decodeSync_amd64_fill_2_end + +sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decodeSync_amd64_fill_2_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decodeSync_amd64_fill_2_end + LSL $0x08, R2, R2 + SUB $0x01, R12, R12 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R12), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte + +sequenceDecs_decodeSync_amd64_fill_2_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decodeSync_amd64_fill_2_end: + // Update literal length + MOVD R6, R0 + MOVD R3, R1 + MOVD R2, R13 + LSL R1, R13, R13 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decodeSync_amd64_ll_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decodeSync_amd64_ll_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decodeSync_amd64_ll_update_zero + NEG R1, R1 + LSR R1, R13, R13 + ADD R13, R0, R0 + +sequenceDecs_decodeSync_amd64_ll_update_zero: + MOVD R0, 32(RSP) + + // Fill bitreader for state updates + MOVD R12, 8(RSP) + MOVD R8, R0 + LSR $0x08, R0, R0 + MOVBU R0, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decodeSync_amd64_skip_update + + // Update Literal Length State + MOVBU R6, R12 + LSRW $0x10, R6, R6 + ADD R12, R3, R1 + MOVD R2, R13 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R13, R13 + MOVD $0x00000001, R14 + BFI $0, R12, $8, R1 + LSLW R1, R14, R14 + SUBW $1, R14, R14 + AND R14, R13, R13 + ADD R13, R6, R6 + + // Load ctx.llTable + MOVD ctx+16(FP), R1 + MOVD (R1), R1 + ADD R6<<3, R1, R15 + MOVD (R15), R6 + + // Update Match Length State + MOVBU R7, R12 + LSRW $0x10, R7, R7 + ADD R12, R3, R1 + MOVD R2, R13 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R13, R13 + MOVD $0x00000001, R14 + BFI $0, R12, $8, R1 + LSLW R1, R14, R14 + SUBW $1, R14, R14 + AND R14, R13, R13 + ADD R13, R7, R7 + + // Load ctx.mlTable + MOVD ctx+16(FP), R1 + MOVD 24(R1), R1 + ADD R7<<3, R1, R15 + MOVD (R15), R7 + + // Update Offset State + MOVBU R8, R12 + LSRW $0x10, R8, R8 + ADD R12, R3, R1 + MOVD R2, R13 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R13, R13 + MOVD $0x00000001, R14 + BFI $0, R12, $8, R1 + LSLW R1, R14, R14 + SUBW $1, R14, R14 + AND R14, R13, R13 + ADD R13, R8, R8 + + // Load ctx.ofTable + MOVD ctx+16(FP), R1 + MOVD 48(R1), R1 + ADD R8<<3, R1, R15 + MOVD (R15), R8 + +sequenceDecs_decodeSync_amd64_skip_update: + // Adjust offset + MOVD s+0(FP), R1 + MOVD 16(RSP), R12 + CMP $0x01, R0 + BLS sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 + ADD $144, R1, R15 + VLD1 (R15), [V0.B16] + MOVD R12, 144(R1) + ADD $152, R1, R15 + VST1 [V0.B16], (R15) + JMP sequenceDecs_decodeSync_amd64_after_adjust + +sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: + MOVD 32(RSP), R16 + CMP $0x00000000, R16 + BNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero + ADD $1, R12, R12 + JMP sequenceDecs_decodeSync_amd64_adjust_offset_nonzero + +sequenceDecs_decodeSync_amd64_adjust_offset_maybezero: + TST R12, R12 + BNE sequenceDecs_decodeSync_amd64_adjust_offset_nonzero + MOVD 144(R1), R12 + JMP sequenceDecs_decodeSync_amd64_after_adjust + +sequenceDecs_decodeSync_amd64_adjust_offset_nonzero: + MOVD R12, R0 + MOVD $0, R13 + MOVD $-1, R14 + CMP $0x03, R12 + CSEL EQ, R13, R0, R0 + CSEL EQ, R14, R13, R13 + ADD R0<<3, R1, R15 + MOVD 144(R15), R16 + ADDS R16, R13, R13 + BNE sequenceDecs_decodeSync_amd64_adjust_temp_valid + MOVD $0x00000001, R13 + +sequenceDecs_decodeSync_amd64_adjust_temp_valid: + CMP $0x01, R12 + BEQ sequenceDecs_decodeSync_amd64_adjust_skip + MOVD 152(R1), R0 + MOVD R0, 160(R1) + +sequenceDecs_decodeSync_amd64_adjust_skip: + MOVD 144(R1), R0 + MOVD R0, 152(R1) + MOVD R13, 144(R1) + MOVD R13, R12 + +sequenceDecs_decodeSync_amd64_after_adjust: + MOVD R12, 16(RSP) + + // Check values + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 + ADD R1, R0, R13 + MOVD s+0(FP), R14 + MOVD 256(R14), R16 + ADD R13, R16, R16 + MOVD R16, 256(R14) + MOVD ctx+16(FP), R13 + MOVD 104(R13), R16 + SUBS R1, R16, R16 + MOVD R16, 104(R13) + BMI error_not_enough_literals + CMP $0x00020002, R0 + BHI sequenceDecs_decodeSync_amd64_error_match_len_too_big + TST R12, R12 + BNE sequenceDecs_decodeSync_amd64_match_len_ofs_ok + TST R0, R0 + BNE sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_amd64_match_len_ofs_ok: + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 + + // Check if we have enough space in s.out + ADD R12, R0, R13 + ADD $16, R13, R13 + ADD R9, R13, R13 + MOVD 40(RSP), R16 + CMP R16, R13 + BHI error_not_enough_space + + // Copy literals + TST R0, R0 + BEQ check_offset + MOVD $0, R13 + +copy_1: + ADD R13, R10, R15 + VLD1 (R15), [V0.B16] + ADD R13, R9, R15 + VST1 [V0.B16], (R15) + ADD $0x10, R13, R13 + CMP R0, R13 + BLO copy_1 + ADD R0, R10, R10 + ADD R0, R9, R9 + ADD R0, R11, R11 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVD R11, R0 + MOVD 48(RSP), R16 + ADD R16, R0, R0 + CMP R0, R1 + BGT error_match_off_too_big + MOVD 64(RSP), R16 + CMP R16, R1 + BGT error_match_off_too_big + + // Copy match from history + MOVD R1, R0 + SUBS R11, R0, R0 + BLS copy_match + MOVD 56(RSP), R13 + SUB R0, R13, R13 + CMP R0, R12 + BGT copy_all_from_history + MOVD R12, R0 + SUBS $0x10, R0, R0 + BLO copy_4_small + +copy_4_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R0, R0 + BHS copy_4_loop + ADD R0, R13, R13 + ADD $16, R13, R13 + ADD R0, R9, R9 + ADD $16, R9, R9 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R9, R15 + VST1 [V0.B16], (R15) + JMP copy_4_end + +copy_4_small: + CMP $0x03, R12 + BEQ copy_4_move_3 + CMP $0x08, R12 + BLO copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end + +copy_4_move_4through7: + MOVWU (R13), R0 + ADD R12, R13, R15 + MOVWU -4(R15), R1 + MOVW R0, (R9) + ADD R12, R9, R15 + MOVW R1, -4(R15) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end + +copy_4_move_8through16: + MOVD (R13), R0 + ADD R12, R13, R15 + MOVD -8(R15), R1 + MOVD R0, (R9) + ADD R12, R9, R15 + MOVD R1, -8(R15) + ADD R12, R13, R13 + ADD R12, R9, R9 + +copy_4_end: + ADD R12, R11, R11 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVD R0, R14 + SUBS $0x10, R14, R14 + BLO copy_5_small + +copy_5_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R9, R9 + ADD $16, R9, R9 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R9, R15 + VST1 [V0.B16], (R15) + JMP copy_5_end + +copy_5_small: + CMP $0x03, R0 + BEQ copy_5_move_3 + BLO copy_5_move_1or2 + CMP $0x08, R0 + BLO copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end + +copy_5_move_3: + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end + +copy_5_move_4through7: + MOVWU (R13), R14 + ADD R0, R13, R15 + MOVWU -4(R15), R4 + MOVW R14, (R9) + ADD R0, R9, R15 + MOVW R4, -4(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end + +copy_5_move_8through16: + MOVD (R13), R14 + ADD R0, R13, R15 + MOVD -8(R15), R4 + MOVD R14, (R9) + ADD R0, R9, R15 + MOVD R4, -8(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + +copy_5_end: + ADD R0, R11, R11 + SUB R0, R12, R12 + + // Copy match from the current buffer +copy_match: + MOVD R9, R0 + SUB R1, R0, R0 + + // ml <= mo + CMP R1, R12 + BHI copy_overlapping_match + + // Copy non-overlapping match + ADD R12, R11, R11 + MOVD R9, R1 + ADD R12, R9, R9 + +copy_2: + VLD1 (R0), [V0.B16] + VST1 [V0.B16], (R1) + ADD $0x10, R0, R0 + ADD $0x10, R1, R1 + SUBS $0x10, R12, R12 + BHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADD R12, R11, R11 + +copy_slow_3: + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 + +handle_loop: + MOVD ctx+16(FP), R0 + MOVD 96(R0), R16 + SUBS $1, R16, R16 + MOVD R16, 96(R0) + BPL sequenceDecs_decodeSync_amd64_main_loop + +loop_finished: + MOVD br+8(FP), R0 + MOVD R2, 24(R0) + MOVB R3, 40(R0) + MOVD R5, 32(R0) + + // Update the context + MOVD ctx+16(FP), R0 + MOVD R11, 136(R0) + MOVD 144(R0), R1 + SUB R1, R10, R10 + MOVD R10, 168(R0) + + // Return success + MOVD $0x00000000, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: + MOVD 24(RSP), R0 + MOVD ctx+16(FP), R1 + MOVD R0, 216(R1) + MOVD $0x00000001, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_amd64_error_match_len_too_big: + MOVD ctx+16(FP), R0 + MOVD 24(RSP), R1 + MOVD R1, 216(R0) + MOVD $0x00000002, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVD ctx+16(FP), R0 + MOVD 16(RSP), R1 + MOVD R1, 224(R0) + MOVD R11, 136(R0) + MOVD $0x00000003, R16 + MOVD R16, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVD ctx+16(FP), R0 + MOVD 32(RSP), R1 + MOVD R1, 208(R0) + MOVD $0x00000004, R16 + MOVD R16, ret+24(FP) + RET + + // Return with overread error +error_overread: + MOVD $0x00000006, R16 + MOVD R16, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVD ctx+16(FP), R0 + MOVD 32(RSP), R1 + MOVD R1, 208(R0) + MOVD 24(RSP), R1 + MOVD R1, 216(R0) + MOVD R11, 136(R0) + MOVD $0x00000005, R16 + MOVD R16, ret+24(FP) + RET + +// skipped sequenceDecs_decodeSync_bmi2 (generic twin preferred on arm64) + +// func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: CMOV, SSE +TEXT ·sequenceDecs_decodeSync_safe_arm64(SB), $64-32 + MOVD br+8(FP), R1 + MOVD 24(R1), R2 + MOVBU 40(R1), R3 + MOVD (R1), R0 + MOVD 32(R1), R5 + ADD R5, R0, R0 + MOVD R0, 8(RSP) + MOVD ctx+16(FP), R0 + MOVD 72(R0), R6 + MOVD 80(R0), R7 + MOVD 88(R0), R8 + MOVD $0, R1 + MOVD R1, 16(RSP) + MOVD R1, 24(RSP) + MOVD R1, 32(RSP) + MOVD 112(R0), R9 + MOVD 128(R0), R1 + MOVD R1, 40(RSP) + MOVD 144(R0), R10 + MOVD 136(R0), R11 + MOVD 200(R0), R1 + MOVD R1, 64(RSP) + MOVD 176(R0), R1 + MOVD R1, 56(RSP) + MOVD 184(R0), R0 + MOVD R0, 48(RSP) + MOVD 48(RSP), R0 + MOVD 56(RSP), R16 + ADD R0, R16, R16 + MOVD R16, 56(RSP) + + // Calculate pointer to s.out[cap(s.out)] (a past-end pointer) + MOVD 40(RSP), R16 + ADD R9, R16, R16 + MOVD R16, 40(RSP) + + // outBase += outPosition + ADD R11, R9, R9 + +sequenceDecs_decodeSync_safe_amd64_main_loop: + MOVD 8(RSP), R12 + + // Fill bitreader to have enough for the offset and match length. + CMP $0x08, R5 + BLT sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R12, R12 + MOVD (R12), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decodeSync_safe_amd64_fill_end + +sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decodeSync_safe_amd64_fill_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decodeSync_safe_amd64_fill_end + LSL $0x08, R2, R2 + SUB $0x01, R12, R12 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R12), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte + +sequenceDecs_decodeSync_safe_amd64_fill_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decodeSync_safe_amd64_fill_end: + // Update offset + MOVD R8, R0 + MOVD R3, R1 + MOVD R2, R13 + LSL R1, R13, R13 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decodeSync_safe_amd64_of_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decodeSync_safe_amd64_of_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decodeSync_safe_amd64_of_update_zero + NEG R1, R1 + LSR R1, R13, R13 + ADD R13, R0, R0 + +sequenceDecs_decodeSync_safe_amd64_of_update_zero: + MOVD R0, 16(RSP) + + // Update match length + MOVD R7, R0 + MOVD R3, R1 + MOVD R2, R13 + LSL R1, R13, R13 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decodeSync_safe_amd64_ml_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decodeSync_safe_amd64_ml_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decodeSync_safe_amd64_ml_update_zero + NEG R1, R1 + LSR R1, R13, R13 + ADD R13, R0, R0 + +sequenceDecs_decodeSync_safe_amd64_ml_update_zero: + MOVD R0, 24(RSP) + + // Fill bitreader to have enough for the remaining + CMP $0x08, R5 + BLT sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte + MOVD R3, R0 + LSR $0x03, R0, R0 + SUB R0, R12, R12 + MOVD (R12), R2 + SUB R0, R5, R5 + AND $0x07, R3, R3 + JMP sequenceDecs_decodeSync_safe_amd64_fill_2_end + +sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte: + CMP $0x00, R5 + BLE sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread + CMP $0x07, R3 + BLE sequenceDecs_decodeSync_safe_amd64_fill_2_end + LSL $0x08, R2, R2 + SUB $0x01, R12, R12 + SUB $0x01, R5, R5 + SUB $0x08, R3, R3 + MOVBU (R12), R0 + ORR R0, R2, R2 + JMP sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte + +sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread: + CMP $0x40, R3 + BHI error_overread + +sequenceDecs_decodeSync_safe_amd64_fill_2_end: + // Update literal length + MOVD R6, R0 + MOVD R3, R1 + MOVD R2, R13 + LSL R1, R13, R13 + UBFX $8, R0, $8, R16 + BFI $0, R16, $8, R1 + LSR $0x20, R0, R0 + TST R1, R1 + BEQ sequenceDecs_decodeSync_safe_amd64_ll_update_zero + ADD R1, R3, R3 + CMP $0x40, R3 + BHI sequenceDecs_decodeSync_safe_amd64_ll_update_zero + CMP $0x40, R1 + BHS sequenceDecs_decodeSync_safe_amd64_ll_update_zero + NEG R1, R1 + LSR R1, R13, R13 + ADD R13, R0, R0 + +sequenceDecs_decodeSync_safe_amd64_ll_update_zero: + MOVD R0, 32(RSP) + + // Fill bitreader for state updates + MOVD R12, 8(RSP) + MOVD R8, R0 + LSR $0x08, R0, R0 + MOVBU R0, R0 + MOVD ctx+16(FP), R1 + MOVD 96(R1), R16 + CMP $0x00, R16 + BEQ sequenceDecs_decodeSync_safe_amd64_skip_update + + // Update Literal Length State + MOVBU R6, R12 + LSRW $0x10, R6, R6 + ADD R12, R3, R1 + MOVD R2, R13 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R13, R13 + MOVD $0x00000001, R14 + BFI $0, R12, $8, R1 + LSLW R1, R14, R14 + SUBW $1, R14, R14 + AND R14, R13, R13 + ADD R13, R6, R6 + + // Load ctx.llTable + MOVD ctx+16(FP), R1 + MOVD (R1), R1 + ADD R6<<3, R1, R15 + MOVD (R15), R6 + + // Update Match Length State + MOVBU R7, R12 + LSRW $0x10, R7, R7 + ADD R12, R3, R1 + MOVD R2, R13 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R13, R13 + MOVD $0x00000001, R14 + BFI $0, R12, $8, R1 + LSLW R1, R14, R14 + SUBW $1, R14, R14 + AND R14, R13, R13 + ADD R13, R7, R7 + + // Load ctx.mlTable + MOVD ctx+16(FP), R1 + MOVD 24(R1), R1 + ADD R7<<3, R1, R15 + MOVD (R15), R7 + + // Update Offset State + MOVBU R8, R12 + LSRW $0x10, R8, R8 + ADD R12, R3, R1 + MOVD R2, R13 + MOVD R1, R3 + NEG R1, R16 + ROR R16, R13, R13 + MOVD $0x00000001, R14 + BFI $0, R12, $8, R1 + LSLW R1, R14, R14 + SUBW $1, R14, R14 + AND R14, R13, R13 + ADD R13, R8, R8 + + // Load ctx.ofTable + MOVD ctx+16(FP), R1 + MOVD 48(R1), R1 + ADD R8<<3, R1, R15 + MOVD (R15), R8 + +sequenceDecs_decodeSync_safe_amd64_skip_update: + // Adjust offset + MOVD s+0(FP), R1 + MOVD 16(RSP), R12 + CMP $0x01, R0 + BLS sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 + ADD $144, R1, R15 + VLD1 (R15), [V0.B16] + MOVD R12, 144(R1) + ADD $152, R1, R15 + VST1 [V0.B16], (R15) + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + +sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: + MOVD 32(RSP), R16 + CMP $0x00000000, R16 + BNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero + ADD $1, R12, R12 + JMP sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero + +sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero: + TST R12, R12 + BNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero + MOVD 144(R1), R12 + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + +sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero: + MOVD R12, R0 + MOVD $0, R13 + MOVD $-1, R14 + CMP $0x03, R12 + CSEL EQ, R13, R0, R0 + CSEL EQ, R14, R13, R13 + ADD R0<<3, R1, R15 + MOVD 144(R15), R16 + ADDS R16, R13, R13 + BNE sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid + MOVD $0x00000001, R13 + +sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid: + CMP $0x01, R12 + BEQ sequenceDecs_decodeSync_safe_amd64_adjust_skip + MOVD 152(R1), R0 + MOVD R0, 160(R1) + +sequenceDecs_decodeSync_safe_amd64_adjust_skip: + MOVD 144(R1), R0 + MOVD R0, 152(R1) + MOVD R13, 144(R1) + MOVD R13, R12 + +sequenceDecs_decodeSync_safe_amd64_after_adjust: + MOVD R12, 16(RSP) + + // Check values + MOVD 24(RSP), R0 + MOVD 32(RSP), R1 + ADD R1, R0, R13 + MOVD s+0(FP), R14 + MOVD 256(R14), R16 + ADD R13, R16, R16 + MOVD R16, 256(R14) + MOVD ctx+16(FP), R13 + MOVD 104(R13), R16 + SUBS R1, R16, R16 + MOVD R16, 104(R13) + BMI error_not_enough_literals + CMP $0x00020002, R0 + BHI sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big + TST R12, R12 + BNE sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok + TST R0, R0 + BNE sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: + MOVD 32(RSP), R0 + MOVD 16(RSP), R1 + MOVD 24(RSP), R12 + + // Check if we have enough space in s.out + ADD R12, R0, R13 + ADD R9, R13, R13 + MOVD 40(RSP), R16 + CMP R16, R13 + BHI error_not_enough_space + + // Copy literals + TST R0, R0 + BEQ check_offset + MOVD R0, R13 + SUBS $0x10, R13, R13 + BLO copy_1_small + +copy_1_loop: + VLD1 (R10), [V0.B16] + VST1 [V0.B16], (R9) + ADD $0x10, R10, R10 + ADD $0x10, R9, R9 + SUBS $0x10, R13, R13 + BHS copy_1_loop + ADD R13, R10, R10 + ADD $16, R10, R10 + ADD R13, R9, R9 + ADD $16, R9, R9 + ADD $-16, R10, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R9, R15 + VST1 [V0.B16], (R15) + JMP copy_1_end + +copy_1_small: + CMP $0x03, R0 + BEQ copy_1_move_3 + BLO copy_1_move_1or2 + CMP $0x08, R0 + BLO copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVBU (R10), R16 + BFI $0, R16, $8, R13 + ADD R0, R10, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R14 + MOVB R13, (R9) + ADD R0, R9, R15 + MOVB R14, -1(R15) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end + +copy_1_move_3: + MOVHU (R10), R13 + MOVBU 2(R10), R16 + BFI $0, R16, $8, R14 + MOVH R13, (R9) + MOVB R14, 2(R9) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end + +copy_1_move_4through7: + MOVWU (R10), R13 + ADD R0, R10, R15 + MOVWU -4(R15), R14 + MOVW R13, (R9) + ADD R0, R9, R15 + MOVW R14, -4(R15) + ADD R0, R10, R10 + ADD R0, R9, R9 + JMP copy_1_end + +copy_1_move_8through16: + MOVD (R10), R13 + ADD R0, R10, R15 + MOVD -8(R15), R14 + MOVD R13, (R9) + ADD R0, R9, R15 + MOVD R14, -8(R15) + ADD R0, R10, R10 + ADD R0, R9, R9 + +copy_1_end: + ADD R0, R11, R11 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVD R11, R0 + MOVD 48(RSP), R16 + ADD R16, R0, R0 + CMP R0, R1 + BGT error_match_off_too_big + MOVD 64(RSP), R16 + CMP R16, R1 + BGT error_match_off_too_big + + // Copy match from history + MOVD R1, R0 + SUBS R11, R0, R0 + BLS copy_match + MOVD 56(RSP), R13 + SUB R0, R13, R13 + CMP R0, R12 + BGT copy_all_from_history + MOVD R12, R0 + SUBS $0x10, R0, R0 + BLO copy_4_small + +copy_4_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R0, R0 + BHS copy_4_loop + ADD R0, R13, R13 + ADD $16, R13, R13 + ADD R0, R9, R9 + ADD $16, R9, R9 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R9, R15 + VST1 [V0.B16], (R15) + JMP copy_4_end + +copy_4_small: + CMP $0x03, R12 + BEQ copy_4_move_3 + CMP $0x08, R12 + BLO copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVHU (R13), R0 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R1 + MOVH R0, (R9) + MOVB R1, 2(R9) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end + +copy_4_move_4through7: + MOVWU (R13), R0 + ADD R12, R13, R15 + MOVWU -4(R15), R1 + MOVW R0, (R9) + ADD R12, R9, R15 + MOVW R1, -4(R15) + ADD R12, R13, R13 + ADD R12, R9, R9 + JMP copy_4_end + +copy_4_move_8through16: + MOVD (R13), R0 + ADD R12, R13, R15 + MOVD -8(R15), R1 + MOVD R0, (R9) + ADD R12, R9, R15 + MOVD R1, -8(R15) + ADD R12, R13, R13 + ADD R12, R9, R9 + +copy_4_end: + ADD R12, R11, R11 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVD R0, R14 + SUBS $0x10, R14, R14 + BLO copy_5_small + +copy_5_loop: + VLD1 (R13), [V0.B16] + VST1 [V0.B16], (R9) + ADD $0x10, R13, R13 + ADD $0x10, R9, R9 + SUBS $0x10, R14, R14 + BHS copy_5_loop + ADD R14, R13, R13 + ADD $16, R13, R13 + ADD R14, R9, R9 + ADD $16, R9, R9 + ADD $-16, R13, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R9, R15 + VST1 [V0.B16], (R15) + JMP copy_5_end + +copy_5_small: + CMP $0x03, R0 + BEQ copy_5_move_3 + BLO copy_5_move_1or2 + CMP $0x08, R0 + BLO copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVBU (R13), R16 + BFI $0, R16, $8, R14 + ADD R0, R13, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R4 + MOVB R14, (R9) + ADD R0, R9, R15 + MOVB R4, -1(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end + +copy_5_move_3: + MOVHU (R13), R14 + MOVBU 2(R13), R16 + BFI $0, R16, $8, R4 + MOVH R14, (R9) + MOVB R4, 2(R9) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end + +copy_5_move_4through7: + MOVWU (R13), R14 + ADD R0, R13, R15 + MOVWU -4(R15), R4 + MOVW R14, (R9) + ADD R0, R9, R15 + MOVW R4, -4(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + JMP copy_5_end + +copy_5_move_8through16: + MOVD (R13), R14 + ADD R0, R13, R15 + MOVD -8(R15), R4 + MOVD R14, (R9) + ADD R0, R9, R15 + MOVD R4, -8(R15) + ADD R0, R13, R13 + ADD R0, R9, R9 + +copy_5_end: + ADD R0, R11, R11 + SUB R0, R12, R12 + + // Copy match from the current buffer +copy_match: + MOVD R9, R0 + SUB R1, R0, R0 + + // ml <= mo + CMP R1, R12 + BHI copy_overlapping_match + + // Copy non-overlapping match + ADD R12, R11, R11 + MOVD R12, R1 + SUBS $0x10, R1, R1 + BLO copy_2_small + +copy_2_loop: + VLD1 (R0), [V0.B16] + VST1 [V0.B16], (R9) + ADD $0x10, R0, R0 + ADD $0x10, R9, R9 + SUBS $0x10, R1, R1 + BHS copy_2_loop + ADD R1, R0, R0 + ADD $16, R0, R0 + ADD R1, R9, R9 + ADD $16, R9, R9 + ADD $-16, R0, R15 + VLD1 (R15), [V0.B16] + ADD $-16, R9, R15 + VST1 [V0.B16], (R15) + JMP copy_2_end + +copy_2_small: + CMP $0x03, R12 + BEQ copy_2_move_3 + BLO copy_2_move_1or2 + CMP $0x08, R12 + BLO copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + ADD R12, R0, R15 + MOVBU -1(R15), R16 + BFI $0, R16, $8, R13 + MOVB R1, (R9) + ADD R12, R9, R15 + MOVB R13, -1(R15) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end + +copy_2_move_3: + MOVHU (R0), R1 + MOVBU 2(R0), R16 + BFI $0, R16, $8, R13 + MOVH R1, (R9) + MOVB R13, 2(R9) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end + +copy_2_move_4through7: + MOVWU (R0), R1 + ADD R12, R0, R15 + MOVWU -4(R15), R13 + MOVW R1, (R9) + ADD R12, R9, R15 + MOVW R13, -4(R15) + ADD R12, R0, R0 + ADD R12, R9, R9 + JMP copy_2_end + +copy_2_move_8through16: + MOVD (R0), R1 + ADD R12, R0, R15 + MOVD -8(R15), R13 + MOVD R1, (R9) + ADD R12, R9, R15 + MOVD R13, -8(R15) + ADD R12, R0, R0 + ADD R12, R9, R9 + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADD R12, R11, R11 + +copy_slow_3: + MOVBU (R0), R16 + BFI $0, R16, $8, R1 + MOVB R1, (R9) + ADD $1, R0, R0 + ADD $1, R9, R9 + SUBS $1, R12, R12 + BNE copy_slow_3 + +handle_loop: + MOVD ctx+16(FP), R0 + MOVD 96(R0), R16 + SUBS $1, R16, R16 + MOVD R16, 96(R0) + BPL sequenceDecs_decodeSync_safe_amd64_main_loop + +loop_finished: + MOVD br+8(FP), R0 + MOVD R2, 24(R0) + MOVB R3, 40(R0) + MOVD R5, 32(R0) + + // Update the context + MOVD ctx+16(FP), R0 + MOVD R11, 136(R0) + MOVD 144(R0), R1 + SUB R1, R10, R10 + MOVD R10, 168(R0) + + // Return success + MOVD $0x00000000, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: + MOVD 24(RSP), R0 + MOVD ctx+16(FP), R1 + MOVD R0, 216(R1) + MOVD $0x00000001, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: + MOVD ctx+16(FP), R0 + MOVD 24(RSP), R1 + MOVD R1, 216(R0) + MOVD $0x00000002, R16 + MOVD R16, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVD ctx+16(FP), R0 + MOVD 16(RSP), R1 + MOVD R1, 224(R0) + MOVD R11, 136(R0) + MOVD $0x00000003, R16 + MOVD R16, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVD ctx+16(FP), R0 + MOVD 32(RSP), R1 + MOVD R1, 208(R0) + MOVD $0x00000004, R16 + MOVD R16, ret+24(FP) + RET + + // Return with overread error +error_overread: + MOVD $0x00000006, R16 + MOVD R16, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVD ctx+16(FP), R0 + MOVD 32(RSP), R1 + MOVD R1, 208(R0) + MOVD 24(RSP), R1 + MOVD R1, 216(R0) + MOVD R11, 136(R0) + MOVD $0x00000005, R16 + MOVD R16, ret+24(FP) + RET + +// skipped sequenceDecs_decodeSync_safe_bmi2 (generic twin preferred on arm64) diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go b/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go new file mode 100644 index 00000000000..42ce5de7163 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_asm.go @@ -0,0 +1,316 @@ +//go:build (amd64 || arm64) && !appengine && !noasm && gc + +package zstd + +import ( + "fmt" + "io" +) + +// This file holds the parts of the assembly sequence decoder that are identical +// across architectures: the context structs exchanged with the asm, the error +// codes, and the decode/decodeSync/executeSimple wrappers. Each architecture +// supplies the small dispatch helpers (decodeAsm, decodeSyncAsm, +// executeSimpleAsm) that select the concrete asm routine — amd64 also chooses a +// BMI2 variant, arm64 has a single implementation. + +type decodeSyncAsmContext struct { + llTable []decSymbol + mlTable []decSymbol + ofTable []decSymbol + llState uint64 + mlState uint64 + ofState uint64 + iteration int + litRemain int + out []byte + outPosition int + literals []byte + litPosition int + history []byte + windowSize int + ll int // set on error (not for all errors, please refer to _generate/gen.go) + ml int // set on error (not for all errors, please refer to _generate/gen.go) + mo int // set on error (not for all errors, please refer to _generate/gen.go) +} + +type decodeAsmContext struct { + llTable []decSymbol + mlTable []decSymbol + ofTable []decSymbol + llState uint64 + mlState uint64 + ofState uint64 + iteration int + seqs []seqVals + litRemain int +} + +type executeAsmContext struct { + seqs []seqVals + seqIndex int + out []byte + history []byte + literals []byte + outPosition int + litPosition int + windowSize int +} + +const noError = 0 + +// error reported when mo == 0 && ml > 0 +const errorMatchLenOfsMismatch = 1 + +// error reported when ml > maxMatchLen +const errorMatchLenTooBig = 2 + +// error reported when mo > available history or mo > s.windowSize +const errorMatchOffTooBig = 3 + +// error reported when the sum of literal lengths exeeceds the literal buffer size +const errorNotEnoughLiterals = 4 + +// error reported when capacity of `out` is too small +const errorNotEnoughSpace = 5 + +// error reported when bits are overread. +const errorOverread = 6 + +// useSafeDecodeSync reports whether decodeSyncSimple must use the bounds-exact +// ("safe") copy variants for the current buffer geometry. +// +// When the output and literal buffers have compressedBlockOverAlloc (16) +// bytes of slack past their logical use, the assembly may use extended +// memory copies that read and write in 16-byte blocks, overrunning the end +// of a literal run or match by up to 15 bytes. Otherwise it must use the +// bounds-exact ("safe") copies. This mirrors the analogous, always-dynamic +// selection in executeSimple below. +// +// The unsafe copies were disabled in #644 (2022) as a mitigation for a +// crash, but that crash's root cause — an unguarded bitReader overread that +// produced out-of-range match offsets/lengths — was fixed three days later +// in #645, which also added the fuzz corpus that has guarded this path since. +// See #1168. An asan-instrumented fuzz job (see .github/workflows/go.yml) +// covers the extended-copy path, which -race and plain fuzzing cannot. +func (s *sequenceDecs) useSafeDecodeSync() bool { + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { + return true + } + if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { + return true + } + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + return true + } + return false +} + +// decode sequences from the stream with the provided history but without a dictionary. +func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { + if len(s.dict) > 0 { + return false, nil + } + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSize { + return false, nil + } + + useSafe := s.useSafeDecodeSync() + + br := s.br + + maxBlockSize := min(s.windowSize, maxCompressedBlockSize) + + ctx := decodeSyncAsmContext{ + llTable: s.litLengths.fse.dt[:maxTablesize], + mlTable: s.matchLengths.fse.dt[:maxTablesize], + ofTable: s.offsets.fse.dt[:maxTablesize], + llState: uint64(s.litLengths.state.state), + mlState: uint64(s.matchLengths.state.state), + ofState: uint64(s.offsets.state.state), + iteration: s.nSeqs - 1, + litRemain: len(s.literals), + out: s.out, + outPosition: len(s.out), + literals: s.literals, + windowSize: s.windowSize, + history: hist, + } + + s.seqSize = 0 + startSize := len(s.out) + + errCode := decodeSyncAsm(s, br, &ctx, useSafe) + switch errCode { + case noError: + break + + case errorMatchLenOfsMismatch: + return true, fmt.Errorf("zero matchoff and matchlen (%d) > 0", ctx.ml) + + case errorMatchLenTooBig: + return true, fmt.Errorf("match len (%d) bigger than max allowed length", ctx.ml) + + case errorMatchOffTooBig: + return true, fmt.Errorf("match offset (%d) bigger than current history (%d)", + ctx.mo, ctx.outPosition+len(hist)-startSize) + + case errorNotEnoughLiterals: + return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", + ctx.ll, ctx.litRemain+ctx.ll) + + case errorOverread: + return true, io.ErrUnexpectedEOF + + case errorNotEnoughSpace: + size := ctx.outPosition + ctx.ll + ctx.ml + if debugDecoder { + println("msl:", s.maxSyncLen, "cap", cap(s.out), "bef:", startSize, "sz:", size-startSize, "mbs:", maxBlockSize, "outsz:", cap(s.out)-startSize) + } + return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + + default: + return true, fmt.Errorf("sequenceDecs_decode returned erroneous code %d", errCode) + } + + s.seqSize += ctx.litRemain + if s.seqSize > maxBlockSize { + return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + return true, err + } + + s.literals = s.literals[ctx.litPosition:] + t := ctx.outPosition + s.out = s.out[:t] + + // Add final literals + s.out = append(s.out, s.literals...) + if debugDecoder { + t += len(s.literals) + if t != len(s.out) { + panic(fmt.Errorf("length mismatch, want %d, got %d", len(s.out), t)) + } + } + + return true, nil +} + +// decode sequences from the stream without the provided history. +func (s *sequenceDecs) decode(seqs []seqVals) error { + br := s.br + + maxBlockSize := min(s.windowSize, maxCompressedBlockSize) + + ctx := decodeAsmContext{ + llTable: s.litLengths.fse.dt[:maxTablesize], + mlTable: s.matchLengths.fse.dt[:maxTablesize], + ofTable: s.offsets.fse.dt[:maxTablesize], + llState: uint64(s.litLengths.state.state), + mlState: uint64(s.matchLengths.state.state), + ofState: uint64(s.offsets.state.state), + seqs: seqs, + iteration: len(seqs) - 1, + litRemain: len(s.literals), + } + + if debugDecoder { + println("decode: decoding", len(seqs), "sequences", br.remain(), "bits remain on stream") + } + + s.seqSize = 0 + lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56 + errCode := decodeAsm(s, br, &ctx, lte56bits) + if errCode != 0 { + i := len(seqs) - ctx.iteration - 1 + switch errCode { + case errorMatchLenOfsMismatch: + ml := ctx.seqs[i].ml + return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) + + case errorMatchLenTooBig: + ml := ctx.seqs[i].ml + return fmt.Errorf("match len (%d) bigger than max allowed length", ml) + + case errorNotEnoughLiterals: + ll := ctx.seqs[i].ll + return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll) + case errorOverread: + return io.ErrUnexpectedEOF + } + + return fmt.Errorf("sequenceDecs_decode_amd64 returned erroneous code %d", errCode) + } + + if ctx.litRemain < 0 { + return fmt.Errorf("literal count is too big: total available %d, total requested %d", + len(s.literals), len(s.literals)-ctx.litRemain) + } + + s.seqSize += ctx.litRemain + if s.seqSize > maxBlockSize { + return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) + } + if debugDecoder { + println("decode: ", br.remain(), "bits remain on stream. code:", errCode) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + } + return err +} + +// executeSimple handles cases when dictionary is not used. +func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error { + // Ensure we have enough output size... + if len(s.out)+s.seqSize+compressedBlockOverAlloc > cap(s.out) { + addBytes := s.seqSize + len(s.out) + compressedBlockOverAlloc + s.out = append(s.out, make([]byte, addBytes)...) + s.out = s.out[:len(s.out)-addBytes] + } + + if debugDecoder { + printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize) + } + + var t = len(s.out) + out := s.out[:t+s.seqSize] + + ctx := executeAsmContext{ + seqs: seqs, + seqIndex: 0, + out: out, + history: hist, + outPosition: t, + litPosition: 0, + literals: s.literals, + windowSize: s.windowSize, + } + // useSafe avoids overwriting the output buffer when the literals slice has + // not been allocated with the required over-allocation slack. + useSafe := cap(s.literals) < len(s.literals)+compressedBlockOverAlloc + + ok := executeSimpleAsm(&ctx, useSafe) + if !ok { + return fmt.Errorf("match offset (%d) bigger than current history (%d)", + seqs[ctx.seqIndex].mo, ctx.outPosition+len(hist)) + } + s.literals = s.literals[ctx.litPosition:] + t = ctx.outPosition + + // Add final literals + copy(out[t:], s.literals) + if debugDecoder { + t += len(s.literals) + if t != len(out) { + panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize)) + } + } + s.out = out + + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go index 516cd9b0701..8a3db6ba22f 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go @@ -1,4 +1,4 @@ -//go:build !amd64 || appengine || !gc || noasm +//go:build (!amd64 && !arm64) || appengine || !gc || noasm package zstd diff --git a/vendor/github.com/klauspost/compress/zstd/snappy.go b/vendor/github.com/klauspost/compress/zstd/snappy.go index 336c2889304..36c56f36d77 100644 --- a/vendor/github.com/klauspost/compress/zstd/snappy.go +++ b/vendor/github.com/klauspost/compress/zstd/snappy.go @@ -334,9 +334,10 @@ func decodeSnappy(blk *blockEnc, src []byte) error { return errUnsupportedLiteralLength } - //if length > snappyMaxBlockSize-d || uint32(length) > len(src)-s { - // return ErrSnappyCorrupt - //} + if length > len(src)-s { + println("length > len(src)-s", length, len(src)-s) + return ErrSnappyCorrupt + } blk.literals = append(blk.literals, src[s:s+length]...) //println(length, "litLen") diff --git a/vendor/github.com/klauspost/cpuid/v2/.goreleaser.yml b/vendor/github.com/klauspost/cpuid/v2/.goreleaser.yml index 1b695b62c35..14712fe0dda 100644 --- a/vendor/github.com/klauspost/cpuid/v2/.goreleaser.yml +++ b/vendor/github.com/klauspost/cpuid/v2/.goreleaser.yml @@ -29,7 +29,7 @@ archives: name_template: "cpuid-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" format_overrides: - goos: windows - format: zip + formats: [ 'zip' ] files: - LICENSE checksum: diff --git a/vendor/github.com/klauspost/cpuid/v2/README.md b/vendor/github.com/klauspost/cpuid/v2/README.md index 7b1d5992116..a99bbdba361 100644 --- a/vendor/github.com/klauspost/cpuid/v2/README.md +++ b/vendor/github.com/klauspost/cpuid/v2/README.md @@ -2,7 +2,7 @@ Package cpuid provides information about the CPU running the current program. CPU features are detected on startup, and kept for fast access through the life of the application. -Currently x86 / x64 (AMD64/i386) and ARM (ARM64) is supported, and no external C (cgo) code is used, which should make the library very easy to use. +Currently x86 / x64 (AMD64/i386), ARM (ARM64), and RISC-V (RV64) are supported, and no external C (cgo) code is used, which should make the library very easy to use. You can access the CPU information by accessing the shared CPU variable of the cpuid library. @@ -281,7 +281,7 @@ Exit Code 1 | AMXBF16 | Tile computational operations on BFLOAT16 numbers | | AMXINT8 | Tile computational operations on 8-bit integers | | AMXFP16 | Tile computational operations on FP16 numbers | -| AMXFP8 | Tile computational operations on FP8 numbers | +| AMXFP8 | Tile computational operations on FP8 numbers | | AMXCOMPLEX | Tile computational operations on complex numbers | | AMXTILE | Tile architecture | | AMXTF32 | Matrix Multiplication of TF32 Tiles into Packed Single Precision Tile | @@ -418,6 +418,7 @@ Exit Code 1 | SEV_SNP | AMD SEV Secure Nested Paging supported | | SGX | Software Guard Extensions | | SGXLC | Software Guard Extensions Launch Control | +| SGXPQC | Software Guard Extensions 256-bit Encryption | | SHA | Intel SHA Extensions | | SME | AMD Secure Memory Encryption supported | | SME_COHERENT | AMD Hardware cache coherency across encryption domains enforced | @@ -450,6 +451,9 @@ Exit Code 1 | TLB_FLUSH_NESTED | AMD: Flushing includes all the nested translations for guest translations | | TME | Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE. | | TOPEXT | TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX. | +| TSA_L1_NO | AMD only: Not vulnerable to TSA-L1 | +| TSA_SQ_NO | AMD only: Not vulnerable to TSA-SQ | +| TSA_VERW_CLEAR | AMD: If set, the memory form of the VERW instruction may be used to help mitigate TSA | | TSCRATEMSR | MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104 | | TSXLDTRK | Intel TSX Suspend Load Address Tracking | | VAES | Vector AES. AVX(512) versions requires additional checks. | @@ -502,6 +506,74 @@ Exit Code 1 | SM3 | SM3 instructions | | SM4 | SM4 instructions | | SVE | Scalable Vector Extension | +| SVE2 | Scalable Vector Extension 2 | +| SB | Speculation barrier (SB instruction) | +| SSBS | Speculative Store Bypass Safe (PSTATE.SSBS) | +| BTI | Branch Target Identification | +| FLAGM2 | Condition flag manipulation version 2 (AXFLAG, XAFLAG) | +| FRINTTS | Floating-point to integer rounding (FRINT32Z, FRINT64Z, etc) | +| DCPODP | Data cache clean to Point of Deep Persistence (DC CVADP) | +| BF16 | BFloat16 instructions (BFDOT, BFMMLA, etc) | +| I8MM | Int8 matrix multiplication (SMMLA, UMMLA, USMMLA) | +| WFXT | WFE/WFI with timeout (WFET, WFIT) | +| MOPS | Memory copy and set instructions (CPYF, SETP, etc) | +| HBC | Hinted conditional branches (BC.cond) | +| CSSC | Common short sequence compression (ABS, SMAX, UMAX, etc) | + +## riscv64 feature detection + +On `riscv64/linux`, CPU features are detected using the `riscv_hwprobe` syscall (Linux 6.4+). +For older kernels, detection falls back to parsing `/proc/cpuinfo` for the ISA string. + +Cache line size is detected via `riscv_hwprobe` (Zicbom block size) or sysfs fallback. +Other cache and topology information is not yet available. + +# RISC-V features: + +| Feature Flag | Description | +|----------------|----------------------------------------------------| +| RV_IMA | IMA base (Integer, Multiply, Atomic) | +| RV_C | Compressed instructions | +| RV_F | Single-precision FP | +| RV_D | Double-precision FP | +| RV_V | Vector extension (V) | +| RV_ZBA | Address generation | +| RV_ZBB | Basic bit manipulation | +| RV_ZBC | Carry-less multiplication | +| RV_ZBS | Single-bit manipulation | +| RV_ZICOND | Integer conditional operations | +| RV_ZIHINTPAUSE | Pause hint | +| RV_ZICBOM | Cache block management operations | +| RV_ZICBOZ | Cache block zero | +| RV_ZICBOP | Cache block prefetch | +| RV_ZFA | Additional floating-point | +| RV_ZFH | Half-precision FP | +| RV_ZFHMIN | Minimal half-precision FP | +| RV_ZTSO | Total store ordering | +| RV_ZACAS | Atomic CAS | +| RV_ZBKB | Bit-manipulation for crypto | +| RV_ZBKC | Carry-less multiply for crypto | +| RV_ZBKX | Crossbar permutations | +| RV_ZKND | NIST Suite: AES decrypt | +| RV_ZKNE | NIST Suite: AES encrypt | +| RV_ZKNH | NIST Suite: SHA-2 (SHA-256/SHA-512) | +| RV_ZKSED | ShangMi Suite: SM4 block cipher | +| RV_ZKSH | ShangMi Suite: SM3 hash | +| RV_ZKT | Data-independent execution latency (Crypto) | +| RV_ZKN | NIST Algorithm Suite (combined from individual) | +| RV_ZKS | ShangMi Algorithm Suite (combined from individual) | +| RV_ZVBB | Vector Basic Bit-manipulation | +| RV_ZVBC | Vector Carry-less multiply | +| RV_ZVKB | Vector Bit-manipulation for crypto | +| RV_ZVKG | Vector GCM/GMAC | +| RV_ZVKNED | NIST Suite: Vector AES encrypt+decrypt | +| RV_ZVKNHA | NIST Suite: Vector SHA-2 (SHA-256) | +| RV_ZVKNHB | NIST Suite: Vector SHA-2 (SHA-512) | +| RV_ZVKSED | ShangMi Suite: Vector SM4 | +| RV_ZVKSH | ShangMi Suite: Vector SM3 hash | +| RV_ZVKT | Vector Data-independent execution latency | +| RV_ZVKNG | NIST Suite with GCM (combined from individual) | +| RV_ZVKSG | ShangMi Suite with GCM (combined from individual) | # license diff --git a/vendor/github.com/klauspost/cpuid/v2/cpuid.go b/vendor/github.com/klauspost/cpuid/v2/cpuid.go index 248439a9a57..db903f46a47 100644 --- a/vendor/github.com/klauspost/cpuid/v2/cpuid.go +++ b/vendor/github.com/klauspost/cpuid/v2/cpuid.go @@ -3,7 +3,7 @@ // Package cpuid provides information about the CPU running the current program. // // CPU features are detected on startup, and kept for fast access through the life of the application. -// Currently x86 / x64 (AMD64) as well as arm64 is supported. +// Currently x86 / x64 (AMD64), arm64, and riscv64 are supported. // // You can access the CPU information by accessing the shared CPU variable of the cpuid library. // @@ -17,6 +17,7 @@ import ( "math/bits" "os" "runtime" + "slices" "strings" ) @@ -61,6 +62,13 @@ const ( SRE Apple + // RISC-V vendors + SiFive + StarFive + THead + Andes + SpacemiT + lastVendor ) @@ -95,6 +103,7 @@ const ( AVX2 // AVX2 functions AVX512BF16 // AVX-512 BFLOAT16 Instructions AVX512BITALG // AVX-512 Bit Algorithms + AVX512BMM // AVX-512 Bit Manipulation Instructions AVX512BW // AVX-512 Byte and Word Instructions AVX512CD // AVX-512 Conflict Detection Instructions AVX512DQ // AVX-512 Doubleword and Quadword Instructions @@ -139,6 +148,7 @@ const ( FMA4 // Bulldozer FMA4 functions FP128 // AMD: When set, the internal FP/SIMD execution datapath is no more than 128-bits wide FP256 // AMD: When set, the internal FP/SIMD execution datapath is no more than 256-bits wide + FRED // Flexible Return and Event Delivery FSRM // Fast Short Rep Mov FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9 FXSROPT // FXSAVE/FXRSTOR optimizations @@ -220,6 +230,7 @@ const ( SEV_SNP // AMD SEV Secure Nested Paging supported SGX // Software Guard Extensions SGXLC // Software Guard Extensions Launch Control + SGXPQC // Software Guard Extensions 256-bit Encryption SHA // Intel SHA Extensions SME // AMD Secure Memory Encryption supported SME_COHERENT // AMD Hardware cache coherency across encryption domains enforced @@ -255,6 +266,9 @@ const ( TLB_FLUSH_NESTED // AMD: Flushing includes all the nested translations for guest translations TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE. TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX. + TSA_L1_NO // AMD only: Not vulnerable to TSA-L1 + TSA_SQ_NO // AM onlyD: Not vulnerable to TSA-SQ + TSA_VERW_CLEAR // If set, the memory form of the VERW instruction may be used to help mitigate TSA TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104 TSXLDTRK // Intel TSX Suspend Load Address Tracking VAES // Vector AES. AVX(512) versions requires additional checks. @@ -304,6 +318,77 @@ const ( SM3 // SM3 instructions SM4 // SM4 instructions SVE // Scalable Vector Extension + SVE2 // Scalable Vector Extension 2 + SB // Speculation barrier (SB instruction) + SSBS // Speculative Store Bypass Safe (PSTATE.SSBS) + BTI // Branch Target Identification + FLAGM2 // Condition flag manipulation version 2 (AXFLAG, XAFLAG) + FRINTTS // Floating-point to integer rounding (FRINT32Z, FRINT64Z, etc) + DCPODP // Data cache clean to Point of Deep Persistence (DC CVADP) + BF16 // BFloat16 instructions (BFDOT, BFMMLA, etc) + I8MM // Int8 matrix multiplication (SMMLA, UMMLA, USMMLA) + WFXT // WFE/WFI with timeout (WFET, WFIT) + MOPS // Memory copy and set instructions (CPYF, SETP, etc) + HBC // Hinted conditional branches (BC.cond) + CSSC // Common short sequence compression (ABS, SMAX, UMAX, etc) + + // PMU + PMU_FIXEDCOUNTER_CYCLES + PMU_FIXEDCOUNTER_REFCYCLES + PMU_FIXEDCOUNTER_INSTRUCTIONS + PMU_FIXEDCOUNTER_TOPDOWN_SLOTS + + // RISC-V features + RV_IMA // IMA base (Integer, Multiply, Atomic) + RV_C // Compressed instructions + RV_F // Single-precision FP + RV_D // Double-precision FP + RV_V // Vector extension (V) + RV_ZBA // Address generation + RV_ZBB // Basic bit manipulation + RV_ZBC // Carry-less multiplication + RV_ZBS // Single-bit manipulation + RV_ZICOND // Integer conditional operations + RV_ZIHINTPAUSE // Pause hint + RV_ZICBOM // Cache block management operations + RV_ZICBOZ // Cache block zero + RV_ZICBOP // Cache block prefetch + RV_ZFA // Additional floating-point + RV_ZFH // Half-precision FP + RV_ZFHMIN // Minimal half-precision FP + RV_ZTSO // Total store ordering + RV_ZACAS // Atomic CAS + // Scalar cryptography + RV_ZBKB // Bit-manipulation for crypto + RV_ZBKC // Carry-less multiply for crypto + RV_ZBKX // Crossbar permutations + RV_ZKND // NIST Suite: AES decrypt + RV_ZKNE // NIST Suite: AES encrypt + RV_ZKNH // NIST Suite: SHA-2 (SHA-256/SHA-512) + RV_ZKSED // ShangMi Suite: SM4 block cipher + RV_ZKSH // ShangMi Suite: SM3 hash + RV_ZKT // Data-independent execution latency (Crypto) + + // Scalar crypto suites (combined from individual extensions) + RV_ZKN // NIST Algorithm Suite (Zknd+Zkne+Zknh+Zbkb+Zbkc+Zbkx+Zkt) + RV_ZKS // ShangMi Algorithm Suite (Zksed+Zksh+Zbkb+Zbkc+Zbkx+Zkt) + + // Vector cryptography + RV_ZVBB // Vector Basic Bit-manipulation + RV_ZVBC // Vector Carry-less multiply + RV_ZVKB // Vector Bit-manipulation for crypto + RV_ZVKG // Vector GCM/GMAC + RV_ZVKNED // NIST Suite: Vector AES encrypt+decrypt + RV_ZVKNHA // NIST Suite: Vector SHA-2 (SHA-256) + RV_ZVKNHB // NIST Suite: Vector SHA-2 (SHA-512) + RV_ZVKSED // ShangMi Suite: Vector SM4 + RV_ZVKSH // ShangMi Suite: Vector SM3 hash + RV_ZVKT // Vector Data-independent execution latency + + // Vector crypto suites (combined from individual extensions) + RV_ZVKNG // NIST Suite with GCM (Zvkned+Zvknhb+Zvkg+Zvkb+Zvkt) + RV_ZVKSG // ShangMi Suite with GCM (Zvksed+Zvksh+Zvkg+Zvkb+Zvkt) + // Keep it last. It automatically defines the size of []flagSet lastID @@ -336,11 +421,36 @@ type CPUInfo struct { SGX SGXSupport AMDMemEncryption AMDMemEncryptionSupport AVX10Level uint8 + PMU PerformanceMonitoringInfo // holds information about the PMU maxFunc uint32 maxExFunc uint32 } +// PerformanceMonitoringInfo holds information about CPU performance monitoring capabilities. +// This is primarily populated from CPUID leaf 0xAh on x86 +type PerformanceMonitoringInfo struct { + // VersionID (x86 only): Version ID of architectural performance monitoring. + // A value of 0 means architectural performance monitoring is not supported or information is unavailable. + VersionID uint8 + // NumGPPMC: Number of General-Purpose Performance Monitoring Counters per logical processor. + // On ARM, this is derived from PMCR_EL0.N (number of event counters). + NumGPCounters uint8 + // GPPMCWidth: Bit width of General-Purpose Performance Monitoring Counters. + // On ARM, typically 64 for PMU event counters. + GPPMCWidth uint8 + // NumFixedPMC: Number of Fixed-Function Performance Counters. + // Valid on x86 if VersionID > 1. On ARM, this typically includes at least the cycle counter (PMCCNTR_EL0). + NumFixedPMC uint8 + // FixedPMCWidth: Bit width of Fixed-Function Performance Counters. + // Valid on x86 if VersionID > 1. On ARM, the cycle counter (PMCCNTR_EL0) is 64-bit. + FixedPMCWidth uint8 + // Raw register output from CPUID leaf 0xAh. + RawEBX uint32 + RawEAX uint32 + RawEDX uint32 +} + var cpuid func(op uint32) (eax, ebx, ecx, edx uint32) var cpuidex func(op, op2 uint32) (eax, ebx, ecx, edx uint32) var xgetbv func(index uint32) (eax, edx uint32) @@ -383,8 +493,8 @@ func Detect() { os.Exit(1) } if disableFlag != nil { - s := strings.Split(*disableFlag, ",") - for _, feat := range s { + s := strings.SplitSeq(*disableFlag, ",") + for feat := range s { feat := ParseFeature(strings.TrimSpace(feat)) if feat != UNKNOWN { CPU.featureSet.unset(feat) @@ -435,12 +545,7 @@ func (c *CPUInfo) Has(id FeatureID) bool { // AnyOf returns whether the CPU supports one or more of the requested features. func (c CPUInfo) AnyOf(ids ...FeatureID) bool { - for _, id := range ids { - if c.featureSet.inSet(id) { - return true - } - } - return false + return slices.ContainsFunc(ids, c.featureSet.inSet) } // Features contains several features combined for a fast check using @@ -460,6 +565,11 @@ func (c *CPUInfo) HasAll(f Features) bool { return c.featureSet.hasSetP(f) } +// HasOneOf returns whether the CPU supports one or more of the requested features. +func (c *CPUInfo) HasOneOf(f Features) bool { + return c.featureSet.hasOneOf(f) +} + // https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels var oneOfLevel = CombineFeatures(SYSEE, SYSCALL) var level1Features = CombineFeatures(CMOV, CMPXCHG8, X87, FXSR, MMX, SSE, SSE2) @@ -467,6 +577,56 @@ var level2Features = CombineFeatures(CMOV, CMPXCHG8, X87, FXSR, MMX, SSE, SSE2, var level3Features = CombineFeatures(CMOV, CMPXCHG8, X87, FXSR, MMX, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE) var level4Features = CombineFeatures(CMOV, CMPXCHG8, X87, FXSR, MMX, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL) +// RV_CRYPTO_FEATS contains all RISC-V scalar cryptography instruction extensions (excludes Zkt since it is a timing guarantee, not a computational instruction). +var RV_CRYPTO_FEATS = CombineFeatures(RV_ZBKB, RV_ZBKC, RV_ZBKX, RV_ZKND, RV_ZKNE, RV_ZKNH, RV_ZKSED, RV_ZKSH) + +// RV_VECTOR_CRYPTO_FEATS contains all RISC-V vector cryptography extensions. +var RV_VECTOR_CRYPTO_FEATS = CombineFeatures(RV_ZVBB, RV_ZVBC, RV_ZVKB, RV_ZVKG, RV_ZVKNED, RV_ZVKNHA, RV_ZVKNHB, RV_ZVKSED, RV_ZVKSH) + +// RISC-V application profile feature sets. +// https://github.com/riscv/riscv-profiles +var rvProfile20Features = CombineFeatures(RV_IMA, RV_C, RV_F, RV_D) +var rvProfile22Features = CombineFeatures(RV_IMA, RV_C, RV_F, RV_D, RV_ZBA, RV_ZBB, RV_ZBS, RV_ZFHMIN, RV_ZICBOM, RV_ZICBOP, RV_ZICBOZ, RV_ZIHINTPAUSE) +var rvProfile23Features = CombineFeatures(RV_IMA, RV_C, RV_F, RV_D, RV_ZBA, RV_ZBB, RV_ZBS, RV_ZFHMIN, RV_ZICBOM, RV_ZICBOP, RV_ZICBOZ, RV_ZIHINTPAUSE, RV_V, RV_ZFA, RV_ZICOND, RV_ZVBB, RV_ZVKB) + +// RISC-V crypto suites — combined from individual extensions. +var rvZKNFeatures = CombineFeatures(RV_ZKND, RV_ZKNE, RV_ZKNH, RV_ZBKB, RV_ZBKC, RV_ZBKX, RV_ZKT) +var rvZKSFeatures = CombineFeatures(RV_ZKSED, RV_ZKSH, RV_ZBKB, RV_ZBKC, RV_ZBKX, RV_ZKT) +var rvZVKNFeatures = CombineFeatures(RV_ZVKNED, RV_ZVKNHB, RV_ZVKG, RV_ZVKB, RV_ZVKT) +var rvZVKSFeatures = CombineFeatures(RV_ZVKSED, RV_ZVKSH, RV_ZVKG, RV_ZVKB, RV_ZVKT) + +// ARM64 architecture levels. armV8Levels[m] is the cumulative set of mandatory +// user-space instruction features added up to and including ARMv8.m that this +// package can detect. EL1/system-only features (PAN, VHE, CSV2/CSV3, ECV, ...) +// are excluded since they are irrelevant to user-space code generation, exactly +// as X64Level ignores non-instruction features. +// +// FEAT_SSBS and FEAT_BTI, although mandatory from ARMv8.5, are intentionally NOT +// required. Both are OS-policy-gated security features (speculative store bypass +// safety and branch-target identification) that Go code generation never depends +// on: their HWCAP/sysctl bits are set only when the OS or hypervisor enables the +// protection, not purely from CPU capability, so they are routinely hidden even +// on capable silicon (neither a Neoverse N2 Linux guest nor Apple Silicon reports +// them). Requiring them would cap such CPUs at v8.4. Both are still detected and +// reported through FeatureSet when present. +// https://go.dev/wiki/MinimumRequirements#arm64 +var armV8Levels = [...]Features{ + CombineFeatures(FP, ASIMD), // v8.0 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM), // v8.1 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP), // v8.2 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC), // v8.3 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC, TS), // v8.4 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC, TS, SB, FRINTTS, FLAGM2, DCPODP), // v8.5 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC, TS, SB, FRINTTS, FLAGM2, DCPODP, BF16, I8MM), // v8.6 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC, TS, SB, FRINTTS, FLAGM2, DCPODP, BF16, I8MM, WFXT), // v8.7 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC, TS, SB, FRINTTS, FLAGM2, DCPODP, BF16, I8MM, WFXT, MOPS, HBC), // v8.8 + CombineFeatures(FP, ASIMD, ATOMICS, CRC32, ASIMDRDM, DCPOP, JSCVT, FCMA, LRCPC, TS, SB, FRINTTS, FLAGM2, DCPODP, BF16, I8MM, WFXT, MOPS, HBC, CSSC), // v8.9 +} + +// armCrypto matches the GOARM64 ",crypto" option: FEAT_AES, FEAT_PMULL, +// FEAT_SHA1 and FEAT_SHA256. +var armCrypto = CombineFeatures(AESARM, PMULL, SHA1, SHA2) + // X64Level returns the microarchitecture level detected on the CPU. // If features are lacking or non x64 mode, 0 is returned. // See https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels @@ -489,6 +649,67 @@ func (c CPUInfo) X64Level() int { return 0 } +// RVProfile returns the RISC-V application profile level. +// 0 = unknown / base ISA only, 20 = RVA20, 22 = RVA22, 23 = RVA23. +// Returns 0 on non-RISC-V architectures or if not detected. +// https://github.com/riscv/riscv-profiles +func (c CPUInfo) RVProfile() int { + switch { + case c.featureSet.hasSetP(rvProfile23Features): + return 23 + case c.featureSet.hasSetP(rvProfile22Features): + return 22 + case c.featureSet.hasSetP(rvProfile20Features): + return 20 + default: + return 0 + } +} + +// ARM64Level returns the ARMv8/ARMv9 architecture version supported by the CPU +// as (major, minor), e.g. 8, 4 for ARMv8.4-A or 9, 0 for ARMv9.0-A. +// Only mandatory user-space instruction features are considered, so the result +// is the highest level whose required instructions are all present. +// Returns 0, 0 on non-arm64 CPUs or when feature detection was unavailable. +func (c CPUInfo) ARM64Level() (major, minor int) { + if !c.featureSet.hasSetP(armV8Levels[0]) { + return 0, 0 + } + m8 := 0 + for m := len(armV8Levels) - 1; m >= 1; m-- { + if c.featureSet.hasSetP(armV8Levels[m]) { + m8 = m + break + } + } + // ARMv9.x mandates everything in ARMv8.(x+5) plus SVE2. + if m8 >= 5 && c.featureSet.inSet(SVE2) { + return 9, m8 - 5 + } + return 8, m8 +} + +// GOARM64 returns a value usable as the GOARM64 build setting for the detected +// CPU, e.g. "v8.4" or "v9.0,crypto". The ",crypto" suffix is appended when AES, +// PMULL, SHA1 and SHA256 are all present; the ",lse" suffix is appended in the +// rare case LSE is present without the rest of the ARMv8.1 feature set. +// Returns "" on non-arm64 CPUs or when feature detection was unavailable. +// See https://go.dev/wiki/MinimumRequirements#arm64 +func (c CPUInfo) GOARM64() string { + major, minor := c.ARM64Level() + if major == 0 { + return "" + } + v := fmt.Sprintf("v%d.%d", major, minor) + if major == 8 && minor == 0 && c.featureSet.inSet(ATOMICS) { + v += ",lse" + } + if c.featureSet.hasSetP(armCrypto) { + v += ",crypto" + } + return v +} + // Disable will disable one or several features. func (c *CPUInfo) Disable(ids ...FeatureID) bool { for _, id := range ids { @@ -735,7 +956,7 @@ func flagSetWith(feat ...FeatureID) flagSet { // Will return UNKNOWN if not found. func ParseFeature(s string) FeatureID { s = strings.ToUpper(s) - for i := firstID; i < lastID; i++ { + for i := range lastID { if i.String() == s { return i } @@ -749,7 +970,7 @@ func (s flagSet) Strings() []string { return []string{""} } r := make([]string, 0) - for i := firstID; i < lastID; i++ { + for i := range lastID { if s.inSet(i) { r = append(r, i.String()) } @@ -770,7 +991,7 @@ func maxFunctionID() uint32 { func brandName() string { if maxExtendedFunction() >= 0x80000004 { v := make([]uint32, 0, 48) - for i := uint32(0); i < 3; i++ { + for i := range uint32(3) { a, b, c, d := cpuid(0x80000002 + i) v = append(v, a, b, c, d) } @@ -1039,7 +1260,7 @@ func (c *CPUInfo) cacheSize() { // Hack: When we encounter the same entry 100 times we break. nSame := 0 var last uint32 - for i := uint32(0); i < math.MaxUint32; i++ { + for i := range uint32(math.MaxUint32) { eax, ebx, ecx, _ := cpuidex(0x8000001D, i) level := (eax >> 5) & 7 @@ -1293,6 +1514,7 @@ func support() flagSet { fs.setIf(eax1&(1<<10) != 0, MOVSB_ZL) fs.setIf(eax1&(1<<11) != 0, STOSB_SHORT) fs.setIf(eax1&(1<<12) != 0, CMPSB_SCADBS_SHORT) + fs.setIf(eax1&(1<<17) != 0, FRED) fs.setIf(eax1&(1<<22) != 0, HRESET) fs.setIf(eax1&(1<<23) != 0, AVXIFMA) fs.setIf(eax1&(1<<26) != 0, LAM) @@ -1358,6 +1580,11 @@ func support() flagSet { fs.setIf(edx&(1<<4) != 0, BHI_CTRL) fs.setIf(edx&(1<<5) != 0, MCDT_NO) + if fs.inSet(SGX) { + eax, _, _, _ := cpuidex(0x12, 0) + fs.setIf(eax&(1<<12) != 0, SGXPQC) + } + // Add keylocker features. if fs.inSet(KEYLOCKER) && mfi >= 0x19 { _, ebx, _, _ := cpuidex(0x19, 0) @@ -1371,6 +1598,7 @@ func support() flagSet { fs.setIf(ebx&(1<<17) != 0, AVX10_256) fs.setIf(ebx&(1<<18) != 0, AVX10_512) } + } // Processor Extended State Enumeration Sub-leaf (EAX = 0DH, ECX = 1) @@ -1514,12 +1742,29 @@ func support() flagSet { } if maxExtendedFunction() >= 0x80000021 && vend == AMD { - a, _, _, _ := cpuid(0x80000021) + a, _, c, _ := cpuid(0x80000021) fs.setIf((a>>31)&1 == 1, SRSO_MSR_FIX) fs.setIf((a>>30)&1 == 1, SRSO_USER_KERNEL_NO) fs.setIf((a>>29)&1 == 1, SRSO_NO) fs.setIf((a>>28)&1 == 1, IBPB_BRTYPE) fs.setIf((a>>27)&1 == 1, SBPB) + fs.setIf((a>>23)&1 == 1, AVX512BMM) + fs.setIf((c>>1)&1 == 1, TSA_L1_NO) + fs.setIf((c>>2)&1 == 1, TSA_SQ_NO) + fs.setIf((a>>5)&1 == 1, TSA_VERW_CLEAR) + } + if vend == AMD { + if family < 0x19 { + // AMD CPUs that are older than Family 19h are not vulnerable to TSA but do not set TSA_L1_NO or TSA_SQ_NO. + // Source: https://www.amd.com/content/dam/amd/en/documents/resources/bulletin/technical-guidance-for-mitigating-transient-scheduler-attacks.pdf + fs.set(TSA_L1_NO) + fs.set(TSA_SQ_NO) + } else if family == 0x1a { + // AMD Family 1Ah models 00h-4Fh and 60h-7Fh are also not vulnerable to TSA but do not set TSA_L1_NO or TSA_SQ_NO. + // Future AMD CPUs will set these CPUID bits if appropriate. CPUs will be designed to set these CPUID bits if appropriate. + notVuln := model <= 0x4f || (model >= 0x60 && model <= 0x7f) + fs.setIf(notVuln, TSA_L1_NO, TSA_SQ_NO) + } } if mfi >= 0x20 { @@ -1575,3 +1820,47 @@ func valAsString(values ...uint32) []byte { } return r } + +func parseLeaf0AH(c *CPUInfo, eax, ebx, edx uint32) (info PerformanceMonitoringInfo) { + info.VersionID = uint8(eax & 0xFF) + info.NumGPCounters = uint8((eax >> 8) & 0xFF) + info.GPPMCWidth = uint8((eax >> 16) & 0xFF) + + info.RawEBX = ebx + info.RawEAX = eax + info.RawEDX = edx + + if info.VersionID > 1 { // This information is only valid if VersionID > 1 + info.NumFixedPMC = uint8(edx & 0x1F) // Bits 4:0 + info.FixedPMCWidth = uint8((edx >> 5) & 0xFF) // Bits 12:5 + } + if info.VersionID > 0 { + // first 4 fixed events are always instructions retired, cycles, ref cycles and topdown slots + if ebx == 0x0 && info.NumFixedPMC == 3 { + c.featureSet.set(PMU_FIXEDCOUNTER_INSTRUCTIONS) + c.featureSet.set(PMU_FIXEDCOUNTER_CYCLES) + c.featureSet.set(PMU_FIXEDCOUNTER_REFCYCLES) + } + if ebx == 0x0 && info.NumFixedPMC == 4 { + c.featureSet.set(PMU_FIXEDCOUNTER_INSTRUCTIONS) + c.featureSet.set(PMU_FIXEDCOUNTER_CYCLES) + c.featureSet.set(PMU_FIXEDCOUNTER_REFCYCLES) + c.featureSet.set(PMU_FIXEDCOUNTER_TOPDOWN_SLOTS) + } + if ebx != 0x0 { + if ((ebx >> 0) & 1) == 0 { + c.featureSet.set(PMU_FIXEDCOUNTER_INSTRUCTIONS) + } + if ((ebx >> 1) & 1) == 0 { + c.featureSet.set(PMU_FIXEDCOUNTER_CYCLES) + } + if ((ebx >> 2) & 1) == 0 { + c.featureSet.set(PMU_FIXEDCOUNTER_REFCYCLES) + } + if ((ebx >> 3) & 1) == 0 { + c.featureSet.set(PMU_FIXEDCOUNTER_TOPDOWN_SLOTS) + } + } + } + return info +} diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go b/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go index 9ae32d607dc..e615b10be7d 100644 --- a/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go @@ -1,7 +1,6 @@ // Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. //go:build arm64 && !gccgo && !noasm && !appengine -// +build arm64,!gccgo,!noasm,!appengine package cpuid @@ -189,6 +188,7 @@ func addInfo(c *CPUInfo, safe bool) { f.setIf(instAttrReg0&(0xf<<60) != 0, RNDR) f.setIf(instAttrReg0&(0xf<<56) != 0, TLB) f.setIf(instAttrReg0&(0xf<<52) != 0, TS) + f.setIf(instAttrReg0&(0xf<<52) == 2<<52, FLAGM2) // TS == 0b0010 (FEAT_FlagM2) f.setIf(instAttrReg0&(0xf<<48) != 0, FHM) f.setIf(instAttrReg0&(0xf<<44) != 0, ASIMDDP) f.setIf(instAttrReg0&(0xf<<40) != 0, SM4) @@ -244,6 +244,13 @@ func addInfo(c *CPUInfo, safe bool) { // fmt.Println("APA") // } f.setIf(instAttrReg1&(0xf<<0) != 0, DCPOP) + f.setIf(instAttrReg1&(0xf<<0) == 2<<0, DCPODP) // DPB == 0b0010 (FEAT_DPB2) + + // Upper ID_AA64ISAR1_EL1 fields, not in the table above. + f.setIf(instAttrReg1&(0xf<<32) != 0, FRINTTS) // bits [35:32] + f.setIf(instAttrReg1&(0xf<<36) != 0, SB) // bits [39:36] + f.setIf(instAttrReg1&(0xf<<44) != 0, BF16) // bits [47:44] + f.setIf(instAttrReg1&(0xf<<52) != 0, I8MM) // bits [55:52] // Store c.featureSet.or(f) diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_ref.go b/vendor/github.com/klauspost/cpuid/v2/detect_ref.go index 574f9389c07..38699f4d78a 100644 --- a/vendor/github.com/klauspost/cpuid/v2/detect_ref.go +++ b/vendor/github.com/klauspost/cpuid/v2/detect_ref.go @@ -1,7 +1,6 @@ // Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. -//go:build (!amd64 && !386 && !arm64) || gccgo || noasm || appengine -// +build !amd64,!386,!arm64 gccgo noasm appengine +//go:build (!amd64 && !386 && !arm64 && !riscv64) || ((amd64 || 386) && (gccgo || noasm || appengine)) package cpuid diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_ref_arm64.go b/vendor/github.com/klauspost/cpuid/v2/detect_ref_arm64.go new file mode 100644 index 00000000000..d2ea76ba823 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/v2/detect_ref_arm64.go @@ -0,0 +1,19 @@ +// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. + +//go:build arm64 && (gccgo || noasm || appengine) + +package cpuid + +func initCPU() { + cpuid = func(uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 } + cpuidex = func(x, y uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 } + xgetbv = func(uint32) (a, b uint32) { return 0, 0 } + rdtscpAsm = func() (a, b, c, d uint32) { return 0, 0, 0, 0 } +} + +func addInfo(c *CPUInfo, safe bool) { + c.CacheLine = 64 + detectOS(c) +} + +func getVectorLength() (vl, pl uint64) { return 0, 0 } diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_riscv64.go b/vendor/github.com/klauspost/cpuid/v2/detect_riscv64.go new file mode 100644 index 00000000000..25381f08982 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/v2/detect_riscv64.go @@ -0,0 +1,16 @@ +// Copyright (c) 2026 Klaus Post, released under MIT License. See LICENSE file. + +package cpuid + +func getVectorLength() (vl, pl uint64) { return 0, 0 } + +func initCPU() { + cpuid = func(uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 } + cpuidex = func(x, y uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 } + xgetbv = func(uint32) (a, b uint32) { return 0, 0 } + rdtscpAsm = func() (a, b, c, d uint32) { return 0, 0, 0, 0 } +} + +func addInfo(c *CPUInfo, safe bool) { + detectOS(c) +} diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_x86.go b/vendor/github.com/klauspost/cpuid/v2/detect_x86.go index f924c9d8399..22819ce4a91 100644 --- a/vendor/github.com/klauspost/cpuid/v2/detect_x86.go +++ b/vendor/github.com/klauspost/cpuid/v2/detect_x86.go @@ -1,7 +1,6 @@ // Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. //go:build (386 && !gccgo && !noasm && !appengine) || (amd64 && !gccgo && !noasm && !appengine) -// +build 386,!gccgo,!noasm,!appengine amd64,!gccgo,!noasm,!appengine package cpuid @@ -36,6 +35,10 @@ func addInfo(c *CPUInfo, safe bool) { c.AVX10Level = c.supportAVX10() c.cacheSize() c.frequencies() + if c.maxFunc >= 0x0A { + eax, ebx, _, edx := cpuid(0x0A) + c.PMU = parseLeaf0AH(c, eax, ebx, edx) + } } func getVectorLength() (vl, pl uint64) { return 0, 0 } diff --git a/vendor/github.com/klauspost/cpuid/v2/featureid_string.go b/vendor/github.com/klauspost/cpuid/v2/featureid_string.go index 07704351faf..f88ead13080 100644 --- a/vendor/github.com/klauspost/cpuid/v2/featureid_string.go +++ b/vendor/github.com/klauspost/cpuid/v2/featureid_string.go @@ -29,226 +29,292 @@ func _() { _ = x[AVX2-19] _ = x[AVX512BF16-20] _ = x[AVX512BITALG-21] - _ = x[AVX512BW-22] - _ = x[AVX512CD-23] - _ = x[AVX512DQ-24] - _ = x[AVX512ER-25] - _ = x[AVX512F-26] - _ = x[AVX512FP16-27] - _ = x[AVX512IFMA-28] - _ = x[AVX512PF-29] - _ = x[AVX512VBMI-30] - _ = x[AVX512VBMI2-31] - _ = x[AVX512VL-32] - _ = x[AVX512VNNI-33] - _ = x[AVX512VP2INTERSECT-34] - _ = x[AVX512VPOPCNTDQ-35] - _ = x[AVXIFMA-36] - _ = x[AVXNECONVERT-37] - _ = x[AVXSLOW-38] - _ = x[AVXVNNI-39] - _ = x[AVXVNNIINT8-40] - _ = x[AVXVNNIINT16-41] - _ = x[BHI_CTRL-42] - _ = x[BMI1-43] - _ = x[BMI2-44] - _ = x[CETIBT-45] - _ = x[CETSS-46] - _ = x[CLDEMOTE-47] - _ = x[CLMUL-48] - _ = x[CLZERO-49] - _ = x[CMOV-50] - _ = x[CMPCCXADD-51] - _ = x[CMPSB_SCADBS_SHORT-52] - _ = x[CMPXCHG8-53] - _ = x[CPBOOST-54] - _ = x[CPPC-55] - _ = x[CX16-56] - _ = x[EFER_LMSLE_UNS-57] - _ = x[ENQCMD-58] - _ = x[ERMS-59] - _ = x[F16C-60] - _ = x[FLUSH_L1D-61] - _ = x[FMA3-62] - _ = x[FMA4-63] - _ = x[FP128-64] - _ = x[FP256-65] - _ = x[FSRM-66] - _ = x[FXSR-67] - _ = x[FXSROPT-68] - _ = x[GFNI-69] - _ = x[HLE-70] - _ = x[HRESET-71] - _ = x[HTT-72] - _ = x[HWA-73] - _ = x[HYBRID_CPU-74] - _ = x[HYPERVISOR-75] - _ = x[IA32_ARCH_CAP-76] - _ = x[IA32_CORE_CAP-77] - _ = x[IBPB-78] - _ = x[IBPB_BRTYPE-79] - _ = x[IBRS-80] - _ = x[IBRS_PREFERRED-81] - _ = x[IBRS_PROVIDES_SMP-82] - _ = x[IBS-83] - _ = x[IBSBRNTRGT-84] - _ = x[IBSFETCHSAM-85] - _ = x[IBSFFV-86] - _ = x[IBSOPCNT-87] - _ = x[IBSOPCNTEXT-88] - _ = x[IBSOPSAM-89] - _ = x[IBSRDWROPCNT-90] - _ = x[IBSRIPINVALIDCHK-91] - _ = x[IBS_FETCH_CTLX-92] - _ = x[IBS_OPDATA4-93] - _ = x[IBS_OPFUSE-94] - _ = x[IBS_PREVENTHOST-95] - _ = x[IBS_ZEN4-96] - _ = x[IDPRED_CTRL-97] - _ = x[INT_WBINVD-98] - _ = x[INVLPGB-99] - _ = x[KEYLOCKER-100] - _ = x[KEYLOCKERW-101] - _ = x[LAHF-102] - _ = x[LAM-103] - _ = x[LBRVIRT-104] - _ = x[LZCNT-105] - _ = x[MCAOVERFLOW-106] - _ = x[MCDT_NO-107] - _ = x[MCOMMIT-108] - _ = x[MD_CLEAR-109] - _ = x[MMX-110] - _ = x[MMXEXT-111] - _ = x[MOVBE-112] - _ = x[MOVDIR64B-113] - _ = x[MOVDIRI-114] - _ = x[MOVSB_ZL-115] - _ = x[MOVU-116] - _ = x[MPX-117] - _ = x[MSRIRC-118] - _ = x[MSRLIST-119] - _ = x[MSR_PAGEFLUSH-120] - _ = x[NRIPS-121] - _ = x[NX-122] - _ = x[OSXSAVE-123] - _ = x[PCONFIG-124] - _ = x[POPCNT-125] - _ = x[PPIN-126] - _ = x[PREFETCHI-127] - _ = x[PSFD-128] - _ = x[RDPRU-129] - _ = x[RDRAND-130] - _ = x[RDSEED-131] - _ = x[RDTSCP-132] - _ = x[RRSBA_CTRL-133] - _ = x[RTM-134] - _ = x[RTM_ALWAYS_ABORT-135] - _ = x[SBPB-136] - _ = x[SERIALIZE-137] - _ = x[SEV-138] - _ = x[SEV_64BIT-139] - _ = x[SEV_ALTERNATIVE-140] - _ = x[SEV_DEBUGSWAP-141] - _ = x[SEV_ES-142] - _ = x[SEV_RESTRICTED-143] - _ = x[SEV_SNP-144] - _ = x[SGX-145] - _ = x[SGXLC-146] - _ = x[SHA-147] - _ = x[SME-148] - _ = x[SME_COHERENT-149] - _ = x[SM3_X86-150] - _ = x[SM4_X86-151] - _ = x[SPEC_CTRL_SSBD-152] - _ = x[SRBDS_CTRL-153] - _ = x[SRSO_MSR_FIX-154] - _ = x[SRSO_NO-155] - _ = x[SRSO_USER_KERNEL_NO-156] - _ = x[SSE-157] - _ = x[SSE2-158] - _ = x[SSE3-159] - _ = x[SSE4-160] - _ = x[SSE42-161] - _ = x[SSE4A-162] - _ = x[SSSE3-163] - _ = x[STIBP-164] - _ = x[STIBP_ALWAYSON-165] - _ = x[STOSB_SHORT-166] - _ = x[SUCCOR-167] - _ = x[SVM-168] - _ = x[SVMDA-169] - _ = x[SVMFBASID-170] - _ = x[SVML-171] - _ = x[SVMNP-172] - _ = x[SVMPF-173] - _ = x[SVMPFT-174] - _ = x[SYSCALL-175] - _ = x[SYSEE-176] - _ = x[TBM-177] - _ = x[TDX_GUEST-178] - _ = x[TLB_FLUSH_NESTED-179] - _ = x[TME-180] - _ = x[TOPEXT-181] - _ = x[TSCRATEMSR-182] - _ = x[TSXLDTRK-183] - _ = x[VAES-184] - _ = x[VMCBCLEAN-185] - _ = x[VMPL-186] - _ = x[VMSA_REGPROT-187] - _ = x[VMX-188] - _ = x[VPCLMULQDQ-189] - _ = x[VTE-190] - _ = x[WAITPKG-191] - _ = x[WBNOINVD-192] - _ = x[WRMSRNS-193] - _ = x[X87-194] - _ = x[XGETBV1-195] - _ = x[XOP-196] - _ = x[XSAVE-197] - _ = x[XSAVEC-198] - _ = x[XSAVEOPT-199] - _ = x[XSAVES-200] - _ = x[AESARM-201] - _ = x[ARMCPUID-202] - _ = x[ASIMD-203] - _ = x[ASIMDDP-204] - _ = x[ASIMDHP-205] - _ = x[ASIMDRDM-206] - _ = x[ATOMICS-207] - _ = x[CRC32-208] - _ = x[DCPOP-209] - _ = x[EVTSTRM-210] - _ = x[FCMA-211] - _ = x[FHM-212] - _ = x[FP-213] - _ = x[FPHP-214] - _ = x[GPA-215] - _ = x[JSCVT-216] - _ = x[LRCPC-217] - _ = x[PMULL-218] - _ = x[RNDR-219] - _ = x[TLB-220] - _ = x[TS-221] - _ = x[SHA1-222] - _ = x[SHA2-223] - _ = x[SHA3-224] - _ = x[SHA512-225] - _ = x[SM3-226] - _ = x[SM4-227] - _ = x[SVE-228] - _ = x[lastID-229] + _ = x[AVX512BMM-22] + _ = x[AVX512BW-23] + _ = x[AVX512CD-24] + _ = x[AVX512DQ-25] + _ = x[AVX512ER-26] + _ = x[AVX512F-27] + _ = x[AVX512FP16-28] + _ = x[AVX512IFMA-29] + _ = x[AVX512PF-30] + _ = x[AVX512VBMI-31] + _ = x[AVX512VBMI2-32] + _ = x[AVX512VL-33] + _ = x[AVX512VNNI-34] + _ = x[AVX512VP2INTERSECT-35] + _ = x[AVX512VPOPCNTDQ-36] + _ = x[AVXIFMA-37] + _ = x[AVXNECONVERT-38] + _ = x[AVXSLOW-39] + _ = x[AVXVNNI-40] + _ = x[AVXVNNIINT8-41] + _ = x[AVXVNNIINT16-42] + _ = x[BHI_CTRL-43] + _ = x[BMI1-44] + _ = x[BMI2-45] + _ = x[CETIBT-46] + _ = x[CETSS-47] + _ = x[CLDEMOTE-48] + _ = x[CLMUL-49] + _ = x[CLZERO-50] + _ = x[CMOV-51] + _ = x[CMPCCXADD-52] + _ = x[CMPSB_SCADBS_SHORT-53] + _ = x[CMPXCHG8-54] + _ = x[CPBOOST-55] + _ = x[CPPC-56] + _ = x[CX16-57] + _ = x[EFER_LMSLE_UNS-58] + _ = x[ENQCMD-59] + _ = x[ERMS-60] + _ = x[F16C-61] + _ = x[FLUSH_L1D-62] + _ = x[FMA3-63] + _ = x[FMA4-64] + _ = x[FP128-65] + _ = x[FP256-66] + _ = x[FRED-67] + _ = x[FSRM-68] + _ = x[FXSR-69] + _ = x[FXSROPT-70] + _ = x[GFNI-71] + _ = x[HLE-72] + _ = x[HRESET-73] + _ = x[HTT-74] + _ = x[HWA-75] + _ = x[HYBRID_CPU-76] + _ = x[HYPERVISOR-77] + _ = x[IA32_ARCH_CAP-78] + _ = x[IA32_CORE_CAP-79] + _ = x[IBPB-80] + _ = x[IBPB_BRTYPE-81] + _ = x[IBRS-82] + _ = x[IBRS_PREFERRED-83] + _ = x[IBRS_PROVIDES_SMP-84] + _ = x[IBS-85] + _ = x[IBSBRNTRGT-86] + _ = x[IBSFETCHSAM-87] + _ = x[IBSFFV-88] + _ = x[IBSOPCNT-89] + _ = x[IBSOPCNTEXT-90] + _ = x[IBSOPSAM-91] + _ = x[IBSRDWROPCNT-92] + _ = x[IBSRIPINVALIDCHK-93] + _ = x[IBS_FETCH_CTLX-94] + _ = x[IBS_OPDATA4-95] + _ = x[IBS_OPFUSE-96] + _ = x[IBS_PREVENTHOST-97] + _ = x[IBS_ZEN4-98] + _ = x[IDPRED_CTRL-99] + _ = x[INT_WBINVD-100] + _ = x[INVLPGB-101] + _ = x[KEYLOCKER-102] + _ = x[KEYLOCKERW-103] + _ = x[LAHF-104] + _ = x[LAM-105] + _ = x[LBRVIRT-106] + _ = x[LZCNT-107] + _ = x[MCAOVERFLOW-108] + _ = x[MCDT_NO-109] + _ = x[MCOMMIT-110] + _ = x[MD_CLEAR-111] + _ = x[MMX-112] + _ = x[MMXEXT-113] + _ = x[MOVBE-114] + _ = x[MOVDIR64B-115] + _ = x[MOVDIRI-116] + _ = x[MOVSB_ZL-117] + _ = x[MOVU-118] + _ = x[MPX-119] + _ = x[MSRIRC-120] + _ = x[MSRLIST-121] + _ = x[MSR_PAGEFLUSH-122] + _ = x[NRIPS-123] + _ = x[NX-124] + _ = x[OSXSAVE-125] + _ = x[PCONFIG-126] + _ = x[POPCNT-127] + _ = x[PPIN-128] + _ = x[PREFETCHI-129] + _ = x[PSFD-130] + _ = x[RDPRU-131] + _ = x[RDRAND-132] + _ = x[RDSEED-133] + _ = x[RDTSCP-134] + _ = x[RRSBA_CTRL-135] + _ = x[RTM-136] + _ = x[RTM_ALWAYS_ABORT-137] + _ = x[SBPB-138] + _ = x[SERIALIZE-139] + _ = x[SEV-140] + _ = x[SEV_64BIT-141] + _ = x[SEV_ALTERNATIVE-142] + _ = x[SEV_DEBUGSWAP-143] + _ = x[SEV_ES-144] + _ = x[SEV_RESTRICTED-145] + _ = x[SEV_SNP-146] + _ = x[SGX-147] + _ = x[SGXLC-148] + _ = x[SGXPQC-149] + _ = x[SHA-150] + _ = x[SME-151] + _ = x[SME_COHERENT-152] + _ = x[SM3_X86-153] + _ = x[SM4_X86-154] + _ = x[SPEC_CTRL_SSBD-155] + _ = x[SRBDS_CTRL-156] + _ = x[SRSO_MSR_FIX-157] + _ = x[SRSO_NO-158] + _ = x[SRSO_USER_KERNEL_NO-159] + _ = x[SSE-160] + _ = x[SSE2-161] + _ = x[SSE3-162] + _ = x[SSE4-163] + _ = x[SSE42-164] + _ = x[SSE4A-165] + _ = x[SSSE3-166] + _ = x[STIBP-167] + _ = x[STIBP_ALWAYSON-168] + _ = x[STOSB_SHORT-169] + _ = x[SUCCOR-170] + _ = x[SVM-171] + _ = x[SVMDA-172] + _ = x[SVMFBASID-173] + _ = x[SVML-174] + _ = x[SVMNP-175] + _ = x[SVMPF-176] + _ = x[SVMPFT-177] + _ = x[SYSCALL-178] + _ = x[SYSEE-179] + _ = x[TBM-180] + _ = x[TDX_GUEST-181] + _ = x[TLB_FLUSH_NESTED-182] + _ = x[TME-183] + _ = x[TOPEXT-184] + _ = x[TSA_L1_NO-185] + _ = x[TSA_SQ_NO-186] + _ = x[TSA_VERW_CLEAR-187] + _ = x[TSCRATEMSR-188] + _ = x[TSXLDTRK-189] + _ = x[VAES-190] + _ = x[VMCBCLEAN-191] + _ = x[VMPL-192] + _ = x[VMSA_REGPROT-193] + _ = x[VMX-194] + _ = x[VPCLMULQDQ-195] + _ = x[VTE-196] + _ = x[WAITPKG-197] + _ = x[WBNOINVD-198] + _ = x[WRMSRNS-199] + _ = x[X87-200] + _ = x[XGETBV1-201] + _ = x[XOP-202] + _ = x[XSAVE-203] + _ = x[XSAVEC-204] + _ = x[XSAVEOPT-205] + _ = x[XSAVES-206] + _ = x[AESARM-207] + _ = x[ARMCPUID-208] + _ = x[ASIMD-209] + _ = x[ASIMDDP-210] + _ = x[ASIMDHP-211] + _ = x[ASIMDRDM-212] + _ = x[ATOMICS-213] + _ = x[CRC32-214] + _ = x[DCPOP-215] + _ = x[EVTSTRM-216] + _ = x[FCMA-217] + _ = x[FHM-218] + _ = x[FP-219] + _ = x[FPHP-220] + _ = x[GPA-221] + _ = x[JSCVT-222] + _ = x[LRCPC-223] + _ = x[PMULL-224] + _ = x[RNDR-225] + _ = x[TLB-226] + _ = x[TS-227] + _ = x[SHA1-228] + _ = x[SHA2-229] + _ = x[SHA3-230] + _ = x[SHA512-231] + _ = x[SM3-232] + _ = x[SM4-233] + _ = x[SVE-234] + _ = x[SVE2-235] + _ = x[SB-236] + _ = x[SSBS-237] + _ = x[BTI-238] + _ = x[FLAGM2-239] + _ = x[FRINTTS-240] + _ = x[DCPODP-241] + _ = x[BF16-242] + _ = x[I8MM-243] + _ = x[WFXT-244] + _ = x[MOPS-245] + _ = x[HBC-246] + _ = x[CSSC-247] + _ = x[PMU_FIXEDCOUNTER_CYCLES-248] + _ = x[PMU_FIXEDCOUNTER_REFCYCLES-249] + _ = x[PMU_FIXEDCOUNTER_INSTRUCTIONS-250] + _ = x[PMU_FIXEDCOUNTER_TOPDOWN_SLOTS-251] + _ = x[RV_IMA-252] + _ = x[RV_C-253] + _ = x[RV_F-254] + _ = x[RV_D-255] + _ = x[RV_V-256] + _ = x[RV_ZBA-257] + _ = x[RV_ZBB-258] + _ = x[RV_ZBC-259] + _ = x[RV_ZBS-260] + _ = x[RV_ZICOND-261] + _ = x[RV_ZIHINTPAUSE-262] + _ = x[RV_ZICBOM-263] + _ = x[RV_ZICBOZ-264] + _ = x[RV_ZICBOP-265] + _ = x[RV_ZFA-266] + _ = x[RV_ZFH-267] + _ = x[RV_ZFHMIN-268] + _ = x[RV_ZTSO-269] + _ = x[RV_ZACAS-270] + _ = x[RV_ZBKB-271] + _ = x[RV_ZBKC-272] + _ = x[RV_ZBKX-273] + _ = x[RV_ZKND-274] + _ = x[RV_ZKNE-275] + _ = x[RV_ZKNH-276] + _ = x[RV_ZKSED-277] + _ = x[RV_ZKSH-278] + _ = x[RV_ZKT-279] + _ = x[RV_ZKN-280] + _ = x[RV_ZKS-281] + _ = x[RV_ZVBB-282] + _ = x[RV_ZVBC-283] + _ = x[RV_ZVKB-284] + _ = x[RV_ZVKG-285] + _ = x[RV_ZVKNED-286] + _ = x[RV_ZVKNHA-287] + _ = x[RV_ZVKNHB-288] + _ = x[RV_ZVKSED-289] + _ = x[RV_ZVKSH-290] + _ = x[RV_ZVKT-291] + _ = x[RV_ZVKNG-292] + _ = x[RV_ZVKSG-293] + _ = x[lastID-294] _ = x[firstID-0] } -const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXFP8AMXTILEAMXTF32AMXCOMPLEXAMXTRANSPOSEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSM3_X86SM4_X86SPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFHMFPFPHPGPAJSCVTLRCPCPMULLRNDRTLBTSSHA1SHA2SHA3SHA512SM3SM4SVElastID" +const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXFP8AMXTILEAMXTF32AMXCOMPLEXAMXTRANSPOSEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BMMAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FREDFSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSGXPQCSHASMESME_COHERENTSM3_X86SM4_X86SPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSA_L1_NOTSA_SQ_NOTSA_VERW_CLEARTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFHMFPFPHPGPAJSCVTLRCPCPMULLRNDRTLBTSSHA1SHA2SHA3SHA512SM3SM4SVESVE2SBSSBSBTIFLAGM2FRINTTSDCPODPBF16I8MMWFXTMOPSHBCCSSCPMU_FIXEDCOUNTER_CYCLESPMU_FIXEDCOUNTER_REFCYCLESPMU_FIXEDCOUNTER_INSTRUCTIONSPMU_FIXEDCOUNTER_TOPDOWN_SLOTSRV_IMARV_CRV_FRV_DRV_VRV_ZBARV_ZBBRV_ZBCRV_ZBSRV_ZICONDRV_ZIHINTPAUSERV_ZICBOMRV_ZICBOZRV_ZICBOPRV_ZFARV_ZFHRV_ZFHMINRV_ZTSORV_ZACASRV_ZBKBRV_ZBKCRV_ZBKXRV_ZKNDRV_ZKNERV_ZKNHRV_ZKSEDRV_ZKSHRV_ZKTRV_ZKNRV_ZKSRV_ZVBBRV_ZVBCRV_ZVKBRV_ZVKGRV_ZVKNEDRV_ZVKNHARV_ZVKNHBRV_ZVKSEDRV_ZVKSHRV_ZVKTRV_ZVKNGRV_ZVKSGlastID" -var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 61, 68, 75, 85, 97, 102, 105, 110, 119, 128, 137, 141, 151, 163, 171, 179, 187, 195, 202, 212, 222, 230, 240, 251, 259, 269, 287, 302, 309, 321, 328, 335, 346, 358, 366, 370, 374, 380, 385, 393, 398, 404, 408, 417, 435, 443, 450, 454, 458, 472, 478, 482, 486, 495, 499, 503, 508, 513, 517, 521, 528, 532, 535, 541, 544, 547, 557, 567, 580, 593, 597, 608, 612, 626, 643, 646, 656, 667, 673, 681, 692, 700, 712, 728, 742, 753, 763, 778, 786, 797, 807, 814, 823, 833, 837, 840, 847, 852, 863, 870, 877, 885, 888, 894, 899, 908, 915, 923, 927, 930, 936, 943, 956, 961, 963, 970, 977, 983, 987, 996, 1000, 1005, 1011, 1017, 1023, 1033, 1036, 1052, 1056, 1065, 1068, 1077, 1092, 1105, 1111, 1125, 1132, 1135, 1140, 1143, 1146, 1158, 1165, 1172, 1186, 1196, 1208, 1215, 1234, 1237, 1241, 1245, 1249, 1254, 1259, 1264, 1269, 1283, 1294, 1300, 1303, 1308, 1317, 1321, 1326, 1331, 1337, 1344, 1349, 1352, 1361, 1377, 1380, 1386, 1396, 1404, 1408, 1417, 1421, 1433, 1436, 1446, 1449, 1456, 1464, 1471, 1474, 1481, 1484, 1489, 1495, 1503, 1509, 1515, 1523, 1528, 1535, 1542, 1550, 1557, 1562, 1567, 1574, 1578, 1581, 1583, 1587, 1590, 1595, 1600, 1605, 1609, 1612, 1614, 1618, 1622, 1626, 1632, 1635, 1638, 1641, 1647} +var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 61, 68, 75, 85, 97, 102, 105, 110, 119, 128, 137, 141, 151, 163, 172, 180, 188, 196, 204, 211, 221, 231, 239, 249, 260, 268, 278, 296, 311, 318, 330, 337, 344, 355, 367, 375, 379, 383, 389, 394, 402, 407, 413, 417, 426, 444, 452, 459, 463, 467, 481, 487, 491, 495, 504, 508, 512, 517, 522, 526, 530, 534, 541, 545, 548, 554, 557, 560, 570, 580, 593, 606, 610, 621, 625, 639, 656, 659, 669, 680, 686, 694, 705, 713, 725, 741, 755, 766, 776, 791, 799, 810, 820, 827, 836, 846, 850, 853, 860, 865, 876, 883, 890, 898, 901, 907, 912, 921, 928, 936, 940, 943, 949, 956, 969, 974, 976, 983, 990, 996, 1000, 1009, 1013, 1018, 1024, 1030, 1036, 1046, 1049, 1065, 1069, 1078, 1081, 1090, 1105, 1118, 1124, 1138, 1145, 1148, 1153, 1159, 1162, 1165, 1177, 1184, 1191, 1205, 1215, 1227, 1234, 1253, 1256, 1260, 1264, 1268, 1273, 1278, 1283, 1288, 1302, 1313, 1319, 1322, 1327, 1336, 1340, 1345, 1350, 1356, 1363, 1368, 1371, 1380, 1396, 1399, 1405, 1414, 1423, 1437, 1447, 1455, 1459, 1468, 1472, 1484, 1487, 1497, 1500, 1507, 1515, 1522, 1525, 1532, 1535, 1540, 1546, 1554, 1560, 1566, 1574, 1579, 1586, 1593, 1601, 1608, 1613, 1618, 1625, 1629, 1632, 1634, 1638, 1641, 1646, 1651, 1656, 1660, 1663, 1665, 1669, 1673, 1677, 1683, 1686, 1689, 1692, 1696, 1698, 1702, 1705, 1711, 1718, 1724, 1728, 1732, 1736, 1740, 1743, 1747, 1770, 1796, 1825, 1855, 1861, 1865, 1869, 1873, 1877, 1883, 1889, 1895, 1901, 1910, 1924, 1933, 1942, 1951, 1957, 1963, 1972, 1979, 1987, 1994, 2001, 2008, 2015, 2022, 2029, 2037, 2044, 2050, 2056, 2062, 2069, 2076, 2083, 2090, 2099, 2108, 2117, 2126, 2134, 2141, 2149, 2157, 2163} func (i FeatureID) String() string { - if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_FeatureID_index)-1 { return "FeatureID(" + strconv.FormatInt(int64(i), 10) + ")" } - return _FeatureID_name[_FeatureID_index[i]:_FeatureID_index[i+1]] + return _FeatureID_name[_FeatureID_index[idx]:_FeatureID_index[idx+1]] } func _() { // An "invalid array index" compiler error signifies that the constant values have changed. @@ -285,16 +351,22 @@ func _() { _ = x[ACRN-28] _ = x[SRE-29] _ = x[Apple-30] - _ = x[lastVendor-31] + _ = x[SiFive-31] + _ = x[StarFive-32] + _ = x[THead-33] + _ = x[Andes-34] + _ = x[SpacemiT-35] + _ = x[lastVendor-36] } -const _Vendor_name = "VendorUnknownIntelAMDVIATransmetaNSCKVMMSVMVMwareXenHVMBhyveHygonSiSRDCAmpereARMBroadcomCaviumDECFujitsuInfineonMotorolaNVIDIAAMCCQualcommMarvellQEMUQNXACRNSREApplelastVendor" +const _Vendor_name = "VendorUnknownIntelAMDVIATransmetaNSCKVMMSVMVMwareXenHVMBhyveHygonSiSRDCAmpereARMBroadcomCaviumDECFujitsuInfineonMotorolaNVIDIAAMCCQualcommMarvellQEMUQNXACRNSREAppleSiFiveStarFiveTHeadAndesSpacemiTlastVendor" -var _Vendor_index = [...]uint8{0, 13, 18, 21, 24, 33, 36, 39, 43, 49, 55, 60, 65, 68, 71, 77, 80, 88, 94, 97, 104, 112, 120, 126, 130, 138, 145, 149, 152, 156, 159, 164, 174} +var _Vendor_index = [...]uint8{0, 13, 18, 21, 24, 33, 36, 39, 43, 49, 55, 60, 65, 68, 71, 77, 80, 88, 94, 97, 104, 112, 120, 126, 130, 138, 145, 149, 152, 156, 159, 164, 170, 178, 183, 188, 196, 206} func (i Vendor) String() string { - if i < 0 || i >= Vendor(len(_Vendor_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_Vendor_index)-1 { return "Vendor(" + strconv.FormatInt(int64(i), 10) + ")" } - return _Vendor_name[_Vendor_index[i]:_Vendor_index[i+1]] + return _Vendor_name[_Vendor_index[idx]:_Vendor_index[idx+1]] } diff --git a/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go index da07522e7cb..addbfc67b8e 100644 --- a/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go @@ -126,4 +126,17 @@ func tryToFillCPUInfoFomSysctl(c *CPUInfo) { setFeature(c, SM3, "hw.optional.arm.FEAT_SM3") // SM3 instructions setFeature(c, SM4, "hw.optional.arm.FEAT_SM4") // SM4 instructions setFeature(c, SVE, "hw.optional.arm.FEAT_SVE") // Scalable Vector Extension + setFeature(c, SVE2, "hw.optional.arm.FEAT_SVE2") // Scalable Vector Extension 2 + setFeature(c, SB, "hw.optional.arm.FEAT_SB") // Speculation barrier + setFeature(c, SSBS, "hw.optional.arm.FEAT_SSBS") // Speculative Store Bypass Safe + setFeature(c, BTI, "hw.optional.arm.FEAT_BTI") // Branch Target Identification + setFeature(c, FLAGM2, "hw.optional.arm.FEAT_FlagM2") // Condition flag manipulation version 2 + setFeature(c, FRINTTS, "hw.optional.arm.FEAT_FRINTTS") // Floating-point to integer rounding + setFeature(c, DCPODP, "hw.optional.arm.FEAT_DPB2") // Data cache clean to Point of Deep Persistence + setFeature(c, BF16, "hw.optional.arm.FEAT_BF16") // BFloat16 instructions + setFeature(c, I8MM, "hw.optional.arm.FEAT_I8MM") // Int8 matrix multiplication + setFeature(c, WFXT, "hw.optional.arm.FEAT_WFxT") // WFE/WFI with timeout + setFeature(c, MOPS, "hw.optional.arm.FEAT_MOPS") // Memory copy and set instructions + setFeature(c, HBC, "hw.optional.arm.FEAT_HBC") // Hinted conditional branches + setFeature(c, CSSC, "hw.optional.arm.FEAT_CSSC") // Common short sequence compression } diff --git a/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go index d96d24438b3..ea9da404c67 100644 --- a/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go @@ -115,15 +115,19 @@ const ( hwcap2_POE = 1 << 63 ) +// hwcap2 holds AT_HWCAP2. Unlike hwcap, the arm64 runtime does not expose it +// through internal/cpu, so detectOS reads it from the auxiliary vector. +var hwcap2 uint + func detectOS(c *CPUInfo) bool { // For now assuming no hyperthreading is reasonable. c.LogicalCores = runtime.NumCPU() c.PhysicalCores = c.LogicalCores c.ThreadsPerCore = 1 - if hwcap == 0 { - // We did not get values from the runtime. - // Try reading /proc/self/auxv - + // hwcap is provided by the runtime through the internal/cpu.HWCap linkname, + // but the runtime does not expose HWCAP2 on arm64. Read the auxiliary vector + // directly to obtain hwcap2 (and hwcap when the linkname is unavailable). + if hwcap == 0 || hwcap2 == 0 { // From https://github.com/golang/sys const ( _AT_HWCAP = 16 @@ -132,37 +136,34 @@ func detectOS(c *CPUInfo) bool { uintSize = int(32 << (^uint(0) >> 63)) ) - buf, err := ioutil.ReadFile("/proc/self/auxv") - if err != nil { - // e.g. on android /proc/self/auxv is not accessible, so silently - // ignore the error and leave Initialized = false. On some - // architectures (e.g. arm64) doinit() implements a fallback - // readout and will set Initialized = true again. - return false - } - bo := binary.LittleEndian - for len(buf) >= 2*(uintSize/8) { - var tag, val uint - switch uintSize { - case 32: - tag = uint(bo.Uint32(buf[0:])) - val = uint(bo.Uint32(buf[4:])) - buf = buf[8:] - case 64: - tag = uint(bo.Uint64(buf[0:])) - val = uint(bo.Uint64(buf[8:])) - buf = buf[16:] - } - switch tag { - case _AT_HWCAP: - hwcap = val - case _AT_HWCAP2: - // Not used + // e.g. on android /proc/self/auxv is not accessible, so silently ignore + // the error and fall back to whatever the runtime provided. + if buf, err := ioutil.ReadFile("/proc/self/auxv"); err == nil { + bo := binary.LittleEndian + for len(buf) >= 2*(uintSize/8) { + var tag, val uint + switch uintSize { + case 32: + tag = uint(bo.Uint32(buf[0:])) + val = uint(bo.Uint32(buf[4:])) + buf = buf[8:] + case 64: + tag = uint(bo.Uint64(buf[0:])) + val = uint(bo.Uint64(buf[8:])) + buf = buf[16:] + } + switch tag { + case _AT_HWCAP: + hwcap = val + case _AT_HWCAP2: + hwcap2 = val + } } } - if hwcap == 0 { - return false - } + } + if hwcap == 0 { + // Nothing detected, e.g. on android or a restricted environment. + return false } // HWCap was populated by the runtime from the auxiliary vector. @@ -184,9 +185,9 @@ func detectOS(c *CPUInfo) bool { c.featureSet.setIf(isSet(hwcap, hwcap_JSCVT), JSCVT) c.featureSet.setIf(isSet(hwcap, hwcap_LRCPC), LRCPC) c.featureSet.setIf(isSet(hwcap, hwcap_PMULL), PMULL) - c.featureSet.setIf(isSet(hwcap, hwcap2_RNG), RNDR) - // c.featureSet.setIf(isSet(hwcap, hwcap_), TLB) - // c.featureSet.setIf(isSet(hwcap, hwcap_), TS) + c.featureSet.setIf(isSet(hwcap2, hwcap2_RNG), RNDR) + // TLB (FEAT_TLBIOS/TLBIRANGE) has no HWCAP bit; only detectable via ID registers. + c.featureSet.setIf(isSet(hwcap, hwcap_FLAGM), TS) c.featureSet.setIf(isSet(hwcap, hwcap_SHA1), SHA1) c.featureSet.setIf(isSet(hwcap, hwcap_SHA2), SHA2) c.featureSet.setIf(isSet(hwcap, hwcap_SHA3), SHA3) @@ -194,6 +195,21 @@ func detectOS(c *CPUInfo) bool { c.featureSet.setIf(isSet(hwcap, hwcap_SM3), SM3) c.featureSet.setIf(isSet(hwcap, hwcap_SM4), SM4) c.featureSet.setIf(isSet(hwcap, hwcap_SVE), SVE) + c.featureSet.setIf(isSet(hwcap, hwcap_SB), SB) + c.featureSet.setIf(isSet(hwcap, hwcap_SSBS), SSBS) + + // Features reported through the second hardware capability word (HWCAP2). + c.featureSet.setIf(isSet(hwcap2, hwcap2_SVE2), SVE2) + c.featureSet.setIf(isSet(hwcap2, hwcap2_BTI), BTI) + c.featureSet.setIf(isSet(hwcap2, hwcap2_FLAGM2), FLAGM2) + c.featureSet.setIf(isSet(hwcap2, hwcap2_FRINT), FRINTTS) + c.featureSet.setIf(isSet(hwcap2, hwcap2_DCPODP), DCPODP) + c.featureSet.setIf(isSet(hwcap2, hwcap2_BF16), BF16) + c.featureSet.setIf(isSet(hwcap2, hwcap2_I8MM), I8MM) + c.featureSet.setIf(isSet(hwcap2, hwcap2_WFXT), WFXT) + c.featureSet.setIf(isSet(hwcap2, hwcap2_MOPS), MOPS) + c.featureSet.setIf(isSet(hwcap2, hwcap2_HBC), HBC) + c.featureSet.setIf(isSet(hwcap2, hwcap2_CSSC), CSSC) // The Samsung S9+ kernel reports support for atomics, but not all cores // actually support them, resulting in SIGILL. See issue #28431. diff --git a/vendor/github.com/klauspost/cpuid/v2/os_linux_riscv64.go b/vendor/github.com/klauspost/cpuid/v2/os_linux_riscv64.go new file mode 100644 index 00000000000..71919a49bd6 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/v2/os_linux_riscv64.go @@ -0,0 +1,225 @@ +// Copyright (c) 2026 Klaus Post, released under MIT License. See LICENSE file. + +package cpuid + +import ( + "bufio" + "os" + "runtime" + "strconv" + "strings" + "unsafe" + + "golang.org/x/sys/unix" +) + +const __NR_riscv_hwprobe = 258 + +type riscvHWProbePair struct { + key int64 + value uint64 +} + +// Keys from linux/include/uapi/asm/hwprobe.h +const ( + riscv_hwprobe_key_mvendorid = 0 + riscv_hwprobe_key_marchid = 1 + riscv_hwprobe_key_mimpid = 2 + riscv_hwprobe_key_base_behavior = 3 + riscv_hwprobe_key_ima_ext_0 = 4 + riscv_hwprobe_key_cpuperf_0 = 5 + riscv_hwprobe_key_zicbom_block_size = 12 +) + +// Bits from linux/arch/riscv/include/uapi/asm/hwprobe.h +const ( + riscv_hwprobe_ima_fd = 1 << 0 + riscv_hwprobe_ima_c = 1 << 1 + riscv_hwprobe_ima_v = 1 << 2 + riscv_hwprobe_ext_zba = 1 << 3 + riscv_hwprobe_ext_zbb = 1 << 4 + riscv_hwprobe_ext_zbs = 1 << 5 + riscv_hwprobe_ext_zicboz = 1 << 6 + riscv_hwprobe_ext_zbc = 1 << 7 + riscv_hwprobe_ext_zbkb = 1 << 8 + riscv_hwprobe_ext_zbkc = 1 << 9 + riscv_hwprobe_ext_zbkx = 1 << 10 + riscv_hwprobe_ext_zknd = 1 << 11 + riscv_hwprobe_ext_zkne = 1 << 12 + riscv_hwprobe_ext_zknh = 1 << 13 + riscv_hwprobe_ext_zksed = 1 << 14 + riscv_hwprobe_ext_zksh = 1 << 15 + riscv_hwprobe_ext_zkt = 1 << 16 + riscv_hwprobe_ext_zvbb = 1 << 17 + riscv_hwprobe_ext_zvbc = 1 << 18 + riscv_hwprobe_ext_zvkb = 1 << 19 + riscv_hwprobe_ext_zvkg = 1 << 20 + riscv_hwprobe_ext_zvkned = 1 << 21 + riscv_hwprobe_ext_zvknha = 1 << 22 + riscv_hwprobe_ext_zvknhb = 1 << 23 + riscv_hwprobe_ext_zvksed = 1 << 24 + riscv_hwprobe_ext_zvksh = 1 << 25 + riscv_hwprobe_ext_zvkt = 1 << 26 + riscv_hwprobe_ext_zfh = 1 << 27 + riscv_hwprobe_ext_zfhmin = 1 << 28 + riscv_hwprobe_ext_zihintntl = 1 << 29 + riscv_hwprobe_ext_zvfh = 1 << 30 + riscv_hwprobe_ext_zvfhmin = 1 << 31 + riscv_hwprobe_ext_zfa = 1 << 32 + riscv_hwprobe_ext_ztso = 1 << 33 + riscv_hwprobe_ext_zacas = 1 << 34 + riscv_hwprobe_ext_zicond = 1 << 35 + riscv_hwprobe_ext_zihintpause = 1 << 36 + riscv_hwprobe_ext_zicbom = 1 << 55 + riscv_hwprobe_ext_zicbop = 1 << 60 +) + +func riscvHWProbe(pairs []riscvHWProbePair) int64 { + if len(pairs) == 0 { + return -1 + } + ret, _, _ := unix.Syscall6(__NR_riscv_hwprobe, + uintptr(unsafe.Pointer(&pairs[0])), + uintptr(len(pairs)), + 0, 0, 0, 0) + return int64(ret) +} + +func detectOS(c *CPUInfo) bool { + c.LogicalCores = runtime.NumCPU() + c.PhysicalCores = c.LogicalCores + c.ThreadsPerCore = 1 + + pairs := []riscvHWProbePair{ + {key: riscv_hwprobe_key_mvendorid}, + {key: riscv_hwprobe_key_marchid}, + {key: riscv_hwprobe_key_mimpid}, + {key: riscv_hwprobe_key_ima_ext_0}, + {key: riscv_hwprobe_key_zicbom_block_size}, + } + ret := riscvHWProbe(pairs) + if ret == 0 && pairs[3].value != ^uint64(0) { + detectFromHWProbe(c, pairs) + if pairs[4].value != ^uint64(0) && pairs[4].value > 0 { + c.CacheLine = int(pairs[4].value) + } + return true + } + + c.CacheLine = detectCacheLine() + return detectFromCPUInfo(c) +} + +func detectFromHWProbe(c *CPUInfo, pairs []riscvHWProbePair) { + if pairs[0].value != ^uint64(0) { + c.VendorID = riscvVendorID(pairs[0].value) + c.VendorString = c.VendorID.String() + } + if pairs[1].value != ^uint64(0) { + c.Model = int(pairs[1].value) + } + if pairs[2].value != ^uint64(0) { + c.Family = int(pairs[2].value) + } + + imaExt := pairs[3].value + + if imaExt&riscv_hwprobe_ima_fd != 0 { + c.featureSet.set(RV_D) + c.featureSet.set(RV_F) + } + c.featureSet.setIf(imaExt&riscv_hwprobe_ima_c != 0, RV_C) + c.featureSet.setIf(imaExt&riscv_hwprobe_ima_v != 0, RV_V) + + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zba != 0, RV_ZBA) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zbb != 0, RV_ZBB) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zbc != 0, RV_ZBC) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zbs != 0, RV_ZBS) + + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zicbom != 0, RV_ZICBOM) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zicboz != 0, RV_ZICBOZ) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zicbop != 0, RV_ZICBOP) + + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zicond != 0, RV_ZICOND) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zihintpause != 0, RV_ZIHINTPAUSE) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zfa != 0, RV_ZFA) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zfh != 0, RV_ZFH) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zfhmin != 0, RV_ZFHMIN) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_ztso != 0, RV_ZTSO) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zacas != 0, RV_ZACAS) + + // Scalar cryptography + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zbkb != 0, RV_ZBKB) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zbkc != 0, RV_ZBKC) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zbkx != 0, RV_ZBKX) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zknd != 0, RV_ZKND) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zkne != 0, RV_ZKNE) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zknh != 0, RV_ZKNH) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zksed != 0, RV_ZKSED) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zksh != 0, RV_ZKSH) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zkt != 0, RV_ZKT) + + // Vector cryptography + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvbb != 0, RV_ZVBB) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvbc != 0, RV_ZVBC) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvkb != 0, RV_ZVKB) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvkg != 0, RV_ZVKG) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvkned != 0, RV_ZVKNED) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvknha != 0, RV_ZVKNHA) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvknhb != 0, RV_ZVKNHB) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvksed != 0, RV_ZVKSED) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvksh != 0, RV_ZVKSH) + c.featureSet.setIf(imaExt&riscv_hwprobe_ext_zvkt != 0, RV_ZVKT) + + // Crypto suites (combined from individual features) + c.featureSet.setIf(c.featureSet.hasSetP(rvZKNFeatures), RV_ZKN) + c.featureSet.setIf(c.featureSet.hasSetP(rvZKSFeatures), RV_ZKS) + c.featureSet.setIf(c.featureSet.hasSetP(rvZVKNFeatures), RV_ZVKNG) + c.featureSet.setIf(c.featureSet.hasSetP(rvZVKSFeatures), RV_ZVKSG) + + // Every Linux-capable riscv64 core has I, M, A base. + c.featureSet.set(RV_IMA) +} + +func detectFromCPUInfo(c *CPUInfo) bool { + f, err := os.Open("/proc/cpuinfo") + if err != nil { + return false + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + fields := strings.SplitN(line, ":", 2) + if len(fields) < 2 { + continue + } + key := strings.TrimSpace(fields[0]) + value := strings.TrimSpace(fields[1]) + + switch key { + case "isa": + parseISAString(c, value) + case "mvendorid": + if vid, err := strconv.ParseUint(value, 0, 64); err == nil { + c.VendorID = riscvVendorID(vid) + c.VendorString = c.VendorID.String() + } + case "uarch": + c.BrandName = value + } + } + return scanner.Err() == nil +} + +func detectCacheLine() int { + data, err := os.ReadFile("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size") + if err != nil { + return 0 + } + if n, err := strconv.Atoi(strings.TrimSpace(string(data))); err == nil && n > 0 { + return n + } + return 0 +} diff --git a/vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go index 8733ba34363..debc123922e 100644 --- a/vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go @@ -1,7 +1,6 @@ // Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file. //go:build arm64 && !linux && !darwin -// +build arm64,!linux,!darwin package cpuid diff --git a/vendor/github.com/klauspost/cpuid/v2/os_other_riscv64.go b/vendor/github.com/klauspost/cpuid/v2/os_other_riscv64.go new file mode 100644 index 00000000000..fd86f7d0562 --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/v2/os_other_riscv64.go @@ -0,0 +1,14 @@ +// Copyright (c) 2026 Klaus Post, released under MIT License. See LICENSE file. + +//go:build riscv64 && !linux + +package cpuid + +import "runtime" + +func detectOS(c *CPUInfo) bool { + c.PhysicalCores = runtime.NumCPU() + c.ThreadsPerCore = 1 + c.LogicalCores = c.PhysicalCores + return false +} diff --git a/vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go index f8f201b5f7b..5b4e8a1b3e0 100644 --- a/vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go @@ -1,7 +1,6 @@ // Copyright (c) 2021 Klaus Post, released under MIT License. See LICENSE file. //go:build nounsafe -// +build nounsafe package cpuid diff --git a/vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go index 92af622eb8c..00158c21c39 100644 --- a/vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go @@ -1,7 +1,6 @@ // Copyright (c) 2021 Klaus Post, released under MIT License. See LICENSE file. //go:build !nounsafe -// +build !nounsafe package cpuid diff --git a/vendor/github.com/klauspost/cpuid/v2/riscv_isa.go b/vendor/github.com/klauspost/cpuid/v2/riscv_isa.go new file mode 100644 index 00000000000..5a87679bdbd --- /dev/null +++ b/vendor/github.com/klauspost/cpuid/v2/riscv_isa.go @@ -0,0 +1,93 @@ +// Copyright (c) 2026 Klaus Post, released under MIT License. See LICENSE file. + +package cpuid + +import "strings" + +func parseISAString(c *CPUInfo, isa string) { + isa = strings.ToLower(isa) + extMap := make(map[string]bool) + for ext := range strings.SplitSeq(isa, "_") { + ext = strings.TrimSpace(ext) + if strings.HasPrefix(ext, "rv64") { + extMap["i"] = true + for _, ch := range ext[4:] { + extMap[string(ch)] = true + } + } else if ext != "" { + extMap[ext] = true + } + } + + if extMap["g"] { + extMap["i"] = true + extMap["m"] = true + extMap["a"] = true + extMap["f"] = true + extMap["d"] = true + } + + c.featureSet.setIf(extMap["i"] && extMap["m"] && extMap["a"], RV_IMA) + c.featureSet.setIf(extMap["c"], RV_C) + c.featureSet.setIf(extMap["f"], RV_F) + c.featureSet.setIf(extMap["d"], RV_D) + c.featureSet.setIf(extMap["v"], RV_V) + c.featureSet.setIf(extMap["zihintpause"], RV_ZIHINTPAUSE) + c.featureSet.setIf(extMap["zba"], RV_ZBA) + c.featureSet.setIf(extMap["zbb"], RV_ZBB) + c.featureSet.setIf(extMap["zbc"], RV_ZBC) + c.featureSet.setIf(extMap["zbs"], RV_ZBS) + c.featureSet.setIf(extMap["zicond"], RV_ZICOND) + c.featureSet.setIf(extMap["zicbom"], RV_ZICBOM) + c.featureSet.setIf(extMap["zicboz"], RV_ZICBOZ) + c.featureSet.setIf(extMap["zicbop"], RV_ZICBOP) + c.featureSet.setIf(extMap["zfa"], RV_ZFA) + c.featureSet.setIf(extMap["zfh"], RV_ZFH) + c.featureSet.setIf(extMap["zfhmin"], RV_ZFHMIN) + c.featureSet.setIf(extMap["ztso"], RV_ZTSO) + c.featureSet.setIf(extMap["zacas"], RV_ZACAS) + + // Scalar cryptography + c.featureSet.setIf(extMap["zbkb"], RV_ZBKB) + c.featureSet.setIf(extMap["zbkc"], RV_ZBKC) + c.featureSet.setIf(extMap["zbkx"], RV_ZBKX) + c.featureSet.setIf(extMap["zknd"], RV_ZKND) + c.featureSet.setIf(extMap["zkne"], RV_ZKNE) + c.featureSet.setIf(extMap["zknh"], RV_ZKNH) + c.featureSet.setIf(extMap["zksed"], RV_ZKSED) + c.featureSet.setIf(extMap["zksh"], RV_ZKSH) + c.featureSet.setIf(extMap["zkt"], RV_ZKT) + + // Vector cryptography + c.featureSet.setIf(extMap["zvbb"], RV_ZVBB) + c.featureSet.setIf(extMap["zvbc"], RV_ZVBC) + c.featureSet.setIf(extMap["zvkb"], RV_ZVKB) + c.featureSet.setIf(extMap["zvkg"], RV_ZVKG) + c.featureSet.setIf(extMap["zvkned"], RV_ZVKNED) + c.featureSet.setIf(extMap["zvknha"], RV_ZVKNHA) + c.featureSet.setIf(extMap["zvknhb"], RV_ZVKNHB) + c.featureSet.setIf(extMap["zvksed"], RV_ZVKSED) + c.featureSet.setIf(extMap["zvksh"], RV_ZVKSH) + c.featureSet.setIf(extMap["zvkt"], RV_ZVKT) + + // Crypto suites (combined from individual features or bundle tokens) + c.featureSet.setIf(extMap["zkn"] || c.featureSet.hasSetP(rvZKNFeatures), RV_ZKN) + c.featureSet.setIf(extMap["zks"] || c.featureSet.hasSetP(rvZKSFeatures), RV_ZKS) + c.featureSet.setIf(extMap["zvkng"] || c.featureSet.hasSetP(rvZVKNFeatures), RV_ZVKNG) + c.featureSet.setIf(extMap["zvksg"] || c.featureSet.hasSetP(rvZVKSFeatures), RV_ZVKSG) +} + +var riscvVendorMap = map[uint64]Vendor{ + 0x489: SiFive, + 0x5b7: StarFive, + 0x5b1: THead, + 0x31e: Andes, + 0x710: SpacemiT, +} + +func riscvVendorID(mvendorid uint64) Vendor { + if v, ok := riscvVendorMap[mvendorid]; ok { + return v + } + return VendorUnknown +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go index 2df7b8598a1..426a409ca41 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -5,13 +5,13 @@ package colorable import ( "bytes" + syscall "golang.org/x/sys/windows" "io" "math" "os" "strconv" "strings" "sync" - syscall "golang.org/x/sys/windows" "unsafe" "github.com/mattn/go-isatty" @@ -93,6 +93,7 @@ type writer struct { handle syscall.Handle althandle syscall.Handle oldattr word + curattr word oldpos coord rest bytes.Buffer mutex sync.Mutex @@ -112,7 +113,7 @@ func NewColorable(file *os.File) io.Writer { var csbi consoleScreenBufferInfo handle := syscall.Handle(file.Fd()) procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} + return &writer{out: file, handle: handle, oldattr: csbi.attributes, curattr: csbi.attributes, oldpos: coord{0, 0}} } return file } @@ -438,7 +439,11 @@ func (w *writer) Write(data []byte) (n int, err error) { w.mutex.Lock() defer w.mutex.Unlock() var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + + if w.rest.Len() == 0 && bytes.IndexByte(data, 0x1b) == -1 { + w.out.Write(data) + return len(data), nil + } handle := w.handle @@ -517,7 +522,7 @@ loop: w.rest.Reset() break } - buf.Write([]byte(string(c))) + buf.WriteByte(c) } if m == 0 { break loop @@ -678,11 +683,11 @@ loop: procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) case 'm': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - attr := csbi.attributes + attr := w.curattr cs := buf.String() if cs == "" { procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr)) + w.curattr = w.oldattr continue } token := strings.Split(cs, ";") @@ -814,9 +819,12 @@ loop: attr |= backgroundBlue } } - procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) } } + if attr != w.curattr { + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) + w.curattr = attr + } case 'h': var ci consoleCursorInfo cs := buf.String() @@ -834,6 +842,8 @@ loop: w.althandle = syscall.Handle(h) if w.althandle != 0 { handle = w.althandle + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.curattr = csbi.attributes } } } @@ -853,6 +863,8 @@ loop: syscall.CloseHandle(w.althandle) w.althandle = 0 handle = w.handle + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.curattr = csbi.attributes } } case 's': diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 7402e0618aa..b24a2fadc9c 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,5 +1,5 @@ -//go:build (appengine || js || nacl || tinygo || wasm) && !windows -// +build appengine js nacl tinygo wasm +//go:build (appengine || js || nacl || tinygo || wasm || wasip1 || wasip2) && !windows +// +build appengine js nacl tinygo wasm wasip1 wasip2 // +build !windows package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go index 8e3c99171bf..5f29c11dd25 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_windows.go +++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go @@ -31,6 +31,10 @@ func init() { if procGetFileInformationByHandleEx.Find() != nil { procGetFileInformationByHandleEx = nil } + // Check if NtQueryObject is available. + if procNtQueryObject.Find() != nil { + procNtQueryObject = nil + } } // IsTerminal return true if the file descriptor is terminal. @@ -43,6 +47,7 @@ func IsTerminal(fd uintptr) bool { // Check pipe name is used for cygwin/msys2 pty. // Cygwin/MSYS2 PTY has a name like: // \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master +// On Windows 7 a trailing suffix (e.g. "-nat") may be appended. func isCygwinPipeName(name string) bool { token := strings.Split(name, "-") if len(token) < 5 { @@ -72,13 +77,19 @@ func isCygwinPipeName(name string) bool { return false } + for _, t := range token[5:] { + if t == "" { + return false + } + } + return true } -// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler +// getFileNameByHandle use the undocumented ntdll NtQueryObject to get file full name from file handler // since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion // guys are using Windows XP, this is a workaround for those guys, it will also work on system from -// Windows vista to 10 +// Windows Vista to 10 // see https://stackoverflow.com/a/18792477 for details func getFileNameByHandle(fd uintptr) (string, error) { if procNtQueryObject == nil { diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md index 2a7d8c265bf..8dc2472360b 100644 --- a/vendor/github.com/miekg/dns/README.md +++ b/vendor/github.com/miekg/dns/README.md @@ -6,7 +6,12 @@ DNS version 2 is now available at , check it out if you want to help shape the next 15 years of the Go DNS package. -The version here will see no new features and less and less development. +The version here will see no new features and less and less development, and my time (if any) will be fully +devoted towards v2. + +**December 2025**: v2 should be (already) a good replacement, the coming months would be a good time to +migrate, see [this file describing the +differences](https://codeberg.org/miekg/dns/src/branch/main/README-diff-with-v1.md), to help you get started. # Alternative (more granular) approach to a DNS library @@ -62,7 +67,7 @@ A not-so-up-to-date-list-that-may-be-actually-current: - https://www.dnsperf.com/ - https://dnssectest.net/ - https://github.com/oif/apex -- https://github.com/jedisct1/dnscrypt-proxy +- https://github.com/jedisct1/dnscrypt-proxy (migrated to v2) - https://github.com/jedisct1/rpdns - https://github.com/xor-gate/sshfp - https://github.com/rs/dnstrace diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go index 9549fa9232b..a0f96187b41 100644 --- a/vendor/github.com/miekg/dns/client.go +++ b/vendor/github.com/miekg/dns/client.go @@ -57,8 +57,8 @@ type Client struct { // Client.Dialer) or context.Context.Deadline (see ExchangeContext) Timeout time.Duration DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero + ReadTimeout time.Duration // net.Conn.SetReadDeadline value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero + WriteTimeout time.Duration // net.Conn.SetWriteDeadline value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations. @@ -92,6 +92,9 @@ func (c *Client) dialTimeout() time.Duration { } func (c *Client) readTimeout() time.Duration { + if c.Timeout != 0 { + return c.Timeout + } if c.ReadTimeout != 0 { return c.ReadTimeout } @@ -99,6 +102,9 @@ func (c *Client) readTimeout() time.Duration { } func (c *Client) writeTimeout() time.Duration { + if c.Timeout != 0 { + return c.Timeout + } if c.WriteTimeout != 0 { return c.WriteTimeout } diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go index edf18596199..382a8083875 100644 --- a/vendor/github.com/miekg/dns/msg.go +++ b/vendor/github.com/miekg/dns/msg.go @@ -338,11 +338,13 @@ loop: return off + 2, nil } + // Trailing root label if off < len(msg) { msg[off] = 0 + return off + 1, nil } - return off + 1, nil + return off, ErrBuf } // isRootLabel returns whether s or bs, from off to end, is the root diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go index 31957b2ea0d..f7c6525dd0f 100644 --- a/vendor/github.com/miekg/dns/scan.go +++ b/vendor/github.com/miekg/dns/scan.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/fs" + "math" "os" "path" "path/filepath" @@ -1231,7 +1232,7 @@ func typeToInt(token string) (uint16, bool) { // stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds. func stringToTTL(token string) (uint32, bool) { - var s, i uint32 + var s, i uint for _, c := range token { switch c { case 's', 'S': @@ -1251,12 +1252,15 @@ func stringToTTL(token string) (uint32, bool) { i = 0 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': i *= 10 - i += uint32(c) - '0' + i += uint(c) - '0' default: return 0, false } } - return s + i, true + if s+i > math.MaxUint32 { + return 0, false + } + return uint32(s + i), true } // Parse LOC records' [.][mM] into a diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go index c53a63d7c8b..33cb83e5ac8 100644 --- a/vendor/github.com/miekg/dns/version.go +++ b/vendor/github.com/miekg/dns/version.go @@ -3,7 +3,7 @@ package dns import "fmt" // Version is current version of this library. -var Version = v{1, 1, 69} +var Version = v{1, 1, 72} // v holds the version of this library. type v struct { diff --git a/vendor/github.com/minio/minio-go/v7/.gitignore b/vendor/github.com/minio/minio-go/v7/.gitignore index 5bb12e74afb..39f4bee7a61 100644 --- a/vendor/github.com/minio/minio-go/v7/.gitignore +++ b/vendor/github.com/minio/minio-go/v7/.gitignore @@ -5,3 +5,4 @@ golangci-lint functional_tests .idea vendor/ +.branch-validate/ diff --git a/vendor/github.com/minio/minio-go/v7/api-bucket-policy.go b/vendor/github.com/minio/minio-go/v7/api-bucket-policy.go index 0e561bdfab2..c4b768cec9f 100644 --- a/vendor/github.com/minio/minio-go/v7/api-bucket-policy.go +++ b/vendor/github.com/minio/minio-go/v7/api-bucket-policy.go @@ -1,6 +1,6 @@ /* * MinIO Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2020 MinIO, Inc. + * Copyright 2026 MinIO, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -18,14 +18,44 @@ package minio import ( "context" + "encoding/json" + "fmt" "io" "net/http" "net/url" "strings" + "github.com/minio/minio-go/v7/pkg/policy" "github.com/minio/minio-go/v7/pkg/s3utils" ) +// SetCannedBucketPolicy sets a canned (predefined) access policy on a bucket. +// This is a convenience method that translates predefined access levels +// (readonly, writeonly, readwrite) into the corresponding bucket policy. +// If access is empty or results in no policy statements, the existing bucket policy will be removed. +// +// Parameters: +// - ctx: Context for request cancellation and timeout +// - bucketName: Name of the bucket +// - access: Canned access level (policy.BucketPolicyNone, policy.BucketPolicyReadOnly, policy.BucketPolicyWriteOnly, policy.BucketPolicyReadWrite) +// +// Returns an error if the operation fails. +func (c *Client) SetCannedBucketPolicy(ctx context.Context, bucketName string, bucketPolicy policy.BucketPolicy) error { + if !bucketPolicy.IsValidBucketPolicy() { + return fmt.Errorf("invalid bucket policy %q", bucketPolicy) + } + p := policy.BucketAccessPolicy{Version: "2012-10-17"} + p.Statements = policy.SetPolicy(p.Statements, bucketPolicy, bucketName, "") + if len(p.Statements) == 0 { + return c.SetBucketPolicy(ctx, bucketName, "") + } + policyB, e := json.Marshal(p) + if e != nil { + return e + } + return c.SetBucketPolicy(ctx, bucketName, string(policyB)) +} + // SetBucketPolicy sets the access permissions policy on an existing bucket. // The policy should be a valid JSON string that conforms to the IAM policy format. // If policy is an empty string, the existing bucket policy will be removed. diff --git a/vendor/github.com/minio/minio-go/v7/api-compose-object.go b/vendor/github.com/minio/minio-go/v7/api-compose-object.go index 6d91bed433f..2ea833b731d 100644 --- a/vendor/github.com/minio/minio-go/v7/api-compose-object.go +++ b/vendor/github.com/minio/minio-go/v7/api-compose-object.go @@ -386,6 +386,7 @@ func (c *Client) copyObjectPartDo(ctx context.Context, srcBucket, srcObject, des return p, err } p.PartNumber, p.ETag = partID, cpObjRes.ETag + cpObjRes.setChecksums(&p) return p, nil } @@ -424,6 +425,7 @@ func (c *Client) uploadPartCopy(ctx context.Context, bucket, object, uploadID st return p, err } p.PartNumber, p.ETag = partNumber, cpObjRes.ETag + cpObjRes.setChecksums(&p) return p, nil } @@ -531,6 +533,19 @@ func (c *Client) ComposeObject(ctx context.Context, dst CopyDestOptions, srcs .. userTags = srcObjectInfos[0].UserTags } + // Set the requested checksum algorithm on the multipart upload. + if dst.ChecksumType.IsSet() { + meta := make(map[string]string, len(userMeta)+2) + for k, v := range userMeta { + meta[k] = v + } + meta[amzChecksumAlgo] = dst.ChecksumType.String() + if dst.ChecksumType.FullObjectRequested() { + meta[amzChecksumMode] = ChecksumFullObjectMode.String() + } + userMeta = meta + } + uploadID, err := c.newUploadID(ctx, dst.Bucket, dst.Object, PutObjectOptions{ ServerSideEncryption: dst.Encryption, UserMetadata: userMeta, diff --git a/vendor/github.com/minio/minio-go/v7/api-datatypes.go b/vendor/github.com/minio/minio-go/v7/api-datatypes.go index f359f29a763..2391c6e5a2f 100644 --- a/vendor/github.com/minio/minio-go/v7/api-datatypes.go +++ b/vendor/github.com/minio/minio-go/v7/api-datatypes.go @@ -184,10 +184,30 @@ type ObjectInfo struct { // eg: x-amz-meta-*, content-encoding etc. Metadata http.Header `json:"metadata" xml:"-"` - // x-amz-meta-* headers stripped "x-amz-meta-" prefix containing the first value. + // Headers is the unfiltered set of response headers from the + // HEAD or GET request that produced this ObjectInfo, e.g. + // Content-Range for ranged requests. RFC 2047-encoded + // x-amz-meta-*/x-minio-meta-* values appear MIME-decoded, matching + // Metadata. Set only when the object info is parsed from an HTTP + // object response (StatObject, GetObject); nil elsewhere, e.g. in + // ListObjects results, on error paths, or for RDMA-backed GetObject. + // It aliases the response headers and must be treated as read-only. + Headers http.Header `json:"rawHeaders,omitempty" xml:"-"` + + // UserMetadata contains x-amz-meta-* user metadata. + // StatObject and GetObject return it with the "X-Amz-Meta-" prefix + // stripped; list results with WithMetadata keep the exact values stored + // on the object (prefixed keys plus system entries such as content-type). // Only returned by MinIO servers. UserMetadata StringMap `json:"userMetadata,omitempty"` + // UserMetadataStripped is the user metadata from list results in the + // keyed form StatObject and GetObject return in UserMetadata: + // x-amz-meta-* entries with the "X-Amz-Meta-" prefix stripped and + // values passed through verbatim. + // Only populated by MinIO servers when listing with WithMetadata. + UserMetadataStripped StringMap `json:"userMetadataStripped,omitempty" xml:"-"` + // x-amz-tagging values in their k/v values. // Only returned by MinIO servers. UserTags URLMap `json:"userTags,omitempty" xml:"UserTags"` diff --git a/vendor/github.com/minio/minio-go/v7/api-get-object-file.go b/vendor/github.com/minio/minio-go/v7/api-get-object-file.go index 6ef9c9330ee..dd62b3f7c86 100644 --- a/vendor/github.com/minio/minio-go/v7/api-get-object-file.go +++ b/vendor/github.com/minio/minio-go/v7/api-get-object-file.go @@ -72,7 +72,7 @@ func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePat filePartPath := filepath.Join(filepath.Dir(filePath), sum256Hex([]byte(filepath.Base(filePath)+objectStat.ETag))+".part.minio") // If exists, open in append mode. If not create it as a part file. - filePart, err := os.OpenFile(filePartPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o600) + filePart, err := os.OpenFile(filePartPath, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0o600) if err != nil { return err } @@ -98,19 +98,41 @@ func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePat // appropriate range offsets to read from. if st.Size() > 0 { opts.SetRange(st.Size(), 0) + if opts.Checksum && objectStat.ChecksumMode == ChecksumFullObjectMode.String() { + if hasherReader := c.newChecksumVerifyingReader(objectStat); hasherReader != nil { + // Read existing file data into hash. + if _, err = io.CopyN(hasherReader.Hash, filePart, st.Size()); err != nil { + _ = hasherReader.Close() + return err + } + opts.checkSumReader = hasherReader + } + } } // Seek to current position for incoming reader. objectReader, objectStat, _, err := c.getObject(ctx, bucketName, objectName, opts) if err != nil { + if opts.checkSumReader != nil { + _ = opts.checkSumReader.Close() + } return err } + defer objectReader.Close() + // Write to the part file. if _, err = io.CopyN(filePart, objectReader, objectStat.Size); err != nil { return err } + // Verify the checksum of the downloaded object before committing the file. + if cr, ok := objectReader.(*checksumVerifyingReader); ok { + if err = cr.VerifyChecksum(); err != nil { + return err + } + } + // Close the file before rename, this is specifically needed for Windows users. closeAndRemove = false if err = filePart.Close(); err != nil { diff --git a/vendor/github.com/minio/minio-go/v7/api-get-object.go b/vendor/github.com/minio/minio-go/v7/api-get-object.go index ab783551520..d41d516a540 100644 --- a/vendor/github.com/minio/minio-go/v7/api-get-object.go +++ b/vendor/github.com/minio/minio-go/v7/api-get-object.go @@ -81,6 +81,8 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o reqCh := make(chan getRequest) // Create response channel. resCh := make(chan getResponse) + // record original range header for stat operation. + originalRangeHeader := opts.Header().Get("Range") // This routine feeds partial object data as and when the caller reads. go func() { @@ -115,6 +117,12 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o httpReader, objectInfo, _, err = c.getObject(gctx, bucketName, objectName, opts) if err != nil { resCh <- getResponse{Error: err} + // An unsatisfiable range is recoverable: the caller + // may Seek or ReadAt within bounds next, so keep + // serving requests instead of ending the stream. + if ToErrorResponse(err).Code == InvalidRange { + continue + } return } etag = objectInfo.ETag @@ -141,19 +149,35 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o // it to io.EOF - return unexpected EOF. err = io.ErrUnexpectedEOF } + // when doing a readAt, we can't reuse the httpReader for next read action. + if req.isReadAt { + httpReader.Close() + httpReader = nil + } + + objectSize := int64(0) + // case for ReadFull with range request + if !req.isReadAt && req.Offset == 0 { + objectSize = objectInfo.Size + } // Send back the first response. resCh <- getResponse{ + ObjectSize: objectSize, objectInfo: objectInfo, Size: size, Error: err, didRead: true, } } else { - // First request is a Stat or Seek call. - // Only need to run a StatObject until an actual Read or ReadAt request comes through. + if originalRangeHeader == "" { + // First request is a Seek call. + // Only need to run a StatObject until an actual Read request comes through. - // Remove range header if already set, for stat Operations to get original file size. - delete(opts.headers, "Range") + // Remove range header if already set, for stat Operations to get original file size. + delete(opts.headers, "Range") + } else { + opts.headers["Range"] = originalRangeHeader + } objectInfo, err = c.StatObject(gctx, bucketName, objectName, StatObjectOptions(opts)) if err != nil { resCh <- getResponse{ @@ -165,12 +189,17 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o etag = objectInfo.ETag // Send back the first response. resCh <- getResponse{ + ObjectSize: objectInfo.Size, objectInfo: objectInfo, } } } else if req.settingObjectInfo { // Request is just to get objectInfo. // Remove range header if already set, for stat Operations to get original file size. - delete(opts.headers, "Range") + if originalRangeHeader == "" { + delete(opts.headers, "Range") + } else { + opts.headers["Range"] = originalRangeHeader + } // Check whether this is snowball // if yes do not use If-Match feature // it doesn't work. @@ -187,16 +216,22 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o } // Send back the objectInfo. resCh <- getResponse{ + ObjectSize: objectInfo.Size, objectInfo: objectInfo, } } else { + objectSize := int64(0) + renewReader := false // Offset changes fetch the new object at an Offset. // Because the httpReader may not be set by the first // request if it was a stat or seek it must be checked // if the object has been read or not to only initialize // new ones when they haven't been already. // All readAt requests are new requests. - if req.DidOffsetChange || !req.beenRead { + // A nil httpReader means the previous fetch failed and + // left no stream, so a new one must be established + // regardless of the offset bookkeeping. + if req.DidOffsetChange || !req.beenRead || httpReader == nil { // Check whether this is snowball // if yes do not use If-Match feature // it doesn't work. @@ -214,16 +249,30 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o } else if req.Offset > 0 { // Range is set with respect to the offset. opts.SetRange(req.Offset, 0) } else { - // Remove range header if already set - delete(opts.headers, "Range") + if originalRangeHeader == "" { + delete(opts.headers, "Range") + } else { + opts.headers["Range"] = originalRangeHeader + } } httpReader, objectInfo, _, err = c.getObject(gctx, bucketName, objectName, opts) if err != nil { resCh <- getResponse{ Error: err, } + // An unsatisfiable range is recoverable: the caller + // may Seek or ReadAt within bounds next, so keep + // serving requests instead of ending the stream. + if ToErrorResponse(err).Code == InvalidRange { + continue + } return } + // case for ReadFull with range request + if !req.isReadAt && req.Offset == 0 { + objectSize = objectInfo.Size + } + renewReader = true totalRead = 0 } @@ -250,9 +299,13 @@ func (c *Client) GetObject(ctx context.Context, bucketName, objectName string, o // it to io.EOF - return unexpected EOF. err = io.ErrUnexpectedEOF } - + if renewReader && req.isReadAt { + httpReader.Close() + httpReader = nil + } // Reply back how much was read. resCh <- getResponse{ + ObjectSize: objectSize, Size: size, Error: err, didRead: true, @@ -281,6 +334,7 @@ type getRequest struct { // get response message container to reply back for the request. type getResponse struct { + ObjectSize int64 Size int Error error didRead bool // Lets subsequent calls know whether or not httpReader has been initiated. @@ -299,6 +353,7 @@ type Object struct { ctx context.Context cancel context.CancelFunc currOffset int64 + totalSize int64 objectInfo ObjectInfo // Ask lower level to initiate data fetching based on currOffset @@ -356,6 +411,10 @@ func (o *Object) doGetRequest(request getRequest) (getResponse, error) { // Data are ready on the wire, no need to reinitiate connection in lower level o.seekData = false + if response.ObjectSize != 0 { + o.totalSize = response.ObjectSize + } + return response, response.Error } @@ -365,7 +424,7 @@ func (o *Object) setOffset(bytesRead int64) error { // Update the currentOffset. o.currOffset += bytesRead - if o.objectInfo.Size > -1 && o.currOffset >= o.objectInfo.Size { + if o.totalSize > -1 && o.currOffset >= o.totalSize { return io.EOF } return nil @@ -387,6 +446,13 @@ func (o *Object) Read(b []byte) (n int, err error) { if o.prevErr != nil || o.isClosed { return 0, o.prevErr } + // If the current offset is at or beyond the known object size, there is + // nothing more to read. Return io.EOF directly instead of issuing a range + // request from EOF (which the server rejects as an unsatisfiable range). + if o.objectInfoSet && o.objectInfo.Size > -1 && o.currOffset >= o.objectInfo.Size { + o.prevErr = io.EOF + return 0, io.EOF + } // Create a new request. readReq := getRequest{ @@ -407,6 +473,14 @@ func (o *Object) Read(b []byte) (n int, err error) { // Send and receive from the first request. response, err := o.doGetRequest(readReq) if err != nil && err != io.EOF { + // An InvalidRange response to a range generated from a non-zero + // read offset means the position is at or past EOF for the object + // as it currently exists. Offset zero sends only a caller-supplied + // range, whose InvalidRange must surface untranslated. + if o.currOffset > 0 && ToErrorResponse(err).Code == InvalidRange { + o.prevErr = io.EOF + return 0, io.EOF + } // Save the error for future calls. o.prevErr = err return response.Size, err @@ -428,6 +502,8 @@ func (o *Object) Read(b []byte) (n int, err error) { } // Stat returns the ObjectInfo structure describing Object. +// When requesting a partial object or reading has started, +// the size returned will reflect the remaining size. func (o *Object) Stat() (ObjectInfo, error) { if o == nil { return ObjectInfo{}, errInvalidArgument("Object is nil") @@ -436,7 +512,24 @@ func (o *Object) Stat() (ObjectInfo, error) { o.mutex.Lock() defer o.mutex.Unlock() - if o.prevErr != nil && o.prevErr != io.EOF || o.isClosed { + if o.prevErr != nil && o.prevErr != io.EOF { + return ObjectInfo{}, o.prevErr + } + + // When the object info is already known (e.g. the RDMA GET path, whose + // payload is delivered out-of-band so the object is created closed, or a + // previously completed request) report it, even for a closed object. + if o.objectInfoSet { + if o.currOffset > o.totalSize { + return ObjectInfo{}, io.EOF + } + if o.currOffset <= o.totalSize { + o.objectInfo.Size = o.totalSize - o.currOffset + } + return o.objectInfo, nil + } + + if o.isClosed { return ObjectInfo{}, o.prevErr } @@ -452,7 +545,12 @@ func (o *Object) Stat() (ObjectInfo, error) { return ObjectInfo{}, err } } - + if o.currOffset > o.totalSize { + return ObjectInfo{}, io.EOF + } + if o.currOffset <= o.totalSize { + o.objectInfo.Size = o.totalSize - o.currOffset + } return o.objectInfo, nil } @@ -488,7 +586,7 @@ func (o *Object) ReadAt(b []byte, offset int64) (n int, err error) { if o.objectInfoSet { // If offset is negative than we return io.EOF. // If offset is greater than or equal to object size we return io.EOF. - if (o.objectInfo.Size > -1 && offset >= o.objectInfo.Size) || offset < 0 { + if (o.totalSize > -1 && offset >= o.totalSize) || offset < 0 { return 0, io.EOF } } @@ -511,6 +609,12 @@ func (o *Object) ReadAt(b []byte, offset int64) (n int, err error) { // Send and receive from the first request. response, err := o.doGetRequest(readAtReq) if err != nil && err != io.EOF { + // Reading at an offset at or beyond the object size yields + // InvalidRange from the server: report io.EOF, matching the + // io.ReaderAt contract for reads past the end. + if ToErrorResponse(err).Code == InvalidRange { + return 0, io.EOF + } // Save the error. o.prevErr = err return response.Size, err @@ -541,9 +645,10 @@ func (o *Object) ReadAt(b []byte, offset int64) (n int, err error) { // and 2 means relative to the end. // Seek returns the new offset and an error, if any. // -// Seeking to a negative offset is an error. Seeking to any positive -// offset is legal, subsequent io operations succeed until the -// underlying object is not closed. +// Seeking to a position before the start of the object is an error. +// Seeking to the end of the object is legal; the subsequent Read reports +// io.EOF. When the object size is known, seeking past the end returns +// io.EOF from Seek itself and leaves the offset unchanged. func (o *Object) Seek(offset int64, whence int) (n int64, err error) { if o == nil { return 0, errInvalidArgument("Object is nil") @@ -558,9 +663,11 @@ func (o *Object) Seek(offset int64, whence int) (n int64, err error) { return 0, o.prevErr } - // Negative offset is valid for whence of '2'. - if offset < 0 && whence != 2 { - return 0, errInvalidArgument(fmt.Sprintf("Negative position not allowed for %d", whence)) + // Negative absolute offsets are invalid for SeekStart. Negative offsets + // for SeekCurrent/SeekEnd are valid as long as the computed position is + // not before the start of the object (checked after applying whence). + if offset < 0 && whence == 0 { + return 0, errInvalidArgument("Negative position not allowed for 0") } // This is the first request. So before anything else @@ -588,31 +695,26 @@ func (o *Object) Seek(offset int64, whence int) (n int64, err error) { default: return 0, errInvalidArgument(fmt.Sprintf("Invalid whence %d", whence)) case 0: - if o.objectInfo.Size > -1 && offset > o.objectInfo.Size { - return 0, io.EOF - } newOffset = offset case 1: - if o.objectInfo.Size > -1 && o.currOffset+offset > o.objectInfo.Size { - return 0, io.EOF - } newOffset += offset case 2: // If we don't know the object size return an error for io.SeekEnd - if o.objectInfo.Size < 0 { + if o.totalSize < 0 { return 0, errInvalidArgument("Whence END is not supported when the object size is unknown") } - // Seeking to positive offset is valid for whence '2', but - // since we are backing a Reader we have reached 'EOF' if - // offset is positive. - if offset > 0 { - return 0, io.EOF - } - // Seeking to negative position not allowed for whence. - if o.objectInfo.Size+offset < 0 { - return 0, errInvalidArgument(fmt.Sprintf("Seeking at negative offset not allowed for %d", whence)) - } - newOffset = o.objectInfo.Size + offset + newOffset = o.totalSize + offset + } + // Seeking to a position before the start of the object is not allowed for + // any whence. + if newOffset < 0 { + return 0, errInvalidArgument(fmt.Sprintf("Seeking at negative offset not allowed for %d", whence)) + } + // Seeking past the end of the object is rejected with io.EOF, preserving + // long-standing behavior. Seeking to exactly the end is legal and the + // subsequent Read reports io.EOF. + if o.objectInfo.Size > -1 && newOffset > o.objectInfo.Size { + return 0, io.EOF } // Reset the saved error since we successfully seeked, let the Read // and ReadAt decide. @@ -717,6 +819,19 @@ func (c *Client) getObject(ctx context.Context, bucketName, objectName string, o return nil, ObjectInfo{}, nil, err } + body := resp.Body + if opts.Checksum { + if opts.checkSumReader != nil { + opts.checkSumReader.SetReader(resp.Body) + body = opts.checkSumReader + } else if objectStat.ChecksumMode == ChecksumFullObjectMode.String() && opts.headers["Range"] == "" { + if hasherReader := c.newChecksumVerifyingReader(objectStat); hasherReader != nil { + hasherReader.SetReader(resp.Body) + body = hasherReader + } + } + } + // do not close body here, caller will close - return resp.Body, objectStat, resp.Header, nil + return body, objectStat, resp.Header, nil } diff --git a/vendor/github.com/minio/minio-go/v7/api-get-options.go b/vendor/github.com/minio/minio-go/v7/api-get-options.go index dd82f97a132..e78235b15ad 100644 --- a/vendor/github.com/minio/minio-go/v7/api-get-options.go +++ b/vendor/github.com/minio/minio-go/v7/api-get-options.go @@ -44,10 +44,15 @@ type GetObjectOptions struct { VersionID string PartNumber int - // Include any checksums, if object was uploaded with checksum. // For multipart objects this is a checksum of part checksums. // https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + // When the response advertises a full-object checksum, un-ranged + // downloads are verified against it: reads through *Object fail with a + // checksum mismatch error at EOF, and FGetObject fails before renaming + // the file into place. Reads that stop before EOF are not verified. Checksum bool + // If not nil, continue checksum hash verification on the existing data. + checkSumReader *checksumVerifyingReader // RDMABuffer, when non-nil and Options.EnableRDMA=true, downloads directly // into a contiguous buffer via libminiocpp.so. The returned *Object's diff --git a/vendor/github.com/minio/minio-go/v7/api-list.go b/vendor/github.com/minio/minio-go/v7/api-list.go index 5e4a381790d..3e13d36ae43 100644 --- a/vendor/github.com/minio/minio-go/v7/api-list.go +++ b/vendor/github.com/minio/minio-go/v7/api-list.go @@ -127,6 +127,9 @@ func (c *Client) listObjectsV2(ctx context.Context, bucketName string, opts List // Return object owner information by default fetchOwner := true + if opts.FetchOwner != nil { + fetchOwner = *opts.FetchOwner + } return func(yield func(ObjectInfo) bool) { if contextCanceled(ctx) { @@ -296,6 +299,7 @@ func (c *Client) listObjectsV2Query(ctx context.Context, bucketName, objectPrefi return listBucketResult, err } listBucketResult.Contents[i].LastModified = listBucketResult.Contents[i].LastModified.Truncate(time.Millisecond) + listBucketResult.Contents[i].UserMetadataStripped = stripUserMetadata(obj.UserMetadata) } for i, obj := range listBucketResult.CommonPrefixes { @@ -419,31 +423,32 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts } for _, version := range vers { info := ObjectInfo{ - ETag: trimEtag(version.ETag), - Key: version.Key, - LastModified: version.LastModified.Truncate(time.Millisecond), - Size: version.Size, - Owner: version.Owner, - StorageClass: version.StorageClass, - IsLatest: version.IsLatest, - VersionID: version.VersionID, - IsDeleteMarker: version.isDeleteMarker, - UserTags: version.UserTags, - UserMetadata: version.UserMetadata, - Internal: version.Internal, - NumVersions: numVersions, - ChecksumAlgorithm: version.ChecksumAlgorithm, - ChecksumMode: version.ChecksumType, - ChecksumCRC32: version.ChecksumCRC32, - ChecksumCRC32C: version.ChecksumCRC32C, - ChecksumSHA1: version.ChecksumSHA1, - ChecksumSHA256: version.ChecksumSHA256, - ChecksumCRC64NVME: version.ChecksumCRC64NVME, - ChecksumMD5: version.ChecksumMD5, - ChecksumSHA512: version.ChecksumSHA512, - ChecksumXXHash64: version.ChecksumXXHash64, - ChecksumXXHash3: version.ChecksumXXHash3, - ChecksumXXHash128: version.ChecksumXXHash128, + ETag: trimEtag(version.ETag), + Key: version.Key, + LastModified: version.LastModified.Truncate(time.Millisecond), + Size: version.Size, + Owner: version.Owner, + StorageClass: version.StorageClass, + IsLatest: version.IsLatest, + VersionID: version.VersionID, + IsDeleteMarker: version.isDeleteMarker, + UserTags: version.UserTags, + UserMetadata: version.UserMetadata, + UserMetadataStripped: version.UserMetadataStripped, + Internal: version.Internal, + NumVersions: numVersions, + ChecksumAlgorithm: version.ChecksumAlgorithm, + ChecksumMode: version.ChecksumType, + ChecksumCRC32: version.ChecksumCRC32, + ChecksumCRC32C: version.ChecksumCRC32C, + ChecksumSHA1: version.ChecksumSHA1, + ChecksumSHA256: version.ChecksumSHA256, + ChecksumCRC64NVME: version.ChecksumCRC64NVME, + ChecksumMD5: version.ChecksumMD5, + ChecksumSHA512: version.ChecksumSHA512, + ChecksumXXHash64: version.ChecksumXXHash64, + ChecksumXXHash3: version.ChecksumXXHash3, + ChecksumXXHash128: version.ChecksumXXHash128, } if !yield(info) { return false @@ -606,6 +611,7 @@ func (c *Client) listObjectVersionsQuery(ctx context.Context, bucketName string, if err != nil { return listObjectVersionsOutput, err } + listObjectVersionsOutput.Versions[i].UserMetadataStripped = stripUserMetadata(obj.UserMetadata) } for i, obj := range listObjectVersionsOutput.CommonPrefixes { @@ -738,6 +744,10 @@ type ListObjectsOptions struct { // Use the deprecated list objects V1 API UseV1 bool + // FetchOwner indicates whether to return object owner information. + // It defaults to true when unset. + FetchOwner *bool + headers http.Header } diff --git a/vendor/github.com/minio/minio-go/v7/api-presigned.go b/vendor/github.com/minio/minio-go/v7/api-presigned.go index 29642200ee1..1591fab32b0 100644 --- a/vendor/github.com/minio/minio-go/v7/api-presigned.go +++ b/vendor/github.com/minio/minio-go/v7/api-presigned.go @@ -140,7 +140,7 @@ func (c *Client) PresignedPostPolicy(ctx context.Context, p *PostPolicy) (u *url } // Get credentials from the configured credentials provider. - credValues, err := c.credsProvider.GetWithContext(c.CredContext()) + credValues, err := c.credsProvider.GetWithContext(c.credContext(ctx)) if err != nil { return nil, nil, err } diff --git a/vendor/github.com/minio/minio-go/v7/api-put-object-fan-out.go b/vendor/github.com/minio/minio-go/v7/api-put-object-fan-out.go index 3023b949cd4..cba0c069ba0 100644 --- a/vendor/github.com/minio/minio-go/v7/api-put-object-fan-out.go +++ b/vendor/github.com/minio/minio-go/v7/api-put-object-fan-out.go @@ -69,6 +69,8 @@ type PutObjectFanOutResponse struct { // stream multiple objects are written, defined via a list of PutObjectFanOutRequests. Each entry // in PutObjectFanOutRequest carries an object keyname and its relevant metadata if any. `Key` is // mandatory, rest of the other options in PutObjectFanOutRequest are optional. +// +// Deprecated: Use PutObject instead. func (c *Client) PutObjectFanOut(ctx context.Context, bucket string, fanOutData io.Reader, fanOutReq PutObjectFanOutRequest) ([]PutObjectFanOutResponse, error) { if len(fanOutReq.Entries) == 0 { return nil, errInvalidArgument("fan out requests cannot be empty") diff --git a/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go b/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go index fe503fb667d..402319cbff2 100644 --- a/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go +++ b/vendor/github.com/minio/minio-go/v7/api-s3-datatypes.go @@ -94,10 +94,16 @@ type Version struct { StorageClass string VersionID string `xml:"VersionId"` - // x-amz-meta-* headers stripped "x-amz-meta-" prefix containing the first value. - // Only returned by MinIO servers. + // UserMetadata contains the exact stored object metadata: x-amz-meta-* + // entries with their prefixed keys plus system entries such as + // content-type. Only returned by MinIO servers. UserMetadata StringMap `json:"userMetadata,omitempty"` + // UserMetadataStripped is UserMetadata in the keyed form StatObject and + // GetObject return in ObjectInfo.UserMetadata. See + // ObjectInfo.UserMetadataStripped. + UserMetadataStripped StringMap `json:"userMetadataStripped,omitempty" xml:"-"` + // x-amz-tagging values in their k/v values. // Only returned by MinIO servers. UserTags URLMap `json:"userTags,omitempty" xml:"UserTags"` @@ -280,6 +286,32 @@ type initiator struct { type copyObjectResult struct { ETag string LastModified time.Time // time string format "2006-01-02T15:04:05.000Z" + + // Checksum values returned in CopyObjectResult / CopyPartResult. + ChecksumCRC32 string `xml:"ChecksumCRC32,omitempty"` + ChecksumCRC32C string `xml:"ChecksumCRC32C,omitempty"` + ChecksumSHA1 string `xml:"ChecksumSHA1,omitempty"` + ChecksumSHA256 string `xml:"ChecksumSHA256,omitempty"` + ChecksumCRC64NVME string `xml:",omitempty"` + ChecksumMD5 string `xml:",omitempty"` + ChecksumSHA512 string `xml:",omitempty"` + ChecksumXXHash64 string `xml:"ChecksumXXHASH64,omitempty"` + ChecksumXXHash3 string `xml:"ChecksumXXHASH3,omitempty"` + ChecksumXXHash128 string `xml:"ChecksumXXHASH128,omitempty"` +} + +// setChecksums copies the copied part's checksums onto a CompletePart. +func (r *copyObjectResult) setChecksums(p *CompletePart) { + p.ChecksumCRC32 = r.ChecksumCRC32 + p.ChecksumCRC32C = r.ChecksumCRC32C + p.ChecksumSHA1 = r.ChecksumSHA1 + p.ChecksumSHA256 = r.ChecksumSHA256 + p.ChecksumCRC64NVME = r.ChecksumCRC64NVME + p.ChecksumMD5 = r.ChecksumMD5 + p.ChecksumSHA512 = r.ChecksumSHA512 + p.ChecksumXXHash64 = r.ChecksumXXHash64 + p.ChecksumXXHash3 = r.ChecksumXXHash3 + p.ChecksumXXHash128 = r.ChecksumXXHash128 } // ObjectPart container for particular part of an object. diff --git a/vendor/github.com/minio/minio-go/v7/api-stat.go b/vendor/github.com/minio/minio-go/v7/api-stat.go index a4b2af7aefc..ba9afa75c8d 100644 --- a/vendor/github.com/minio/minio-go/v7/api-stat.go +++ b/vendor/github.com/minio/minio-go/v7/api-stat.go @@ -57,7 +57,12 @@ func (c *Client) BucketExists(ctx context.Context, bucketName string) (bool, err } // StatObject verifies if object exists, you have permission to access it -// and returns information about the object. +// and returns information about the object. When the returned error is +// non-nil but a response was received, the ObjectInfo still carries the +// VersionID and IsDeleteMarker values parsed from the response headers, +// plus ReplicationReady on every error path except the versioned +// delete-marker 405 (an asymmetry preserved from the pre-v7.0.93 +// behavior, which populated ReplicationReady on the generic branch only). func (c *Client) StatObject(ctx context.Context, bucketName, objectName string, opts StatObjectOptions) (ObjectInfo, error) { // Input validation. if err := s3utils.CheckValidBucketName(bucketName); err != nil { @@ -92,32 +97,32 @@ func (c *Client) StatObject(ctx context.Context, bucketName, objectName string, }) defer closeResponse(resp) if err != nil { - return ObjectInfo{}, err - } - - if resp != nil { + // executeMethod returns a non-nil error for every non-success + // status. When a response exists, its headers still carry the + // version and delete-marker fields — surface them with the error. + if resp == nil { + return ObjectInfo{}, err + } deleteMarker := resp.Header.Get(amzDeleteMarker) == "true" replicationReady := resp.Header.Get(minioTgtReplicationReady) == "true" - if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent { - if resp.StatusCode == http.StatusMethodNotAllowed && opts.VersionID != "" && deleteMarker { - errResp := ErrorResponse{ - StatusCode: resp.StatusCode, - Code: MethodNotAllowed, - Message: s3ErrorResponseMap[MethodNotAllowed], - BucketName: bucketName, - Key: objectName, - } - return ObjectInfo{ - VersionID: resp.Header.Get(amzVersionID), - IsDeleteMarker: deleteMarker, - }, errResp + if resp.StatusCode == http.StatusMethodNotAllowed && opts.VersionID != "" && deleteMarker { + errResp := ErrorResponse{ + StatusCode: resp.StatusCode, + Code: MethodNotAllowed, + Message: s3ErrorResponseMap[MethodNotAllowed], + BucketName: bucketName, + Key: objectName, } return ObjectInfo{ - VersionID: resp.Header.Get(amzVersionID), - IsDeleteMarker: deleteMarker, - ReplicationReady: replicationReady, // whether delete marker can be replicated - }, httpRespToErrorResponse(resp, bucketName, objectName) + VersionID: resp.Header.Get(amzVersionID), + IsDeleteMarker: deleteMarker, + }, errResp } + return ObjectInfo{ + VersionID: resp.Header.Get(amzVersionID), + IsDeleteMarker: deleteMarker, + ReplicationReady: replicationReady, // whether delete marker can be replicated + }, err } return ToObjectInfo(bucketName, objectName, resp.Header) diff --git a/vendor/github.com/minio/minio-go/v7/api.go b/vendor/github.com/minio/minio-go/v7/api.go index dbf639ab1d0..f7241af77fa 100644 --- a/vendor/github.com/minio/minio-go/v7/api.go +++ b/vendor/github.com/minio/minio-go/v7/api.go @@ -175,7 +175,7 @@ type Options struct { // Global constants. const ( libraryName = "minio-go" - libraryVersion = "v7.0.98" + libraryVersion = "v7.3.0" ) // User Agent should always following the below style. @@ -403,7 +403,7 @@ func (c *Client) TraceOff() { // SetS3TransferAccelerate - turns s3 accelerated endpoint on or off for all your // requests. This feature is only specific to S3 for all other endpoints this // function does nothing. To read further details on s3 transfer acceleration -// please vist - +// please visit - // http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html func (c *Client) SetS3TransferAccelerate(accelerateEndpoint string) { if s3utils.IsAmazonEndpoint(*c.endpointURL) { @@ -554,7 +554,7 @@ type requestMetadata struct { } // dumpHTTP - dump HTTP request and response. -func (c *Client) dumpHTTP(req *http.Request, resp *http.Response) error { +func (c *Client) dumpHTTP(req *http.Request, resp *http.Response, doErr error) error { // Starts http dump. _, err := fmt.Fprintln(c.traceOutput, "---------START-HTTP---------") if err != nil { @@ -568,6 +568,9 @@ func (c *Client) dumpHTTP(req *http.Request, resp *http.Response) error { } // Only display request header. + if req.Body != nil { + req.Body = http.NoBody + } reqTrace, err := httputil.DumpRequestOut(req, false) if err != nil { return err @@ -579,28 +582,36 @@ func (c *Client) dumpHTTP(req *http.Request, resp *http.Response) error { return err } - // Only display response header. - var respTrace []byte + if resp != nil { + // Only display response header. + var respTrace []byte - // For errors we make sure to dump response body as well. - if resp.StatusCode != http.StatusOK && - resp.StatusCode != http.StatusPartialContent && - resp.StatusCode != http.StatusNoContent { - respTrace, err = httputil.DumpResponse(resp, true) - if err != nil { - return err + // For errors we make sure to dump response body as well. + if !successStatus.Contains(resp.StatusCode) { + respTrace, err = httputil.DumpResponse(resp, true) + if err != nil { + return err + } + } else { + respTrace, err = httputil.DumpResponse(resp, false) + if err != nil { + return err + } } - } else { - respTrace, err = httputil.DumpResponse(resp, false) + + // Write response to trace output. + _, err = fmt.Fprint(c.traceOutput, strings.TrimSuffix(string(respTrace), "\r\n")) if err != nil { return err } } - // Write response to trace output. - _, err = fmt.Fprint(c.traceOutput, strings.TrimSuffix(string(respTrace), "\r\n")) - if err != nil { - return err + if doErr != nil { + // Write error to trace output. + _, err = fmt.Fprintln(c.traceOutput, strings.TrimSuffix(string(doErr.Error()), "\r\n")) + if err != nil { + return err + } } // Ends the http dump. @@ -623,6 +634,9 @@ func (c *Client) do(req *http.Request) (resp *http.Response, err error) { resp, err = c.httpClient.Do(req) if err != nil { + if c.isTraceEnabled { + _ = c.dumpHTTP(req, nil, err) + } // Handle this specifically for now until future Golang versions fix this issue properly. if urlErr, ok := err.(*url.Error); ok { if strings.Contains(urlErr.Err.Error(), "EOF") { @@ -643,9 +657,9 @@ func (c *Client) do(req *http.Request) (resp *http.Response, err error) { } // If trace is enabled, dump http request and response, - // except when the traceErrorsOnly enabled and the response's status code is ok - if c.isTraceEnabled && (!c.traceErrorsOnly || resp.StatusCode != http.StatusOK) { - err = c.dumpHTTP(req, resp) + // except when traceErrorsOnly is enabled and the response has a success status code + if c.isTraceEnabled && (!c.traceErrorsOnly || !successStatus.Contains(resp.StatusCode)) { + err = c.dumpHTTP(req, resp, nil) if err != nil { return nil, err } @@ -657,6 +671,7 @@ func (c *Client) do(req *http.Request) (resp *http.Response, err error) { // List of success status. var successStatus = set.CreateIntSet( http.StatusOK, + http.StatusAccepted, http.StatusNoContent, http.StatusPartialContent, ) @@ -833,8 +848,24 @@ func (c *Client) executeMethod(ctx context.Context, method string, metadata requ return res, err } +// credsRetrievalPanic carries a panic value out of the de-duplicated +// credential retrieval goroutine so newRequest can resume it on each +// caller's goroutine. The value is re-raised verbatim, as if the provider +// had panicked on the caller's goroutine; the retrieval goroutine's stack +// is not carried along. +type credsRetrievalPanic struct{ value any } + +func (p credsRetrievalPanic) Error() string { + return fmt.Sprintf("credentials retrieval panicked: %v", p.value) +} + // newRequest - instantiate a new HTTP request for a given method. func (c *Client) newRequest(ctx context.Context, method string, metadata requestMetadata) (req *http.Request, err error) { + if ctx == nil { + // A nil context would be dereferenced below — by the bucket + // location lookup, the waiter select, and context.WithoutCancel. + return nil, errInvalidArgument("context cannot be nil") + } // If no method is supplied default to 'POST'. if method == "" { method = http.MethodPost @@ -867,23 +898,88 @@ func (c *Client) newRequest(ctx context.Context, method string, metadata request return nil, err } - if c.httpTrace != nil { - ctx = httptrace.WithClientTrace(ctx, c.httpTrace) - } - - // make sure to de-dup calls to credential services, this reduces - // the overall load to the endpoint generating credential service. - value, err, _ := c.credsGroup.Do(metadata.bucketName, func() (credentials.Value, error) { - if s3utils.IsS3ExpressBucket(metadata.bucketName) && s3utils.IsAmazonEndpoint(*c.endpointURL) { - return c.CreateSession(ctx, metadata.bucketName, SessionReadWrite) + // Cached, unexpired credentials (or an absent provider — anonymous + // access) are served inline; a retrieval that races expiry runs + // inline too, with the caller's live context, serialized by the + // Credentials mutex. A still-fresh cached S3 Express session is + // served inline as well; actual retrievals go through the de-dup + // group. + express := s3utils.IsS3ExpressBucket(metadata.bucketName) && s3utils.IsAmazonEndpoint(*c.endpointURL) + var value credentials.Value + var served bool + if express { + value, served = c.sessionFromCache(metadata.bucketName) + } else if c.credsProvider == nil || !c.credsProvider.IsExpired() { + value, err = c.credsProvider.GetWithContext(c.credContext(ctx)) + served = true + } + if !served { + // The provider retrieval is detached (context.WithoutCancel) so + // one caller's cancellation cannot fail concurrent waiters; each + // waiter stops waiting when its own context ends, though a + // caller arriving mid-retrieval blocks in IsExpired on the + // Credentials mutex until the retrieval completes. Detachment + // strips the caller's deadline along with its cancellation: on + // this path the caller context governs only the wait, and reaches + // the credential request itself only outside the group — on the + // inline not-expired path above and the direct call sites + // (presign, bucket location, express CreateSession). The S3 + // Express session request keeps the caller context: a full S3 + // operation's retries must stay cancellable, so its waiters + // share the winner's fate, and its trace for the same reason: + // the round trip was traced before this change. + // A retrieval panic resumes on each waiting caller's goroutine + // (credsRetrievalPanic); a runtime.Goexit reaches waiters as a + // terminal error from the de-dup group, since the retrieval + // goroutine cannot return one itself. + retrieveCtx := ctx + if express { + if c.httpTrace != nil { + retrieveCtx = httptrace.WithClientTrace(retrieveCtx, c.httpTrace) + } + } else { + retrieveCtx = context.WithoutCancel(ctx) + } + resCh := c.credsGroup.DoChan(metadata.bucketName, func() (v credentials.Value, rerr error) { + defer func() { + if r := recover(); r != nil { + rerr = credsRetrievalPanic{value: r} + } + }() + if express { + return c.CreateSession(retrieveCtx, metadata.bucketName, SessionReadWrite) + } + // Get credentials from the configured credentials provider. + return c.credsProvider.GetWithContext(c.credContext(retrieveCtx)) + }) + var res singleflight.Result[credentials.Value] + select { + case res = <-resCh: + case <-ctx.Done(): + // A result already delivered when the cancellation fires is + // preferred over the caller's context error. + select { + case res = <-resCh: + default: + return nil, ctx.Err() + } + } + var cp credsRetrievalPanic + if errors.As(res.Err, &cp) { + panic(cp.value) } - // Get credentials from the configured credentials provider. - return c.credsProvider.GetWithContext(c.CredContext()) - }) + value, err = res.Val, res.Err + } if err != nil { return nil, err } + // Attach the trace after retrieval: provider credential requests were + // never traced. The express session request is traced above. + if c.httpTrace != nil { + ctx = httptrace.WithClientTrace(ctx, c.httpTrace) + } + // Initialize a new HTTP request for the method. req, err = http.NewRequestWithContext(ctx, method, targetURL.String(), nil) if err != nil { @@ -1157,6 +1253,14 @@ func (c *Client) CredContext() *credentials.CredContext { } } +// credContext returns the client's CredContext with ctx attached as the +// caller context for credential retrieval. +func (c *Client) credContext(ctx context.Context) *credentials.CredContext { + cc := c.CredContext() + cc.Context = ctx + return cc +} + // GetCreds returns the access creds for the client func (c *Client) GetCreds() (credentials.Value, error) { if c.credsProvider == nil { diff --git a/vendor/github.com/minio/minio-go/v7/bucket-cache.go b/vendor/github.com/minio/minio-go/v7/bucket-cache.go index 7c64972842c..50b20c4dc64 100644 --- a/vendor/github.com/minio/minio-go/v7/bucket-cache.go +++ b/vendor/github.com/minio/minio-go/v7/bucket-cache.go @@ -76,33 +76,35 @@ func (c *Client) getBucketLocation(ctx context.Context, bucketName string) (stri // processes the getBucketLocation http response from the server. func processBucketLocationResponse(resp *http.Response, bucketName string) (bucketLocation string, err error) { - if resp != nil { - if resp.StatusCode != http.StatusOK { - err = httpRespToErrorResponse(resp, bucketName, "") - errResp := ToErrorResponse(err) - // For access denied error, it could be an anonymous - // request. Move forward and let the top level callers - // succeed if possible based on their policy. - switch errResp.Code { - case NotImplemented: - switch errResp.Server { - case "AmazonSnowball": - return "snowball", nil - case "cloudflare": - return "us-east-1", nil - } - case AuthorizationHeaderMalformed: - fallthrough - case InvalidRegion: - fallthrough - case AccessDenied: - if errResp.Region == "" { - return "us-east-1", nil - } - return errResp.Region, nil + if resp == nil { + return "", errInvalidArgument("Empty http response. " + reportIssue) + } + + if resp.StatusCode != http.StatusOK { + err = httpRespToErrorResponse(resp, bucketName, "") + errResp := ToErrorResponse(err) + // For access denied error, it could be an anonymous + // request. Move forward and let the top level callers + // succeed if possible based on their policy. + switch errResp.Code { + case NotImplemented: + switch errResp.Server { + case "AmazonSnowball": + return "snowball", nil + case "cloudflare": + return "us-east-1", nil } - return "", err + case AuthorizationHeaderMalformed: + fallthrough + case InvalidRegion: + fallthrough + case AccessDenied: + if errResp.Region == "" { + return "us-east-1", nil + } + return errResp.Region, nil } + return "", err } // Extract location. @@ -170,7 +172,7 @@ func (c *Client) getBucketLocationRequest(ctx context.Context, bucketName string c.setUserAgent(req) // Get credentials from the configured credentials provider. - value, err := c.credsProvider.GetWithContext(c.CredContext()) + value, err := c.credsProvider.GetWithContext(c.credContext(ctx)) if err != nil { return nil, err } diff --git a/vendor/github.com/minio/minio-go/v7/checksum.go b/vendor/github.com/minio/minio-go/v7/checksum.go index bb3ce27b185..d6324b1c05a 100644 --- a/vendor/github.com/minio/minio-go/v7/checksum.go +++ b/vendor/github.com/minio/minio-go/v7/checksum.go @@ -25,6 +25,7 @@ import ( "encoding/base64" "encoding/binary" "errors" + "fmt" "hash" "io" "math/bits" @@ -316,6 +317,86 @@ func (c ChecksumType) String() string { return "" } +// checksumVerifyingReader verifies the checksum of data as it is read. +type checksumVerifyingReader struct { + io.ReadCloser + hash.Hash + expectChecksum string +} + +// newChecksumVerifyingReader returns a checksum-verifying reader for obj, +// wrapping the given response body, or nil if obj carries no usable checksum. +func (c *Client) newChecksumVerifyingReader(obj ObjectInfo) *checksumVerifyingReader { + switch { + case obj.ChecksumCRC32 != "": + return &checksumVerifyingReader{Hash: ChecksumCRC32.Hasher(), expectChecksum: obj.ChecksumCRC32} + case obj.ChecksumCRC32C != "": + return &checksumVerifyingReader{Hash: ChecksumCRC32C.Hasher(), expectChecksum: obj.ChecksumCRC32C} + case obj.ChecksumSHA1 != "": + return &checksumVerifyingReader{Hash: ChecksumSHA1.Hasher(), expectChecksum: obj.ChecksumSHA1} + case obj.ChecksumSHA256 != "": + return &checksumVerifyingReader{Hash: c.sha256Hasher(), expectChecksum: obj.ChecksumSHA256} + case obj.ChecksumCRC64NVME != "": + return &checksumVerifyingReader{Hash: ChecksumCRC64NVME.Hasher(), expectChecksum: obj.ChecksumCRC64NVME} + case obj.ChecksumMD5 != "": + return &checksumVerifyingReader{Hash: c.md5Hasher(), expectChecksum: obj.ChecksumMD5} + case obj.ChecksumSHA512 != "": + return &checksumVerifyingReader{Hash: ChecksumSHA512.Hasher(), expectChecksum: obj.ChecksumSHA512} + case obj.ChecksumXXHash64 != "": + return &checksumVerifyingReader{Hash: ChecksumXXHash64.Hasher(), expectChecksum: obj.ChecksumXXHash64} + case obj.ChecksumXXHash3 != "": + return &checksumVerifyingReader{Hash: ChecksumXXHash3.Hasher(), expectChecksum: obj.ChecksumXXHash3} + case obj.ChecksumXXHash128 != "": + return &checksumVerifyingReader{Hash: ChecksumXXHash128.Hasher(), expectChecksum: obj.ChecksumXXHash128} + default: + return nil + } +} + +func (c *checksumVerifyingReader) SetReader(r io.ReadCloser) { + c.ReadCloser = r +} + +// Close returns any pooled hasher and closes the underlying reader if one is set. +func (c *checksumVerifyingReader) Close() error { + if closer, ok := c.Hash.(interface{ Close() }); ok { + closer.Close() + } + if c.ReadCloser == nil { + return nil + } + return c.ReadCloser.Close() +} + +// Read reads data and hashes it. At EOF the checksum is verified; on +// mismatch the mismatch error is returned in place of io.EOF. +func (c *checksumVerifyingReader) Read(p []byte) (int, error) { + n, err := c.ReadCloser.Read(p) + if n > 0 { + n2, werr := c.Write(p[:n]) + if werr != nil { + return n, werr + } + if n2 != n { + return n, io.ErrShortWrite + } + } + if err == io.EOF { + if verr := c.VerifyChecksum(); verr != nil { + return n, verr + } + } + return n, err +} + +// VerifyChecksum returns an error if the computed checksum does not match. +func (c *checksumVerifyingReader) VerifyChecksum() error { + if got := base64.StdEncoding.EncodeToString(c.Sum(nil)); got != c.expectChecksum { + return fmt.Errorf("checksum mismatch, expected %s, got %s", c.expectChecksum, got) + } + return nil +} + // ChecksumReader reads all of r and returns a checksum of type c. // Returns any error that may have occurred while reading. func (c ChecksumType) ChecksumReader(r io.Reader) (Checksum, error) { diff --git a/vendor/github.com/minio/minio-go/v7/create-session.go b/vendor/github.com/minio/minio-go/v7/create-session.go index d85e79d4b1e..3f1b3175c9e 100644 --- a/vendor/github.com/minio/minio-go/v7/create-session.go +++ b/vendor/github.com/minio/minio-go/v7/create-session.go @@ -51,19 +51,30 @@ type createSessionResult struct { } `xml:",omitempty"` } +// expressSessionRenewalLeeway is how long before its expiration a cached +// S3 Express session stops being served, leaving room for renewal. +const expressSessionRenewalLeeway = 10 * time.Second + +// sessionFromCache returns the cached S3 Express session credentials for +// bucketName while they remain outside the renewal leeway. +func (c *Client) sessionFromCache(bucketName string) (credentials.Value, bool) { + v, ok := c.bucketSessionCache.Get(bucketName) + if !ok || !v.Expiration.After(time.Now().Add(expressSessionRenewalLeeway)) { + return credentials.Value{}, false + } + return v, true +} + // CreateSession - https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html // the returning credentials may be cached depending on the expiration of the original -// credential, credentials will get renewed 10 secs earlier than when its gonna expire -// allowing for some leeway in the renewal process. +// credential; a cached session stops being served expressSessionRenewalLeeway before +// it expires, allowing for some leeway in the renewal process. func (c *Client) CreateSession(ctx context.Context, bucketName string, sessionMode SessionMode) (cred credentials.Value, err error) { if err := s3utils.CheckValidBucketNameS3Express(bucketName); err != nil { return credentials.Value{}, err } - v, ok := c.bucketSessionCache.Get(bucketName) - if ok && v.Expiration.After(time.Now().Add(10*time.Second)) { - // Verify if the credentials will not expire - // in another 10 seconds, if not we renew it again. + if v, ok := c.sessionFromCache(bucketName); ok { return v, nil } @@ -143,7 +154,7 @@ func (c *Client) createSessionRequest(ctx context.Context, bucketName string, se c.setUserAgent(req) // Get credentials from the configured credentials provider. - value, err := c.credsProvider.GetWithContext(c.CredContext()) + value, err := c.credsProvider.GetWithContext(c.credContext(ctx)) if err != nil { return nil, err } diff --git a/vendor/github.com/minio/minio-go/v7/functional_tests.go b/vendor/github.com/minio/minio-go/v7/functional_tests.go index ef5f2377f1d..80d98955a2f 100644 --- a/vendor/github.com/minio/minio-go/v7/functional_tests.go +++ b/vendor/github.com/minio/minio-go/v7/functional_tests.go @@ -172,9 +172,12 @@ func logError(testName, function string, args map[string]interface{}, startTime // If server returns NotImplemented we assume it is gateway mode and hence log it as info and move on to next tests // Special case for ComposeObject API as it is implemented on client side and adds specific error details like `Error in upload-part-copy` in // addition to NotImplemented error returned from server - if isErrNotImplemented(err) { + switch { + case isErrNotImplemented(err): logIgnored(testName, function, args, startTime, message) - } else { + case isErrFreeTierLicense(err): + logNotAvailable(testName, function, args, startTime, message) + default: logFailure(testName, function, args, startTime, alert, message, err) if !isRunOnFail() { panic(fmt.Sprintf("Test failed with message: %s, err: %v", message, err)) @@ -206,6 +209,15 @@ func logIgnored(testName, function string, args map[string]interface{}, startTim ).Info("") } +// log not applicable test runs for license-gated features +func logNotAvailable(testName, function string, args map[string]interface{}, startTime time.Time, alert string) { + baseLogger(testName, function, args, startTime). + With( + "status", "NA", + "alert", strings.Split(alert, " ")[0]+" requires a paid-tier license", + ).Info("") +} + // Delete objects in given bucket, recursively func cleanupBucket(bucketName string, c *minio.Client) error { // Create a done channel to control 'ListObjectsV2' go routine. @@ -279,6 +291,11 @@ func isErrNotImplemented(err error) bool { return minio.ToErrorResponse(err).Code == minio.NotImplemented } +// isErrFreeTierLicense reports whether the server rejected the request because it requires a paid-tier license. +func isErrFreeTierLicense(err error) bool { + return minio.ToErrorResponse(err).Code == minio.XMinioPaidTierLicenseRequired +} + func isRunOnFail() bool { return os.Getenv("RUN_ON_FAIL") == "1" } @@ -795,6 +812,125 @@ func testListObjectVersions() { logSuccess(testName, function, args, startTime) } +func testStatObjectResponseHeaders() { + // initialize logging params + startTime := time.Now() + testName := getFuncName() + function := "StatObject(bucketName, objectName, opts)" + args := map[string]interface{}{} + + c, err := NewClient(ClientConfig{}) + if err != nil { + logError(testName, function, args, startTime, "", "MinIO client object creation failed", err) + return + } + + // Generate a new random bucket name. + bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-") + args["bucketName"] = bucketName + + // Make a new bucket. + err = c.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1"}) + if err != nil { + logError(testName, function, args, startTime, "", "MakeBucket failed", err) + return + } + + defer cleanupBucket(bucketName, c) + + bufSize := dataFileMap["datafile-33-kB"] + reader := getDataReader("datafile-33-kB") + defer reader.Close() + + objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") + args["objectName"] = objectName + + _, err = c.PutObject(context.Background(), bucketName, objectName, reader, int64(bufSize), minio.PutObjectOptions{ContentType: "binary/octet-stream"}) + if err != nil { + logError(testName, function, args, startTime, "", "PutObject failed", err) + return + } + + opts := minio.StatObjectOptions{} + err = opts.SetRange(0, 99) + if err != nil { + logError(testName, function, args, startTime, "", "SetRange failed", err) + return + } + args["range"] = "0-99" + + st, err := c.StatObject(context.Background(), bucketName, objectName, opts) + if err != nil { + logError(testName, function, args, startTime, "", "StatObject failed", err) + return + } + + if st.Size != 100 { + logError(testName, function, args, startTime, "", "StatObject ranged size mismatch", fmt.Errorf("got %d, want 100", st.Size)) + return + } + wantContentRange := fmt.Sprintf("bytes 0-99/%d", bufSize) + gotContentRange := st.Headers.Get("Content-Range") + if gotContentRange != wantContentRange { + logError(testName, function, args, startTime, "", "StatObject response headers Content-Range mismatch", fmt.Errorf("got %q, want %q", gotContentRange, wantContentRange)) + return + } + if st.Headers.Get("ETag") == "" { + logError(testName, function, args, startTime, "", "StatObject response headers missing ETag", errors.New("empty ETag header")) + return + } + + gopts := minio.GetObjectOptions{} + err = gopts.SetRange(0, 99) + if err != nil { + logError(testName, function, args, startTime, "", "SetRange failed", err) + return + } + obj, err := c.GetObject(context.Background(), bucketName, objectName, gopts) + if err != nil { + logError(testName, function, args, startTime, "", "GetObject failed", err) + return + } + defer obj.Close() + // Read first: a first-op Stat issues an un-ranged StatObject by design, + // so the ranged GET response headers are observable only after a read. + buf := make([]byte, 100) + if _, err = io.ReadFull(obj, buf); err != nil { + logError(testName, function, args, startTime, "", "GetObject ranged read failed", err) + return + } + gst, err := obj.Stat() + if err != nil { + logError(testName, function, args, startTime, "", "GetObject Stat failed", err) + return + } + if got := gst.Headers.Get("Content-Range"); got != wantContentRange { + logError(testName, function, args, startTime, "", "GetObject response headers Content-Range mismatch", fmt.Errorf("got %q, want %q", got, wantContentRange)) + return + } + + sawObject := false + for listInfo := range c.ListObjects(context.Background(), bucketName, minio.ListObjectsOptions{}) { + if listInfo.Err != nil { + logError(testName, function, args, startTime, "", "ListObjects failed", listInfo.Err) + return + } + if listInfo.Key == objectName { + sawObject = true + } + if listInfo.Headers != nil { + logError(testName, function, args, startTime, "", "ListObjects ObjectInfo.Headers expected nil", fmt.Errorf("got %v", listInfo.Headers)) + return + } + } + if !sawObject { + logError(testName, function, args, startTime, "", "ListObjects did not list the uploaded object", errors.New("uploaded object missing from listing")) + return + } + + logSuccess(testName, function, args, startTime) +} + func testStatObjectWithVersioning() { // initialize logging params startTime := time.Now() @@ -5379,7 +5515,7 @@ func testGetObjectReadSeekFunctional() { } if st.Size != int64(bufSize) { - logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+string(int64(bufSize))+", got "+string(st.Size), err) + logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+strconv.Itoa(bufSize)+", got "+strconv.FormatInt(st.Size, 10), err) return } @@ -5418,50 +5554,77 @@ func testGetObjectReadSeekFunctional() { {0, 0, 0, nil, true, 0, 0}, // Start from offset 2048, fetch data and compare {2048, 0, 2048, nil, true, 2048, bufSize}, - // Start from offset larger than possible - {int64(bufSize) + 1024, 0, 0, seekErr, false, 0, 0}, + // Start from offset larger than possible: Seek rejects it with io.EOF + // and keeps the offset unchanged. + {int64(bufSize) + 1024, 0, 0, io.EOF, false, 0, 0}, // Move to offset 0 without comparing {0, 0, 0, nil, false, 0, 0}, // Move one step forward and compare {1, 1, 1, nil, true, 1, bufSize}, - // Move larger than possible - {int64(bufSize), 1, 0, seekErr, false, 0, 0}, - // Provide negative offset with CUR_SEEK - {int64(-1), 1, 0, seekErr, false, 0, 0}, - // Test with whence SEEK_END and with positive offset - {1024, 2, int64(bufSize) - 1024, io.EOF, true, 0, 0}, + // Move larger than possible: Seek returns io.EOF. + {int64(bufSize), 1, 0, io.EOF, false, 0, 0}, + // Provide negative offset with CUR_SEEK: valid since the resulting + // absolute position is within the object. + {int64(-1), 1, int64(bufSize) - 1, nil, false, 0, 0}, + // Test with whence SEEK_END and with positive offset: Seek returns + // io.EOF. + {1024, 2, 0, io.EOF, false, 0, 0}, // Test with whence SEEK_END and with negative offset {-1024, 2, int64(bufSize) - 1024, nil, true, bufSize - 1024, bufSize}, // Test with whence SEEK_END and with large negative offset {-int64(bufSize) * 2, 2, 0, seekErr, true, 0, 0}, + // Seek to exactly the object end; the subsequent read reports io.EOF. + {0, 2, int64(bufSize), nil, false, 0, 0}, } for i, testCase := range testCases { + // Snapshot the cursor so rejected seeks can be asserted side-effect + // free. + prevPos, err := r.Seek(0, io.SeekCurrent) + if err != nil { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, reading the current position failed", i+1), err) + return + } // Perform seek operation n, err := r.Seek(testCase.offset, testCase.whence) // We expect an error if testCase.err == seekErr && err == nil { - logError(testName, function, args, startTime, "", "Test "+string(i+1)+", unexpected err value: expected: "+testCase.err.Error()+", found: "+err.Error(), err) + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, unexpected err value: expected: %v, found: %v", i+1, testCase.err, err), err) return } // We expect a specific error if testCase.err != seekErr && testCase.err != err { - logError(testName, function, args, startTime, "", "Test "+string(i+1)+", unexpected err value: expected: "+testCase.err.Error()+", found: "+err.Error(), err) + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, unexpected err value: expected: %v, found: %v", i+1, testCase.err, err), err) return } // If we expect an error go to the next loop if testCase.err != nil { + // A rejected seek must leave the cursor unchanged. + curPos, cerr := r.Seek(0, io.SeekCurrent) + if cerr != nil || curPos != prevPos { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, cursor after rejected seek: expected %d, got %d", i+1, prevPos, curPos), cerr) + return + } continue } // Check the returned seek pos if n != testCase.pos { - logError(testName, function, args, startTime, "", "Test "+string(i+1)+", number of bytes seeked does not match, expected "+string(testCase.pos)+", got "+string(n), err) + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, number of bytes seeked does not match, expected %d, got %d", i+1, testCase.pos, n), err) return } // Compare only if shouldCmp is activated if testCase.shouldCmp { cmpData(r, testCase.start, testCase.end) } + // A successful seek to the object end must defer io.EOF to the + // subsequent read. + if !testCase.shouldCmp && testCase.err == nil && testCase.pos >= int64(bufSize) { + readN, readErr := r.Read(make([]byte, 1)) + if readN != 0 || readErr != io.EOF { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, read after seek to object end expected zero bytes and io.EOF, got %d bytes and %v", i+1, readN, readErr), readErr) + return + } + } } logSuccess(testName, function, args, startTime) } @@ -5569,8 +5732,8 @@ func testGetObjectReadAtFunctional() { return } - if st.Size != int64(bufSize) { - logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+string(int64(bufSize))+", got "+string(st.Size), err) + if st.Size != (int64(bufSize) - int64(len(bufRead))) { + logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+strconv.Itoa(bufSize)+", got "+strconv.Itoa(bufSize-len(bufRead)), err) return } @@ -5665,6 +5828,228 @@ func testGetObjectReadAtFunctional() { logSuccess(testName, function, args, startTime) } +// testGetObjectWithRange - get object with range +func testGetObjectWithRange() { + // initialize logging params + startTime := time.Now() + testName := getFuncName() + function := "GetObject(bucketName, objectName)" + args := map[string]interface{}{} + + c, err := NewClient(ClientConfig{}) + if err != nil { + logError(testName, function, args, startTime, "", "MinIO client object creation failed", err) + return + } + + // Generate a new random bucket name. + bucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "minio-go-test-") + args["bucketName"] = bucketName + + // Make a new bucket. + err = c.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1"}) + if err != nil { + logError(testName, function, args, startTime, "", "MakeBucket failed", err) + return + } + + defer cleanupBucket(bucketName, c) + + // Generate 33K of data. + bufSize := dataFileMap["datafile-33-kB"] + reader := getDataReader("datafile-33-kB") + defer reader.Close() + + objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") + args["objectName"] = objectName + + buf, err := io.ReadAll(reader) + if err != nil { + logError(testName, function, args, startTime, "", "ReadAll failed", err) + return + } + + // Save the data + _, err = c.PutObject(context.Background(), bucketName, objectName, bytes.NewReader(buf), int64(len(buf)), minio.PutObjectOptions{ContentType: "binary/octet-stream"}) + if err != nil { + logError(testName, function, args, startTime, "", "PutObject failed", err) + return + } + + var r *minio.Object + testIndex := 0 + baseSize := 0 + New := func() { + opts := minio.GetObjectOptions{} + switch testIndex { + case 0: + baseSize = bufSize + case 1: + opts.SetRange(100, 1000) + baseSize = 1000 - 100 + 1 + case 2: + opts.SetRange(100, 0) + baseSize = bufSize - 100 + case 3: + opts.SetRange(0, 1000) + baseSize = 1000 + 1 + } + r, err = c.GetObject(context.Background(), bucketName, objectName, opts) + if err != nil { + logError(testName, function, args, startTime, "", "Failed to create MinIO client object", err) + } + } + + Size := func(size int) { + st, err := r.Stat() + if err != nil { + logError(testName, function, args, startTime, "", "Failed to get object stat", err) + } + if int(st.Size) != size { + logError(testName, function, args, startTime, "", "Incorrect size returned", fmt.Errorf("Test index %d Expected size %d, got %d", testIndex, size, int(st.Size))) + } + } + Read := func(size int) { + b := make([]byte, size) + _, err := r.Read(b) + if err != nil { + logError(testName, function, args, startTime, "", "Failed to read from object", err) + } + } + + ReadFull := func(size int) { + b := make([]byte, size) + _, err := r.Read(b) + if err != nil { + logError(testName, function, args, startTime, "", "Failed to read from object", err) + } + } + + ReadAll := func() { + _, err := io.ReadAll(r) + if err != nil { + logError(testName, function, args, startTime, "", "Failed to read from object", err) + } + } + + Seek := func(offset int64, whence int) { + _, err := r.Seek(offset, whence) + if err != nil { + logError(testName, function, args, startTime, "", "Failed to seek in object", err) + } + } + ReadAt := func(offset int64, size int64) { + b := make([]byte, size) + _, err := r.ReadAt(b, offset) + if err != nil { + logError(testName, function, args, startTime, "", "Failed to read from object", err) + } + } + for index := range 4 { + testIndex = index + // case 1: stat first and then read 100 bytes for per read + { + New() + Size(baseSize) + Read(100) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + Read(100) + Size(baseSize - 300) + ReadFull(100) + Size(baseSize - 400) + } + // case 2: read 100 bytes for per read + { + New() + Read(100) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + Read(100) + Size(baseSize - 300) + ReadFull(100) + Size(baseSize - 400) + } + // case 3: Stat -> Read -> ReadAt -> Read + { + New() + Size(baseSize) + Read(100) + Size(baseSize - 100) + // should not move the offset, so next stat is not changed + ReadAt(100, 100) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + } + // case 4: Read -> ReadAt -> Read + { + New() + Read(100) + Size(baseSize - 100) + // should not move the offset, so next stat is not changed + ReadAt(100, 100) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + } + // case 5: Stat -> Read -> ReadAt -> Read -> Seek -> Read + { + New() + Size(baseSize) + Read(100) + Size(baseSize - 100) + // should not move the offset, so next stat is not changed + ReadAt(100, 100) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + Seek(100, io.SeekCurrent) + Size(baseSize - 300) + Read(100) + Size(baseSize - 400) + } + // case 6: Read -> ReadAt -> Read -> Seek -> Read + { + New() + Read(100) + Size(baseSize - 100) + // should not move the offset, so next stat is not changed + ReadAt(100, 100) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + Seek(100, io.SeekCurrent) + Size(baseSize - 300) + Read(100) + Size(baseSize - 400) + } + // case 7: Stat -> ReadAll -> ReadAt + { + New() + Size(baseSize) + ReadAll() + ReadAt(100, 100) + } + // case 8: ReadAll -> ReadAt + { + New() + ReadAll() + ReadAt(100, 100) + } + // case9: Seek first + { + New() + Seek(100, io.SeekCurrent) + Size(baseSize - 100) + Read(100) + Size(baseSize - 200) + } + } +} + // Reproduces issue https://github.com/minio/minio-go/issues/1137 func testGetObjectReadAtWhenEOFWasReached() { // initialize logging params @@ -5746,7 +6131,7 @@ func testGetObjectReadAtWhenEOFWasReached() { return } - if st.Size != int64(bufSize) { + if st.Size != (int64(bufSize) - int64(len(buf1))) { logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+string(int64(bufSize))+", got "+string(st.Size), err) return } @@ -6527,7 +6912,7 @@ func testSSECEncryptedGetObjectReadSeekFunctional() { } if st.Size != int64(bufSize) { - logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+string(int64(bufSize))+", got "+string(st.Size), err) + logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+strconv.Itoa(bufSize)+", got "+strconv.FormatInt(st.Size, 10), err) return } @@ -6563,17 +6948,20 @@ func testSSECEncryptedGetObjectReadSeekFunctional() { {0, 0, 0, nil, true, 0, 0}, // Start from offset 2048, fetch data and compare {2048, 0, 2048, nil, true, 2048, bufSize}, - // Start from offset larger than possible + // Start from offset larger than possible: Seek rejects it with io.EOF + // and keeps the offset unchanged. {int64(bufSize) + 1024, 0, 0, io.EOF, false, 0, 0}, // Move to offset 0 without comparing {0, 0, 0, nil, false, 0, 0}, // Move one step forward and compare {1, 1, 1, nil, true, 1, bufSize}, - // Move larger than possible + // Move larger than possible: Seek returns io.EOF. {int64(bufSize), 1, 0, io.EOF, false, 0, 0}, - // Provide negative offset with CUR_SEEK - {int64(-1), 1, 0, fmt.Errorf("Negative position not allowed for 1"), false, 0, 0}, - // Test with whence SEEK_END and with positive offset + // Provide negative offset with CUR_SEEK: valid since the resulting + // absolute position is within the object. + {int64(-1), 1, int64(bufSize) - 1, nil, false, 0, 0}, + // Test with whence SEEK_END and with positive offset: Seek returns + // io.EOF. {1024, 2, 0, io.EOF, false, 0, 0}, // Test with whence SEEK_END and with negative offset {-1024, 2, int64(bufSize) - 1024, nil, true, bufSize - 1024, bufSize}, @@ -6581,9 +6969,18 @@ func testSSECEncryptedGetObjectReadSeekFunctional() { {-int64(bufSize) * 2, 2, 0, fmt.Errorf("Seeking at negative offset not allowed for 2"), false, 0, 0}, // Test with invalid whence {0, 3, 0, fmt.Errorf("Invalid whence 3"), false, 0, 0}, + // Seek to exactly the object end; the subsequent read reports io.EOF. + {0, 2, int64(bufSize), nil, false, 0, 0}, } for i, testCase := range testCases { + // Snapshot the cursor so rejected seeks can be asserted side-effect + // free. + prevPos, err := r.Seek(0, io.SeekCurrent) + if err != nil { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, reading the current position failed", i+1), err) + return + } // Perform seek operation n, err := r.Seek(testCase.offset, testCase.whence) if err != nil && testCase.err == nil { @@ -6605,6 +7002,12 @@ func testSSECEncryptedGetObjectReadSeekFunctional() { fmt.Sprintf("Test %d, unexpected err value: expected: %s, found: %s", i+1, testCase.err, err), err) return } + // A rejected seek must leave the cursor unchanged. + curPos, cerr := r.Seek(0, io.SeekCurrent) + if cerr != nil || curPos != prevPos { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, cursor after rejected seek: expected %d, got %d", i+1, prevPos, curPos), cerr) + return + } } // Check the returned seek pos if n != testCase.pos { @@ -6616,6 +7019,15 @@ func testSSECEncryptedGetObjectReadSeekFunctional() { if testCase.shouldCmp { cmpData(r, testCase.start, testCase.end) } + // A successful seek to the object end must defer io.EOF to the + // subsequent read. + if !testCase.shouldCmp && testCase.err == nil && testCase.pos >= int64(bufSize) { + readN, readErr := r.Read(make([]byte, 1)) + if readN != 0 || readErr != io.EOF { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, read after seek to object end expected zero bytes and io.EOF, got %d bytes and %v", i+1, readN, readErr), readErr) + return + } + } } logSuccess(testName, function, args, startTime) @@ -6693,7 +7105,7 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() { } if st.Size != int64(bufSize) { - logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+string(int64(bufSize))+", got "+string(st.Size), err) + logError(testName, function, args, startTime, "", "Number of bytes does not match, expected "+strconv.Itoa(bufSize)+", got "+strconv.FormatInt(st.Size, 10), err) return } @@ -6729,17 +7141,20 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() { {0, 0, 0, nil, true, 0, 0}, // Start from offset 2048, fetch data and compare {2048, 0, 2048, nil, true, 2048, bufSize}, - // Start from offset larger than possible + // Start from offset larger than possible: Seek rejects it with io.EOF + // and keeps the offset unchanged. {int64(bufSize) + 1024, 0, 0, io.EOF, false, 0, 0}, // Move to offset 0 without comparing {0, 0, 0, nil, false, 0, 0}, // Move one step forward and compare {1, 1, 1, nil, true, 1, bufSize}, - // Move larger than possible + // Move larger than possible: Seek returns io.EOF. {int64(bufSize), 1, 0, io.EOF, false, 0, 0}, - // Provide negative offset with CUR_SEEK - {int64(-1), 1, 0, fmt.Errorf("Negative position not allowed for 1"), false, 0, 0}, - // Test with whence SEEK_END and with positive offset + // Provide negative offset with CUR_SEEK: valid since the resulting + // absolute position is within the object. + {int64(-1), 1, int64(bufSize) - 1, nil, false, 0, 0}, + // Test with whence SEEK_END and with positive offset: Seek returns + // io.EOF. {1024, 2, 0, io.EOF, false, 0, 0}, // Test with whence SEEK_END and with negative offset {-1024, 2, int64(bufSize) - 1024, nil, true, bufSize - 1024, bufSize}, @@ -6747,9 +7162,18 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() { {-int64(bufSize) * 2, 2, 0, fmt.Errorf("Seeking at negative offset not allowed for 2"), false, 0, 0}, // Test with invalid whence {0, 3, 0, fmt.Errorf("Invalid whence 3"), false, 0, 0}, + // Seek to exactly the object end; the subsequent read reports io.EOF. + {0, 2, int64(bufSize), nil, false, 0, 0}, } for i, testCase := range testCases { + // Snapshot the cursor so rejected seeks can be asserted side-effect + // free. + prevPos, err := r.Seek(0, io.SeekCurrent) + if err != nil { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, reading the current position failed", i+1), err) + return + } // Perform seek operation n, err := r.Seek(testCase.offset, testCase.whence) if err != nil && testCase.err == nil { @@ -6771,6 +7195,12 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() { fmt.Sprintf("Test %d, unexpected err value: expected: %s, found: %s", i+1, testCase.err, err), err) return } + // A rejected seek must leave the cursor unchanged. + curPos, cerr := r.Seek(0, io.SeekCurrent) + if cerr != nil || curPos != prevPos { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, cursor after rejected seek: expected %d, got %d", i+1, prevPos, curPos), cerr) + return + } } // Check the returned seek pos if n != testCase.pos { @@ -6782,6 +7212,15 @@ func testSSES3EncryptedGetObjectReadSeekFunctional() { if testCase.shouldCmp { cmpData(r, testCase.start, testCase.end) } + // A successful seek to the object end must defer io.EOF to the + // subsequent read. + if !testCase.shouldCmp && testCase.err == nil && testCase.pos >= int64(bufSize) { + readN, readErr := r.Read(make([]byte, 1)) + if readN != 0 || readErr != io.EOF { + logError(testName, function, args, startTime, "", fmt.Sprintf("Test %d, read after seek to object end expected zero bytes and io.EOF, got %d bytes and %v", i+1, readN, readErr), readErr) + return + } + } } logSuccess(testName, function, args, startTime) @@ -6879,7 +7318,7 @@ func testSSECEncryptedGetObjectReadAtFunctional() { } if st.Size != int64(bufSize) { - logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+string(int64(bufSize))+", got "+string(st.Size), err) + logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+strconv.Itoa(bufSize)+", got "+strconv.Itoa(int(st.Size)), err) return } @@ -8856,7 +9295,7 @@ func testGetObjectReadSeekFunctionalV2() { } if st.Size != int64(bufSize) { - logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+string(int64(bufSize))+" got "+string(st.Size), err) + logError(testName, function, args, startTime, "", "Number of bytes in stat does not match, expected "+strconv.Itoa(bufSize)+" got "+strconv.FormatInt(st.Size, 10), err) return } @@ -8867,7 +9306,7 @@ func testGetObjectReadSeekFunctionalV2() { return } if n != offset { - logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+string(offset)+" got "+string(n), err) + logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+strconv.FormatInt(offset, 10)+" got "+strconv.FormatInt(n, 10), err) return } n, err = r.Seek(0, 1) @@ -8876,12 +9315,44 @@ func testGetObjectReadSeekFunctionalV2() { return } if n != offset { - logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+string(offset)+" got "+string(n), err) + logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+strconv.FormatInt(offset, 10)+" got "+strconv.FormatInt(n, 10), err) return } - _, err = r.Seek(offset, 2) - if err == nil { - logError(testName, function, args, startTime, "", "Seek on positive offset for whence '2' should error out", err) + // Seeking past the object end with SEEK_END is rejected with io.EOF and + // leaves the offset unchanged. + n, err = r.Seek(offset, 2) + if err != io.EOF { + logError(testName, function, args, startTime, "", "Seek past object end should return io.EOF", err) + return + } + if n != 0 { + logError(testName, function, args, startTime, "", "Seek past object end should return offset 0, got "+strconv.FormatInt(n, 10), err) + return + } + // A rejected seek must leave the cursor unchanged. + n, err = r.Seek(0, 1) + if err != nil { + logError(testName, function, args, startTime, "", "Seek failed", err) + return + } + if n != offset { + logError(testName, function, args, startTime, "", "Cursor moved after rejected seek, expected "+strconv.FormatInt(offset, 10)+" got "+strconv.FormatInt(n, 10), err) + return + } + // Seeking to exactly the object end succeeds; the subsequent read reports + // io.EOF. + n, err = r.Seek(0, 2) + if err != nil { + logError(testName, function, args, startTime, "", "Seek failed", err) + return + } + if n != st.Size { + logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+strconv.FormatInt(st.Size, 10)+" got "+strconv.FormatInt(n, 10), err) + return + } + readN, readErr := r.Read(make([]byte, 1)) + if readN != 0 || readErr != io.EOF { + logError(testName, function, args, startTime, "", "Read after seeking to object end should return zero bytes and EOF", readErr) return } n, err = r.Seek(-offset, 2) @@ -8890,7 +9361,7 @@ func testGetObjectReadSeekFunctionalV2() { return } if n != st.Size-offset { - logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+string(st.Size-offset)+" got "+string(n), err) + logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+strconv.FormatInt(st.Size-offset, 10)+" got "+strconv.FormatInt(n, 10), err) return } @@ -8913,7 +9384,7 @@ func testGetObjectReadSeekFunctionalV2() { return } if n != (offset - 1) { - logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+string(offset-1)+" got "+string(n), err) + logError(testName, function, args, startTime, "", "Number of seeked bytes does not match, expected "+strconv.FormatInt(offset-1, 10)+" got "+strconv.FormatInt(n, 10), err) return } @@ -15084,6 +15555,7 @@ func main() { testMakeBucketError() testMakeBucketRegions() testPutObjectWithMetadata() + testGetObjectWithRange() testPutObjectReadAt() testPutObjectStreaming() testPutObjectPreconditionOnNonExistent() @@ -15122,6 +15594,7 @@ func main() { testRemoveObjects() testRemoveObjectsIter() testListObjectVersions() + testStatObjectResponseHeaders() testStatObjectWithVersioning() testGetObjectWithVersioning() testCopyObjectWithVersioning() diff --git a/vendor/github.com/minio/minio-go/v7/hook-reader.go b/vendor/github.com/minio/minio-go/v7/hook-reader.go index 06dbbb74d70..0d78e9afff4 100644 --- a/vendor/github.com/minio/minio-go/v7/hook-reader.go +++ b/vendor/github.com/minio/minio-go/v7/hook-reader.go @@ -25,22 +25,31 @@ import ( // hookReader hooks additional reader in the source stream. It is // useful for making progress bars. Second reader is appropriately // notified about the exact number of bytes read from the primary -// source on each Read operation. +// source on each Read operation. It deliberately implements neither +// io.Seeker nor io.Closer: retry logic treats a seekable body as +// rewindable, and executeMethod closes request bodies that implement +// io.Closer — a caller-supplied reader must be shielded from both. type hookReader struct { source io.Reader hook io.Reader } +// hookReadSeeker extends hookReader with seeking support. It is +// constructed only when the source implements io.Seeker, so a wrapped +// reader exposes Seek if and only if it can actually rewind. This lets +// retry logic disable retries for non-seekable bodies instead of +// retrying over a drained reader. +type hookReadSeeker struct { + hookReader + seeker io.Seeker +} + // Seek implements io.Seeker. Seeks source first, and if necessary // seeks hook if Seek method is appropriately found. -func (hr *hookReader) Seek(offset int64, whence int) (n int64, err error) { - // Verify for source has embedded Seeker, use it. - sourceSeeker, ok := hr.source.(io.Seeker) - if ok { - n, err = sourceSeeker.Seek(offset, whence) - if err != nil { - return 0, err - } +func (hr *hookReadSeeker) Seek(offset int64, whence int) (n int64, err error) { + n, err = hr.seeker.Seek(offset, whence) + if err != nil { + return 0, err } if hr.hook != nil { @@ -53,7 +62,7 @@ func (hr *hookReader) Seek(offset int64, whence int) (n int64, err error) { return 0, err } if n != m { - return 0, fmt.Errorf("hook seeker seeked %d bytes, expected source %d bytes", m, n) + return 0, fmt.Errorf("hook seeker sought to offset %d, expected source offset %d", m, n) } } } @@ -80,14 +89,13 @@ func (hr *hookReader) Read(b []byte) (n int, err error) { return n, err } -// newHook returns a io.ReadSeeker which implements hookReader that -// reports the data read from the source to the hook. +// newHook returns an io.Reader that reports the data read from the +// source to the hook. The returned reader implements io.Seeker only +// when the source does. func newHook(source, hook io.Reader) io.Reader { - if hook == nil { - return &hookReader{source: source} - } - return &hookReader{ - source: source, - hook: hook, + hr := hookReader{source: source, hook: hook} + if seeker, ok := source.(io.Seeker); ok { + return &hookReadSeeker{hookReader: hr, seeker: seeker} } + return &hr } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go index 415b0709520..41225e4cf2f 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go @@ -19,6 +19,7 @@ package credentials import ( "bytes" + "context" "crypto/sha256" "encoding/hex" "encoding/xml" @@ -142,7 +143,7 @@ func closeResponse(resp *http.Response) { } } -func getAssumeRoleCredentials(clnt *http.Client, endpoint string, opts STSAssumeRoleOptions) (AssumeRoleResponse, error) { +func getAssumeRoleCredentials(ctx context.Context, clnt *http.Client, endpoint string, opts STSAssumeRoleOptions) (AssumeRoleResponse, error) { v := url.Values{} v.Set("Action", "AssumeRole") v.Set("Version", STSVersion) @@ -180,7 +181,7 @@ func getAssumeRoleCredentials(clnt *http.Client, endpoint string, opts STSAssume } postBody.Seek(0, 0) - req, err := http.NewRequest(http.MethodPost, u.String(), postBody) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), postBody) if err != nil { return AssumeRoleResponse{}, err } @@ -245,7 +246,7 @@ func (m *STSAssumeRole) RetrieveWithCredContext(cc *CredContext) (Value, error) return Value{}, errors.New("STS endpoint unknown") } - a, err := getAssumeRoleCredentials(client, stsEndpoint, m.Options) + a, err := getAssumeRoleCredentials(cc.requestContext(), client, stsEndpoint, m.Options) if err != nil { return Value{}, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials-sso.sample b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials-sso.sample new file mode 100644 index 00000000000..46af924b30a --- /dev/null +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials-sso.sample @@ -0,0 +1,57 @@ +[profile p1] +sso_session = main +sso_account_id = 123456789 +sso_role_name = myrole + +[sso-session main] +sso_region = us-test-2 +sso_start_url = https://testacct.awsapps.com/start + +[profile p2-legacy] +sso_start_url = https://legacy.awsapps.com/start +sso_region = us-test-1 +sso_account_id = 987654321 +sso_role_name = legacyrole + +[profile p3-broken] +sso_account_id = 111111111 +sso_role_name = brokenrole + +[profile p4-noregion] +sso_start_url = https://noregion.awsapps.com/start +sso_account_id = 222222222 +sso_role_name = noregionrole + +[profile p5-ghost-session] +sso_session = ghost +sso_account_id = 333333333 +sso_role_name = ghostrole + +[profile p6-norole] +sso_start_url = https://norole.awsapps.com/start +sso_region = us-test-1 +sso_account_id = 444444444 + +[profile p7-noaccount] +sso_session = main +sso_role_name = noaccountrole + +[profile p8-mixed] +sso_start_url = https://mixed.awsapps.com/start +aws_access_key_id = mixedAccessKey +aws_secret_access_key = mixedSecret + +[profile p9-mixed-complete] +sso_session = main +sso_account_id = 555555555 +sso_role_name = mixedcompleterole +aws_access_key_id = completeAccessKey +aws_secret_access_key = completeSecret + +[profile p10-partial-key] +sso_start_url = https://partial.awsapps.com/start +aws_access_key_id = partialAccessKey + +[profile p11-partial-secret] +sso_session = main +aws_secret_access_key = partialSecret diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go index 52aff9a57f6..dfc25c072a3 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go @@ -18,6 +18,7 @@ package credentials import ( + "context" "net/http" "sync" "time" @@ -85,6 +86,21 @@ type CredContext struct { // Endpoint specifies the MinIO endpoint that will be used if no // explicit endpoint is provided. Endpoint string + + // Context is the optional caller context. Cancellation and deadlines + // on it propagate to the HTTP requests the built-in providers make + // to fetch credentials, in addition to any provider-level timeout + // bound. A nil Context means no caller cancellation applies. + Context context.Context +} + +// requestContext returns the caller context carried by cc, or +// context.Background() when no Context is set. +func (cc *CredContext) requestContext() context.Context { + if cc.Context == nil { + return context.Background() + } + return cc.Context } // A Expiry provides shared expiration logic to be used by credentials diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go index 2d0336f92ec..204bcfa2b1a 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go @@ -18,8 +18,15 @@ package credentials import ( + "context" + "crypto/sha1" + "encoding/hex" "encoding/json" "errors" + "fmt" + "io" + "io/fs" + "net/http" "os" "os/exec" "path/filepath" @@ -29,7 +36,10 @@ import ( "gopkg.in/ini.v1" ) -// A externalProcessCredentials stores the output of a credential_process +// ssoPortalRequestTimeout bounds the AWS SSO portal role-credentials request. +const ssoPortalRequestTimeout = time.Minute + +// An externalProcessCredentials stores the output of a credential_process type externalProcessCredentials struct { Version int SessionToken string @@ -38,6 +48,34 @@ type externalProcessCredentials struct { Expiration time.Time } +// An ssoCredentials stores the response of fetching role credentials for +// an AWS SSO role from the SSO portal. +type ssoCredentials struct { + RoleCredentials ssoRoleCredentials `json:"roleCredentials"` +} + +// An ssoRoleCredentials stores the role-specific credentials portion of +// an SSO role credentials response. Expiration is milliseconds since +// the Unix epoch. +type ssoRoleCredentials struct { + AccessKeyID string `json:"accessKeyId"` + Expiration int64 `json:"expiration"` + SecretAccessKey string `json:"secretAccessKey"` + SessionToken string `json:"sessionToken"` +} + +func (s ssoRoleCredentials) expirationTime() time.Time { + return time.Unix(0, s.Expiration*int64(time.Millisecond)) +} + +// ssoCachedToken is the subset of the cached token file written by +// `aws sso login` under ~/.aws/sso/cache/ that we need. +type ssoCachedToken struct { + AccessToken string `json:"accessToken"` + ExpiresAt time.Time `json:"expiresAt"` + Region string `json:"region"` +} + // A FileAWSCredentials retrieves credentials from the current user's home // directory, and keeps track if those credentials are expired. // @@ -47,10 +85,15 @@ type FileAWSCredentials struct { // Path to the shared credentials file. // - // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the - // env value is empty will default to current user's home directory. - // Linux/OSX: "$HOME/.aws/credentials" - // Windows: "%USERPROFILE%\.aws\credentials" + // If empty, the default AWS files are merged instead: the AWS config + // file ("AWS_CONFIG_FILE" env variable or "$HOME/.aws/config") loaded + // first, then the shared credentials file + // ("AWS_SHARED_CREDENTIALS_FILE" env variable or + // "$HOME/.aws/credentials") overriding matching keys, the same + // resolution the AWS SDK uses. Profiles written by `aws configure sso` + // live in the config file and are discovered this way. + // + // If set, only this one file is read. Filename string // AWS Profile to extract credentials from the shared credentials file. If empty @@ -60,6 +103,14 @@ type FileAWSCredentials struct { // retrieved states if the credentials have been successfully retrieved. retrieved bool + + // overrideSSOCacheDir overrides, for tests, the directory holding the + // cached SSO tokens (defaults to ~/.aws/sso/cache). + overrideSSOCacheDir string + + // overrideSSOPortalURL overrides, for tests, the AWS SSO portal URL + // serving role credentials. + overrideSSOPortalURL string } // NewFileAWSCredentials returns a pointer to a new Credentials object @@ -71,27 +122,27 @@ func NewFileAWSCredentials(filename, profile string) *Credentials { }) } -func (p *FileAWSCredentials) retrieve() (Value, error) { - if p.Filename == "" { - p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE") - if p.Filename == "" { - homeDir, err := os.UserHomeDir() - if err != nil { - return Value{}, err - } - p.Filename = filepath.Join(homeDir, ".aws", "credentials") - } - } - if p.Profile == "" { - p.Profile = os.Getenv("AWS_PROFILE") - if p.Profile == "" { - p.Profile = "default" +func (p *FileAWSCredentials) retrieve(cc *CredContext) (Value, error) { + profile := p.Profile + if profile == "" { + profile = os.Getenv("AWS_PROFILE") + if profile == "" { + profile = "default" } } p.retrieved = false - iniProfile, err := loadProfile(p.Filename, p.Profile) + var ( + iniConfig *ini.File + iniProfile *ini.Section + err error + ) + if p.Filename != "" { + iniConfig, iniProfile, err = loadProfile(p.Filename, profile) + } else { + iniConfig, iniProfile, err = loadDefaultProfiles(profile) + } if err != nil { return Value{}, err } @@ -103,10 +154,53 @@ func (p *FileAWSCredentials) retrieve() (Value, error) { // Default to empty string if not found. token := iniProfile.Key("aws_session_token") - // If credential_process is defined, obtain credentials by executing - // the external process + // A complete static key pair takes precedence over SSO configuration + // and credential_process in the same profile, matching aws-sdk-go-v2's + // resolution order: static credentials, then SSO, then + // credential_process. + hasStaticKeys := id.String() != "" && secret.String() != "" + + // Exactly one half of a static key pair is never usable and poisons + // downstream consumers — Chain accepts a Value when either field is + // set — so it is rejected before any resolution, matching + // aws-sdk-go-v2's partial-credentials validation. + if !hasStaticKeys && (id.String() != "" || secret.String() != "") { + return Value{}, errors.New("profile has partial static credentials: aws_access_key_id and aws_secret_access_key must both be set") + } + + // If the profile is configured for AWS SSO, obtain credentials from the + // token cached by `aws sso login`. + if !hasStaticKeys && iniProfile.Key("sso_role_name").String() != "" { + ssoCreds, err := p.getSSOCredentials(cc, iniConfig, iniProfile) + if err != nil { + return Value{}, err + } + expiration := ssoCreds.RoleCredentials.expirationTime() + p.retrieved = true + p.SetExpiration(expiration, DefaultExpiryWindow) + return Value{ + AccessKeyID: ssoCreds.RoleCredentials.AccessKeyID, + SecretAccessKey: ssoCreds.RoleCredentials.SecretAccessKey, + SessionToken: ssoCreds.RoleCredentials.SessionToken, + Expiration: expiration, + SignerType: SignatureV4, + }, nil + } + + // A profile carrying SSO configuration without sso_role_name cannot + // engage the SSO flow above; without a complete static key pair the + // values below would be anonymous. + if !hasStaticKeys && + (iniProfile.Key("sso_session").String() != "" || iniProfile.Key("sso_start_url").String() != "" || + iniProfile.Key("sso_account_id").String() != "" || iniProfile.Key("sso_region").String() != "") { + return Value{}, errors.New("profile has SSO configuration but no sso_role_name, and no complete static credentials") + } + + // If credential_process is defined, obtain credentials by executing the + // external process. Static credentials and SSO in the same profile both + // take precedence over it, matching aws-sdk-go-v2. credentialProcess := strings.TrimSpace(iniProfile.Key("credential_process").String()) - if credentialProcess != "" { + if !hasStaticKeys && credentialProcess != "" { args := strings.Fields(credentialProcess) if len(args) <= 1 { return Value{}, errors.New("invalid credential process args") @@ -131,6 +225,7 @@ func (p *FileAWSCredentials) retrieve() (Value, error) { SignerType: SignatureV4, }, nil } + p.retrieved = true return Value{ AccessKeyID: id.String(), @@ -140,28 +235,319 @@ func (p *FileAWSCredentials) retrieve() (Value, error) { }, nil } +// getSSOCredentials fetches role credentials for an SSO-configured profile +// from the AWS SSO portal, using the access token cached by `aws sso login`. +func (p *FileAWSCredentials) getSSOCredentials(cc *CredContext, iniConfig *ini.File, iniProfile *ini.Section) (ssoCredentials, error) { + ssoAccountID := iniProfile.Key("sso_account_id").String() + ssoRoleName := iniProfile.Key("sso_role_name").String() + if ssoAccountID == "" { + return ssoCredentials{}, errors.New("profile defines sso_role_name but no sso_account_id") + } + + // Modern config: the profile references an [sso-session ] section + // and the cached token file is named after the SHA1 of the session name. + // Legacy config: sso_start_url/sso_region live directly on the profile + // and the cached token file is named after the SHA1 of the start URL. + ssoSessionName := iniProfile.Key("sso_session").String() + cacheKey := ssoSessionName + ssoRegion := iniProfile.Key("sso_region").String() + if ssoSessionName != "" { + if sessionSection, err := iniConfig.GetSection("sso-session " + ssoSessionName); err == nil { + // aws-sdk-go-v2 rejects profile sso_region/sso_start_url + // values that contradict the sso-session; guessing between + // the two could silently query the wrong portal. + if region := sessionSection.Key("sso_region").String(); region != "" { + if ssoRegion != "" && ssoRegion != region { + return ssoCredentials{}, fmt.Errorf("sso_region %q in profile must match sso_region %q in sso-session %q", ssoRegion, region, ssoSessionName) + } + ssoRegion = region + } + if sessionStartURL := sessionSection.Key("sso_start_url").String(); sessionStartURL != "" { + if profileStartURL := iniProfile.Key("sso_start_url").String(); profileStartURL != "" && profileStartURL != sessionStartURL { + return ssoCredentials{}, fmt.Errorf("sso_start_url %q in profile must match sso_start_url %q in sso-session %q", profileStartURL, sessionStartURL, ssoSessionName) + } + } + } + } else { + startURL := iniProfile.Key("sso_start_url").String() + if startURL == "" { + return ssoCredentials{}, errors.New("profile defines sso_role_name but neither sso_session nor sso_start_url") + } + cacheKey = startURL + } + + hash := sha1.Sum([]byte(cacheKey)) + cachedTokenFilename := hex.EncodeToString(hash[:]) + ".json" + + cacheDir := p.overrideSSOCacheDir + if cacheDir == "" { + homeDir, err := os.UserHomeDir() + if err != nil { + return ssoCredentials{}, fmt.Errorf("getting home dir: %w", err) + } + cacheDir = filepath.Join(homeDir, ".aws", "sso", "cache") + } + cachedTokenPath := filepath.Join(cacheDir, cachedTokenFilename) + cachedTokenRaw, err := os.ReadFile(cachedTokenPath) + if err != nil { + return ssoCredentials{}, fmt.Errorf("reading cached SSO token %q (try `aws sso login`): %w", cachedTokenPath, err) + } + + var cachedToken ssoCachedToken + if err := json.Unmarshal(cachedTokenRaw, &cachedToken); err != nil { + return ssoCredentials{}, fmt.Errorf("parsing cached SSO token %q: %w", cachedTokenPath, err) + } + now := time.Now + if p.CurrentTime != nil { + now = p.CurrentTime + } + if cachedToken.ExpiresAt.Before(now()) { + return ssoCredentials{}, errors.New("cached SSO token is expired, refresh it with `aws sso login`") + } + + if ssoRegion == "" { + ssoRegion = cachedToken.Region + } + if ssoRegion == "" { + return ssoCredentials{}, errors.New("unable to determine AWS SSO region from profile, sso-session or cached token") + } + + portalURL := p.overrideSSOPortalURL + if portalURL == "" { + portalURL = ssoPortalBaseURL(ssoRegion) + } + if cc == nil { + cc = defaultCredContext + } + ctx, cancel := context.WithTimeout(cc.requestContext(), ssoPortalRequestTimeout) + defer cancel() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, portalURL+"/federation/credentials", nil) + if err != nil { + return ssoCredentials{}, fmt.Errorf("creating SSO role credentials request: %w", err) + } + req.Header.Set("x-amz-sso_bearer_token", cachedToken.AccessToken) + query := req.URL.Query() + query.Add("account_id", ssoAccountID) + query.Add("role_name", ssoRoleName) + req.URL.RawQuery = query.Encode() + + client := cc.Client + if client == nil { + client = defaultCredContext.Client + } + resp, err := client.Do(req) + if err != nil { + return ssoCredentials{}, fmt.Errorf("fetching SSO role credentials: %w", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10)) + return ssoCredentials{}, fmt.Errorf("fetching SSO role credentials: %s: %s", resp.Status, strings.TrimSpace(string(body))) + } + + var ssoCreds ssoCredentials + if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&ssoCreds); err != nil { + return ssoCredentials{}, fmt.Errorf("parsing SSO role credentials response: %w", err) + } + if ssoCreds.RoleCredentials.AccessKeyID == "" || ssoCreds.RoleCredentials.SecretAccessKey == "" { + return ssoCredentials{}, errors.New("SSO portal returned empty role credentials") + } + return ssoCreds, nil +} + +// ssoPortalBaseURL returns the AWS SSO portal endpoint for region. The DNS +// suffix follows the region's AWS partition per aws-sdk-go-v2 endpoint +// metadata; regions of unlisted partitions, including aws-us-gov, use the +// standard amazonaws.com suffix. +func ssoPortalBaseURL(region string) string { + suffix := "amazonaws.com" + switch { + case strings.HasPrefix(region, "cn-"): + suffix = "amazonaws.com.cn" + case strings.HasPrefix(region, "us-iso-"): + suffix = "c2s.ic.gov" + case strings.HasPrefix(region, "us-isob-"): + suffix = "sc2s.sgov.gov" + case strings.HasPrefix(region, "eu-isoe-"): + suffix = "cloud.adc-e.uk" + case strings.HasPrefix(region, "us-isof-"): + suffix = "csp.hci.ic.gov" + case strings.HasPrefix(region, "eusc-"): + suffix = "amazonaws.eu" + } + return fmt.Sprintf("https://portal.sso.%s.%s", region, suffix) +} + // Retrieve reads and extracts the shared credentials from the current // users home directory. +// +// Deprecated: Retrieve() exists for historical compatibility and should not +// be used. To get new credentials use the RetrieveWithCredContext function. func (p *FileAWSCredentials) Retrieve() (Value, error) { - return p.retrieve() + return p.retrieve(nil) } -// RetrieveWithCredContext is like Retrieve(), cred context is no-op for File credentials -func (p *FileAWSCredentials) RetrieveWithCredContext(_ *CredContext) (Value, error) { - return p.retrieve() +// RetrieveWithCredContext retrieves credentials from the file like Retrieve, +// using the context's HTTP client for any SSO portal call. +func (p *FileAWSCredentials) RetrieveWithCredContext(cc *CredContext) (Value, error) { + return p.retrieve(cc) } -// loadProfiles loads from the file pointed to by shared credentials filename for profile. +// loadProfile loads from the file pointed to by shared credentials filename for profile. // The credentials retrieved from the profile will be returned or error. Error will be // returned if it fails to read from the file, or the data is invalid. -func loadProfile(filename, profile string) (*ini.Section, error) { +func loadProfile(filename, profile string) (*ini.File, *ini.Section, error) { config, err := ini.Load(filename) if err != nil { - return nil, err + return nil, nil, err } iniProfile, err := config.GetSection(profile) if err != nil { - return nil, err + // AWS config files (~/.aws/config) name non-default profile + // sections "profile ". + var sectionErr error + iniProfile, sectionErr = config.GetSection("profile " + profile) + if sectionErr != nil { + return nil, nil, err + } + } + return config, iniProfile, nil +} + +// loadDefaultProfiles loads profile from the default AWS files, mirroring +// the AWS SDK's shared-config resolution: the config file (AWS_CONFIG_FILE +// or ~/.aws/config) is loaded first and the shared credentials file +// (AWS_SHARED_CREDENTIALS_FILE or ~/.aws/credentials) overrides matching +// keys. A missing file is tolerated as long as the other one loads; a file +// that exists but fails to parse aborts resolution, like aws-sdk-go-v2, +// because silently skipping it could resolve credentials from the wrong +// (lower-precedence) source. +func loadDefaultProfiles(profile string) (*ini.File, *ini.Section, error) { + configFilename := os.Getenv("AWS_CONFIG_FILE") + credsFilename := os.Getenv("AWS_SHARED_CREDENTIALS_FILE") + var loadErrs []error + if configFilename == "" || credsFilename == "" { + // A home-dir failure only rules out the files defaulted under it; + // a file named via env var must still load. + homeDir, err := os.UserHomeDir() + if err != nil { + loadErrs = append(loadErrs, err) + } else { + if configFilename == "" { + configFilename = filepath.Join(homeDir, ".aws", "config") + } + if credsFilename == "" { + credsFilename = filepath.Join(homeDir, ".aws", "credentials") + } + } + } + + merged := ini.Empty() + loaded := false + if configFilename != "" { + config, err := ini.Load(configFilename) + switch { + case err == nil: + loaded = true + mergeAWSConfigSections(merged, config) + case errors.Is(err, fs.ErrNotExist): + loadErrs = append(loadErrs, err) + default: + return nil, nil, err + } + } + if credsFilename != "" { + config, err := ini.Load(credsFilename) + switch { + case err == nil: + loaded = true + mergeAWSCredentialsSections(merged, config) + case errors.Is(err, fs.ErrNotExist): + loadErrs = append(loadErrs, err) + default: + return nil, nil, err + } + } + if !loaded { + // Prefer the home-dir error when there is one (the informative + // failure); otherwise return the last not-exist error bare so the + // legacy os.IsNotExist probe on a missing-files result keeps working. + err := loadErrs[len(loadErrs)-1] + for _, e := range loadErrs { + if !errors.Is(e, fs.ErrNotExist) { + err = e + break + } + } + return nil, nil, err + } + iniProfile, err := merged.GetSection(profile) + if err != nil { + return nil, nil, err + } + return merged, iniProfile, nil +} + +// mergeAWSConfigSections copies the AWS config file's sections into dst +// under the SDK's config-file rules: bare sections other than "default" and +// "sso-session " are invalid profile names and ignored, and a +// "profile " section is renamed to , replacing a bare +// same-named section wholesale rather than merging with it. +func mergeAWSConfigSections(dst, src *ini.File) { + for _, section := range src.Sections() { + name := section.Name() + if name == ini.DefaultSection || strings.HasPrefix(name, "profile ") || + (!strings.EqualFold(name, "default") && !strings.HasPrefix(name, "sso-session ")) { + continue + } + copySectionKeys(dst.Section(name), section) + } + for _, section := range src.Sections() { + name := section.Name() + if !strings.HasPrefix(name, "profile ") { + continue + } + dstSection := dst.Section(strings.TrimPrefix(name, "profile ")) + for _, key := range dstSection.Keys() { + dstSection.DeleteKey(key.Name()) + } + copySectionKeys(dstSection, section) + } +} + +// mergeAWSCredentialsSections copies the shared credentials file's sections +// into dst, overriding matching keys; "profile "-prefixed section names are +// invalid in the credentials file and ignored. When a section overrides an +// existing profile, the static credentials move atomically: +// aws_access_key_id, aws_secret_access_key and aws_session_token are only +// taken from an overriding section carrying the complete key pair, so a +// partial pair cannot clobber half of an existing one. A section new to +// the merge is copied as-is; a partial pair it carries is rejected at +// resolution time, matching aws-sdk-go-v2's partial-credentials error. +func mergeAWSCredentialsSections(dst, src *ini.File) { + for _, section := range src.Sections() { + name := section.Name() + if name == ini.DefaultSection || strings.HasPrefix(name, "profile ") { + continue + } + _, err := dst.GetSection(name) + newSection := err != nil + hasPair := section.HasKey("aws_access_key_id") && section.HasKey("aws_secret_access_key") + dstSection := dst.Section(name) + for _, key := range section.Keys() { + switch key.Name() { + case "aws_access_key_id", "aws_secret_access_key", "aws_session_token": + if !newSection && !hasPair { + continue + } + } + dstSection.Key(key.Name()).SetValue(key.Value()) + } + } +} + +func copySectionKeys(dst, src *ini.Section) { + for _, key := range src.Keys() { + dst.Key(key.Name()).SetValue(key.Value()) } - return iniProfile, nil } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go index f4f7c8f7e29..f35d9d6598a 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go @@ -58,6 +58,17 @@ type IAM struct { // Region configurable custom region for STS Region string + // ExpiryWindow configures how long before the actual credential + // expiration the credentials are considered expired and refreshed. + // The zero value keeps the default behavior of refreshing once 80% + // of the credential lifetime has elapsed. A positive value refreshes + // that long before the actual expiration; a value that meets or + // exceeds the credential lifetime places the effective expiration at + // or before the moment of retrieval, so the credentials are refreshed + // on every subsequent retrieval. A negative value behaves like the + // default. + ExpiryWindow time.Duration + // Support for container authorization token https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html Container struct { AuthorizationToken string @@ -94,6 +105,15 @@ func NewIAM(endpoint string) *Credentials { }) } +// expiryWindow returns the configured ExpiryWindow, falling back to +// DefaultExpiryWindow when unset or negative. +func (m *IAM) expiryWindow() time.Duration { + if m.ExpiryWindow <= 0 { + return DefaultExpiryWindow + } + return m.ExpiryWindow +} + // RetrieveWithCredContext is like Retrieve with Cred Context func (m *IAM) RetrieveWithCredContext(cc *CredContext) (Value, error) { if cc == nil { @@ -151,6 +171,8 @@ func (m *IAM) RetrieveWithCredContext(cc *CredContext) (Value, error) { client = defaultCredContext.Client } + ctx := cc.requestContext() + endpoint := m.Endpoint switch { @@ -184,7 +206,11 @@ func (m *IAM) RetrieveWithCredContext(cc *CredContext) (Value, error) { stsWebIdentityCreds, err := creds.RetrieveWithCredContext(cc) if err == nil { - m.SetExpiration(creds.Expiration(), DefaultExpiryWindow) + // Use the raw credential expiration, not creds.Expiration(): + // the inner provider has already reduced its own expiration by + // DefaultExpiryWindow, and applying a window to the reduced + // value would compound the two. + m.SetExpiration(stsWebIdentityCreds.Expiration, m.expiryWindow()) } return stsWebIdentityCreds, err @@ -193,11 +219,11 @@ func (m *IAM) RetrieveWithCredContext(cc *CredContext) (Value, error) { endpoint = fmt.Sprintf("%s%s", DefaultECSRoleEndpoint, relativeURI) } - roleCreds, err = getEcsTaskCredentials(client, endpoint, token) + roleCreds, err = getEcsTaskCredentials(ctx, client, endpoint, token) case tokenFile != "" && fullURI != "": endpoint = fullURI - roleCreds, err = getEKSPodIdentityCredentials(client, endpoint, tokenFile) + roleCreds, err = getEKSPodIdentityCredentials(ctx, client, endpoint, tokenFile) case fullURI != "": if len(endpoint) == 0 { @@ -211,17 +237,16 @@ func (m *IAM) RetrieveWithCredContext(cc *CredContext) (Value, error) { } } - roleCreds, err = getEcsTaskCredentials(client, endpoint, token) + roleCreds, err = getEcsTaskCredentials(ctx, client, endpoint, token) default: - roleCreds, err = getCredentials(client, endpoint) + roleCreds, err = getCredentials(ctx, client, endpoint) } if err != nil { return Value{}, err } - // Expiry window is set to 10secs. - m.SetExpiration(roleCreds.Expiration, DefaultExpiryWindow) + m.SetExpiration(roleCreds.Expiration, m.expiryWindow()) return Value{ AccessKeyID: roleCreds.AccessKeyID, @@ -273,8 +298,8 @@ func getIAMRoleURL(endpoint string) (*url.URL, error) { // with the current EC2 service. If there are no credentials, // or there is an error making or receiving the request. // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html -func listRoleNames(client *http.Client, u *url.URL, token string) ([]string, error) { - req, err := http.NewRequest(http.MethodGet, u.String(), nil) +func listRoleNames(ctx context.Context, client *http.Client, u *url.URL, token string) ([]string, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { return nil, err } @@ -303,8 +328,8 @@ func listRoleNames(client *http.Client, u *url.URL, token string) ([]string, err return credsList, nil } -func getEcsTaskCredentials(client *http.Client, endpoint, token string) (ec2RoleCredRespBody, error) { - req, err := http.NewRequest(http.MethodGet, endpoint, nil) +func getEcsTaskCredentials(ctx context.Context, client *http.Client, endpoint, token string) (ec2RoleCredRespBody, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil) if err != nil { return ec2RoleCredRespBody{}, err } @@ -330,20 +355,20 @@ func getEcsTaskCredentials(client *http.Client, endpoint, token string) (ec2Role return respCreds, nil } -func getEKSPodIdentityCredentials(client *http.Client, endpoint string, tokenFile string) (ec2RoleCredRespBody, error) { +func getEKSPodIdentityCredentials(ctx context.Context, client *http.Client, endpoint string, tokenFile string) (ec2RoleCredRespBody, error) { if tokenFile != "" { bytes, err := os.ReadFile(tokenFile) if err != nil { return ec2RoleCredRespBody{}, fmt.Errorf("getEKSPodIdentityCredentials: failed to read token file:%s", err) } token := string(bytes) - return getEcsTaskCredentials(client, endpoint, token) + return getEcsTaskCredentials(ctx, client, endpoint, token) } return ec2RoleCredRespBody{}, fmt.Errorf("getEKSPodIdentityCredentials: no tokenFile found") } -func fetchIMDSToken(client *http.Client, endpoint string) (string, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) +func fetchIMDSToken(ctx context.Context, client *http.Client, endpoint string) (string, error) { + ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint+TokenPath, nil) @@ -371,14 +396,18 @@ func fetchIMDSToken(client *http.Client, endpoint string) (string, error) { // // If the credentials cannot be found, or there is an error // reading the response an error will be returned. -func getCredentials(client *http.Client, endpoint string) (ec2RoleCredRespBody, error) { +func getCredentials(ctx context.Context, client *http.Client, endpoint string) (ec2RoleCredRespBody, error) { if endpoint == "" { endpoint = DefaultIAMRoleEndpoint } // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html - token, err := fetchIMDSToken(client, endpoint) + token, err := fetchIMDSToken(ctx, client, endpoint) if err != nil { + // A dead caller context is not an IMDSv2 availability signal. + if cerr := ctx.Err(); cerr != nil { + return ec2RoleCredRespBody{}, fmt.Errorf("%w (imds token fetch: %v)", cerr, err) + } // Return only errors for valid situations, if the IMDSv2 is not enabled // we will not be able to get the token, in such a situation we have // to rely on IMDSv1 behavior as a fallback, this check ensures that. @@ -395,7 +424,7 @@ func getCredentials(client *http.Client, endpoint string) (ec2RoleCredRespBody, } // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html - roleNames, err := listRoleNames(client, u, token) + roleNames, err := listRoleNames(ctx, client, u, token) if err != nil { return ec2RoleCredRespBody{}, err } @@ -415,7 +444,7 @@ func getCredentials(client *http.Client, endpoint string) (ec2RoleCredRespBody, // $ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access // u.Path = path.Join(u.Path, roleName) - req, err := http.NewRequest(http.MethodGet, u.String(), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { return ec2RoleCredRespBody{}, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go index ef6f436b84b..7ab7d68ef94 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go @@ -19,6 +19,7 @@ package credentials import ( "bytes" + "context" "encoding/xml" "errors" "fmt" @@ -100,7 +101,7 @@ func NewSTSClientGrants(stsEndpoint string, getClientGrantsTokenExpiry func() (* }), nil } -func getClientGrantsCredentials(clnt *http.Client, endpoint string, +func getClientGrantsCredentials(ctx context.Context, clnt *http.Client, endpoint string, getClientGrantsTokenExpiry func() (*ClientGrantsToken, error), ) (AssumeRoleWithClientGrantsResponse, error) { accessToken, err := getClientGrantsTokenExpiry() @@ -119,7 +120,7 @@ func getClientGrantsCredentials(clnt *http.Client, endpoint string, return AssumeRoleWithClientGrantsResponse{}, err } - req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode())) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), strings.NewReader(v.Encode())) if err != nil { return AssumeRoleWithClientGrantsResponse{}, err } @@ -179,7 +180,7 @@ func (m *STSClientGrants) RetrieveWithCredContext(cc *CredContext) (Value, error return Value{}, errors.New("STS endpoint unknown") } - a, err := getClientGrantsCredentials(client, stsEndpoint, m.GetClientGrantsTokenExpiry) + a, err := getClientGrantsCredentials(cc.requestContext(), client, stsEndpoint, m.GetClientGrantsTokenExpiry) if err != nil { return Value{}, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go index e9e7a1151f1..b986c175f7e 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go @@ -107,7 +107,7 @@ func (c *CustomTokenIdentity) RetrieveWithCredContext(cc *CredContext) (value Va u.RawQuery = v.Encode() - req, err := http.NewRequest(http.MethodPost, u.String(), nil) + req, err := http.NewRequestWithContext(cc.requestContext(), http.MethodPost, u.String(), nil) if err != nil { return value, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go index 7e80cd6a2ac..648c95d273a 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go @@ -172,7 +172,7 @@ func (k *LDAPIdentity) RetrieveWithCredContext(cc *CredContext) (value Value, er v.Set("ConfigName", k.ConfigName) } - req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode())) + req, err := http.NewRequestWithContext(cc.requestContext(), http.MethodPost, u.String(), strings.NewReader(v.Encode())) if err != nil { return value, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go index beab4a6a648..ebaae128066 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go @@ -131,7 +131,7 @@ func (i *STSCertificateIdentity) RetrieveWithCredContext(cc *CredContext) (Value } endpointURL.RawQuery = queryValues.Encode() - req, err := http.NewRequest(http.MethodPost, endpointURL.String(), nil) + req, err := http.NewRequestWithContext(cc.requestContext(), http.MethodPost, endpointURL.String(), nil) if err != nil { return Value{}, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go index a9987255ec7..c3afdc6299d 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go @@ -19,6 +19,7 @@ package credentials import ( "bytes" + "context" "encoding/xml" "errors" "fmt" @@ -137,7 +138,7 @@ func WithPolicy(policy string) func(*STSWebIdentity) { } } -func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string, policy string, +func getWebIdentityCredentials(ctx context.Context, clnt *http.Client, endpoint, roleARN, roleSessionName string, policy string, getWebIDTokenExpiry func() (*WebIdentityToken, error), tokenRevokeType string, ) (AssumeRoleWithWebIdentityResponse, error) { idToken, err := getWebIDTokenExpiry() @@ -180,7 +181,7 @@ func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSession return AssumeRoleWithWebIdentityResponse{}, err } - req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode())) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), strings.NewReader(v.Encode())) if err != nil { return AssumeRoleWithWebIdentityResponse{}, err } @@ -242,7 +243,7 @@ func (m *STSWebIdentity) RetrieveWithCredContext(cc *CredContext) (Value, error) return Value{}, errors.New("STS endpoint unknown") } - a, err := getWebIdentityCredentials(client, stsEndpoint, m.RoleARN, m.roleSessionName, m.Policy, m.GetWebIDTokenExpiry, m.TokenRevokeType) + a, err := getWebIdentityCredentials(cc.requestContext(), client, stsEndpoint, m.RoleARN, m.roleSessionName, m.Policy, m.GetWebIDTokenExpiry, m.TokenRevokeType) if err != nil { return Value{}, err } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go index 01d4e6aa798..2ae38b85a7e 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go @@ -209,6 +209,58 @@ func (t Transition) MarshalXML(en *xml.Encoder, startElement xml.StartElement) e return en.EncodeElement(transitionWrapper(t), startElement) } +// Compression is a MinIO AIStor extension with no S3 equivalent: it compresses +// matching current object versions in place. Presence of the element enables the +// action, so Rule carries it as a pointer — unlike Transition, there is no +// StorageClass to key presence off and Days: 0 legitimately means "immediately". +// +// HighCompression selects the strongest level the server offers; without it the +// rule writes the level ingest uses and only compresses objects stored +// uncompressed. +// +// Unlike Transition and Expiration there is no absolute Date trigger — a one-off +// sweep is what the compress batch job is for. That also means no custom +// MarshalJSON: with no embedded time.Time to suppress, every field honors +// omitempty, and a zero element still marshals as {} because Rule holds it as a +// pointer and its presence alone enables the action. +type Compression struct { + XMLName xml.Name `xml:"Compression" json:"-"` + Days ExpirationDays `xml:"Days,omitempty" json:"Days,omitempty"` + HighCompression bool `xml:"HighCompression,omitempty" json:"HighCompression,omitempty"` + SkipCompressed bool `xml:"SkipCompressed,omitempty" json:"SkipCompressed,omitempty"` + IncludeEncrypted bool `xml:"IncludeEncrypted,omitempty" json:"IncludeEncrypted,omitempty"` +} + +// IsDaysNull returns true if days field is null +func (c *Compression) IsDaysNull() bool { + return c == nil || c.Days == ExpirationDays(0) +} + +// IsNull returns true if the element is absent. +func (c *Compression) IsNull() bool { + return c == nil +} + +// NoncurrentVersionCompression is the Compression counterpart for noncurrent +// object versions. See Compression for why Rule holds it as a pointer. +type NoncurrentVersionCompression struct { + XMLName xml.Name `xml:"NoncurrentVersionCompression" json:"-"` + NoncurrentDays ExpirationDays `xml:"NoncurrentDays,omitempty" json:"NoncurrentDays,omitempty"` + HighCompression bool `xml:"HighCompression,omitempty" json:"HighCompression,omitempty"` + SkipCompressed bool `xml:"SkipCompressed,omitempty" json:"SkipCompressed,omitempty"` + IncludeEncrypted bool `xml:"IncludeEncrypted,omitempty" json:"IncludeEncrypted,omitempty"` +} + +// IsDaysNull returns true if noncurrent days field is null +func (n *NoncurrentVersionCompression) IsDaysNull() bool { + return n == nil || n.NoncurrentDays == ExpirationDays(0) +} + +// IsNull returns true if the element is absent. +func (n *NoncurrentVersionCompression) IsNull() bool { + return n == nil +} + // And And Rule for LifecycleTag, to be used in LifecycleRuleFilter type And struct { XMLName xml.Name `xml:"And" json:"-"` @@ -265,12 +317,11 @@ func (f Filter) MarshalJSON() ([]byte, error) { } // MarshalXML - produces the xml representation of the Filter struct -// only one of Prefix, And and Tag should be present in the output. +// at most one of Prefix, And, Tag, ObjectSizeGreaterThan and +// ObjectSizeLessThan is present in the output. +// A zero-value Filter marshals as ; +// suppressing the element entirely is the caller's responsibility. func (f Filter) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - if f.IsNull() { - return nil - } - if err := e.EncodeToken(start); err != nil { return err } @@ -473,6 +524,8 @@ func (r Rule) MarshalJSON() ([]byte, error) { Prefix string `json:"Prefix,omitempty"` Status string `json:"Status"` Transition *Transition `json:"Transition,omitempty"` + Compression *Compression `json:"Compression,omitempty"` + NoncurrentVersionCompression *NoncurrentVersionCompression `json:"NoncurrentVersionCompression,omitempty"` } newr := rule{ Prefix: r.Prefix, @@ -504,10 +557,45 @@ func (r Rule) MarshalJSON() ([]byte, error) { if !r.AllVersionsExpiration.IsNull() { newr.AllVersionsExpiration = &r.AllVersionsExpiration } + newr.Compression = r.Compression + newr.NoncurrentVersionCompression = r.NoncurrentVersionCompression return json.Marshal(newr) } +// ruleAlias drops Rule's methods so EncodeElement falls back to the default +// struct-tag encoding. +type ruleAlias Rule + +// ruleWrapper embeds ruleAlias, so it needs no updating when Rule gains a +// field. Its RuleFilter is shallower than the embedded one, and encoding/xml's +// depth-based field shadowing suppresses the deeper field, so is +// emitted only through this pointer: nil omits the element, a set pointer +// emits it (empty) as the last child of . +type ruleWrapper struct { + ruleAlias + RuleFilter *Filter `xml:"Filter,omitempty"` +} + +// MarshalXML customizes XML encoding of Rule: a rule with neither Filter nor +// Prefix set emits an empty as the last +// child of — S3 requires a Filter when no Prefix element is present; +// the empty child is this library's representation of an empty +// filter. A rule with only a top-level Prefix omits the Filter element; a +// non-null Filter marshals through the default encoding in its declared +// field position. MarshalJSON is unaffected and still omits a null Filter. +func (r Rule) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if !r.RuleFilter.IsNull() { + return e.EncodeElement(ruleAlias(r), start) + } + + w := ruleWrapper{ruleAlias: ruleAlias(r)} + if r.Prefix == "" { + w.RuleFilter = &w.ruleAlias.RuleFilter + } + return e.EncodeElement(w, start) +} + // Rule represents a single rule in lifecycle configuration type Rule struct { XMLName xml.Name `xml:"Rule,omitempty" json:"-"` @@ -522,6 +610,8 @@ type Rule struct { Prefix string `xml:"Prefix,omitempty" json:"Prefix,omitempty"` Status string `xml:"Status" json:"Status"` Transition Transition `xml:"Transition,omitempty" json:"Transition,omitempty"` + Compression *Compression `xml:"Compression,omitempty" json:"Compression,omitempty"` + NoncurrentVersionCompression *NoncurrentVersionCompression `xml:"NoncurrentVersionCompression,omitempty" json:"NoncurrentVersionCompression,omitempty"` } // Configuration is a collection of Rule objects. diff --git a/vendor/github.com/minio/minio-go/v7/pkg/policy/bucket-policy-condition.go b/vendor/github.com/minio/minio-go/v7/pkg/policy/bucket-policy-condition.go new file mode 100644 index 00000000000..4d6d85cbc10 --- /dev/null +++ b/vendor/github.com/minio/minio-go/v7/pkg/policy/bucket-policy-condition.go @@ -0,0 +1,114 @@ +/* + * MinIO Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 MinIO, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package policy + +import ( + "github.com/minio/minio-go/v7/pkg/set" +) + +// ConditionKeyMap - map of policy condition key and value. +type ConditionKeyMap map[string]set.StringSet + +// Add - adds key and value. The value is appended If key already exists. +func (ckm ConditionKeyMap) Add(key string, value set.StringSet) { + if v, ok := ckm[key]; ok { + ckm[key] = v.Union(value) + } else { + ckm[key] = set.CopyStringSet(value) + } +} + +// Remove - removes value of given key. If key has empty after removal, the key is also removed. +func (ckm ConditionKeyMap) Remove(key string, value set.StringSet) { + if v, ok := ckm[key]; ok { + if value != nil { + ckm[key] = v.Difference(value) + } + + if ckm[key].IsEmpty() { + delete(ckm, key) + } + } +} + +// RemoveKey - removes key and its value. +func (ckm ConditionKeyMap) RemoveKey(key string) { + delete(ckm, key) +} + +// CopyConditionKeyMap - returns new copy of given ConditionKeyMap. +func CopyConditionKeyMap(condKeyMap ConditionKeyMap) ConditionKeyMap { + out := make(ConditionKeyMap) + + for k, v := range condKeyMap { + out[k] = set.CopyStringSet(v) + } + + return out +} + +// mergeConditionKeyMap - returns a new ConditionKeyMap which contains merged key/value of given two ConditionKeyMap. +func mergeConditionKeyMap(condKeyMap1, condKeyMap2 ConditionKeyMap) ConditionKeyMap { + out := CopyConditionKeyMap(condKeyMap1) + + for k, v := range condKeyMap2 { + if ev, ok := out[k]; ok { + out[k] = ev.Union(v) + } else { + out[k] = set.CopyStringSet(v) + } + } + + return out +} + +// ConditionMap - map of condition and conditional values. +type ConditionMap map[string]ConditionKeyMap + +// Add - adds condition key and condition value. The value is appended if key already exists. +func (cond ConditionMap) Add(condKey string, condKeyMap ConditionKeyMap) { + if v, ok := cond[condKey]; ok { + cond[condKey] = mergeConditionKeyMap(v, condKeyMap) + } else { + cond[condKey] = CopyConditionKeyMap(condKeyMap) + } +} + +// Remove - removes condition key and its value. +func (cond ConditionMap) Remove(condKey string) { + delete(cond, condKey) +} + +// mergeConditionMap - returns new ConditionMap which contains merged key/value of two ConditionMap. +func mergeConditionMap(condMap1, condMap2 ConditionMap) ConditionMap { + out := make(ConditionMap) + + for k, v := range condMap1 { + out[k] = CopyConditionKeyMap(v) + } + + for k, v := range condMap2 { + if ev, ok := out[k]; ok { + out[k] = mergeConditionKeyMap(ev, v) + } else { + out[k] = CopyConditionKeyMap(v) + } + } + + return out +} diff --git a/vendor/github.com/minio/minio-go/v7/pkg/policy/bucket-policy.go b/vendor/github.com/minio/minio-go/v7/pkg/policy/bucket-policy.go new file mode 100644 index 00000000000..762c9015622 --- /dev/null +++ b/vendor/github.com/minio/minio-go/v7/pkg/policy/bucket-policy.go @@ -0,0 +1,680 @@ +/* + * MinIO Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 MinIO, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package policy + +import ( + "encoding/json" + "errors" + "reflect" + "strings" + + "github.com/minio/minio-go/v7/pkg/set" +) + +// BucketPolicy - Bucket level policy. +type BucketPolicy string + +// Different types of Policies currently supported for buckets. +const ( + BucketPolicyNone BucketPolicy = "none" + BucketPolicyReadOnly BucketPolicy = "readonly" + BucketPolicyReadWrite BucketPolicy = "readwrite" + BucketPolicyWriteOnly BucketPolicy = "writeonly" +) + +// IsValidBucketPolicy - returns true if policy is valid and supported, false otherwise. +func (p BucketPolicy) IsValidBucketPolicy() bool { + switch p { + case BucketPolicyNone, BucketPolicyReadOnly, BucketPolicyReadWrite, BucketPolicyWriteOnly: + return true + } + return false +} + +// Resource prefix for all aws resources. +const awsResourcePrefix = "arn:aws:s3:::" + +// Common bucket actions for both read and write policies. +var commonBucketActions = set.CreateStringSet("s3:GetBucketLocation") + +// Read only bucket actions. +var readOnlyBucketActions = set.CreateStringSet("s3:ListBucket") + +// Write only bucket actions. +var writeOnlyBucketActions = set.CreateStringSet("s3:ListBucketMultipartUploads") + +// Read only object actions. +var readOnlyObjectActions = set.CreateStringSet("s3:GetObject") + +// Write only object actions. +var writeOnlyObjectActions = set.CreateStringSet("s3:AbortMultipartUpload", "s3:DeleteObject", "s3:ListMultipartUploadParts", "s3:PutObject") + +// Read and write object actions. +var readWriteObjectActions = readOnlyObjectActions.Union(writeOnlyObjectActions) + +// All valid bucket and object actions. +var validActions = commonBucketActions. + Union(readOnlyBucketActions). + Union(writeOnlyBucketActions). + Union(readOnlyObjectActions). + Union(writeOnlyObjectActions) + +var startsWithFunc = func(resource, resourcePrefix string) bool { + return strings.HasPrefix(resource, resourcePrefix) +} + +// User - canonical users list. +type User struct { + AWS set.StringSet `json:"AWS,omitempty"` + CanonicalUser set.StringSet `json:"CanonicalUser,omitempty"` +} + +// UnmarshalJSON is a custom json unmarshaler for Principal field, +// the reason is that Principal can take a json struct represented by +// User string but it can also take a string. +func (u *User) UnmarshalJSON(data []byte) error { + // Try to unmarshal data in a struct equal to User, + // to avoid infinite recursive call of this function + type AliasUser User + var au AliasUser + err := json.Unmarshal(data, &au) + if err == nil { + *u = User(au) + return nil + } + // Data type is not known, check if it is a json string + // which contains a star, which is permitted in the spec + var str string + err = json.Unmarshal(data, &str) + if err == nil { + if str != "*" { + return errors.New("unrecognized Principal field") + } + *u = User{AWS: set.CreateStringSet("*")} + return nil + } + return err +} + +// Statement - minio policy statement +type Statement struct { + Actions set.StringSet `json:"Action"` + Conditions ConditionMap `json:"Condition,omitempty"` + Effect string + Principal User `json:"Principal"` + Resources set.StringSet `json:"Resource"` + Sid string +} + +// BucketAccessPolicy - minio policy collection +type BucketAccessPolicy struct { + Version string // date in YYYY-MM-DD format + Statements []Statement `json:"Statement"` +} + +// isValidStatement - returns whether given statement is valid to process for given bucket name. +func isValidStatement(statement Statement, bucketName string) bool { + if statement.Actions.Intersection(validActions).IsEmpty() { + return false + } + + if statement.Effect != "Allow" { + return false + } + + if statement.Principal.AWS == nil || !statement.Principal.AWS.Contains("*") { + return false + } + + bucketResource := awsResourcePrefix + bucketName + if statement.Resources.Contains(bucketResource) { + return true + } + + if statement.Resources.FuncMatch(startsWithFunc, bucketResource+"/").IsEmpty() { + return false + } + + return true +} + +// Returns new statements with bucket actions for given policy. +func newBucketStatement(policy BucketPolicy, bucketName, prefix string) (statements []Statement) { + statements = []Statement{} + if policy == BucketPolicyNone || bucketName == "" { + return statements + } + + bucketResource := set.CreateStringSet(awsResourcePrefix + bucketName) + + statement := Statement{ + Actions: commonBucketActions, + Effect: "Allow", + Principal: User{AWS: set.CreateStringSet("*")}, + Resources: bucketResource, + Sid: "", + } + statements = append(statements, statement) + + if policy == BucketPolicyReadOnly || policy == BucketPolicyReadWrite { + statement = Statement{ + Actions: readOnlyBucketActions, + Effect: "Allow", + Principal: User{AWS: set.CreateStringSet("*")}, + Resources: bucketResource, + Sid: "", + } + if prefix != "" { + condKeyMap := make(ConditionKeyMap) + condKeyMap.Add("s3:prefix", set.CreateStringSet(prefix+"*")) + condMap := make(ConditionMap) + condMap.Add("StringLike", condKeyMap) + statement.Conditions = condMap + } + statements = append(statements, statement) + } + + if policy == BucketPolicyWriteOnly || policy == BucketPolicyReadWrite { + statement = Statement{ + Actions: writeOnlyBucketActions, + Effect: "Allow", + Principal: User{AWS: set.CreateStringSet("*")}, + Resources: bucketResource, + Sid: "", + } + statements = append(statements, statement) + } + + return statements +} + +// Returns new statements contains object actions for given policy. +func newObjectStatement(policy BucketPolicy, bucketName, prefix string) (statements []Statement) { + statements = []Statement{} + if policy == BucketPolicyNone || bucketName == "" { + return statements + } + + statement := Statement{ + Effect: "Allow", + Principal: User{AWS: set.CreateStringSet("*")}, + Resources: set.CreateStringSet(awsResourcePrefix + bucketName + "/" + prefix + "*"), + Sid: "", + } + + switch policy { + case BucketPolicyReadOnly: + statement.Actions = readOnlyObjectActions + case BucketPolicyWriteOnly: + statement.Actions = writeOnlyObjectActions + case BucketPolicyReadWrite: + statement.Actions = readWriteObjectActions + } + + statements = append(statements, statement) + return statements +} + +// Returns new statements for given policy, bucket and prefix. +func newStatements(policy BucketPolicy, bucketName, prefix string) (statements []Statement) { + statements = []Statement{} + ns := newBucketStatement(policy, bucketName, prefix) + statements = append(statements, ns...) + + ns = newObjectStatement(policy, bucketName, prefix) + statements = append(statements, ns...) + + return statements +} + +// Returns whether given bucket statements are used by other than given prefix statements. +func getInUsePolicy(statements []Statement, bucketName, prefix string) (readOnlyInUse, writeOnlyInUse bool) { + resourcePrefix := awsResourcePrefix + bucketName + "/" + objectResource := awsResourcePrefix + bucketName + "/" + prefix + "*" + + for _, s := range statements { + if !s.Resources.Contains(objectResource) && !s.Resources.FuncMatch(startsWithFunc, resourcePrefix).IsEmpty() { + if s.Actions.Intersection(readOnlyObjectActions).Equals(readOnlyObjectActions) { + readOnlyInUse = true + } + + if s.Actions.Intersection(writeOnlyObjectActions).Equals(writeOnlyObjectActions) { + writeOnlyInUse = true + } + } + if readOnlyInUse && writeOnlyInUse { + break + } + } + + return readOnlyInUse, writeOnlyInUse +} + +// Removes object actions in given statement. +func removeObjectActions(statement Statement, objectResource string) Statement { + if statement.Conditions == nil { + if len(statement.Resources) > 1 { + statement.Resources.Remove(objectResource) + } else { + statement.Actions = statement.Actions.Difference(readOnlyObjectActions) + statement.Actions = statement.Actions.Difference(writeOnlyObjectActions) + } + } + + return statement +} + +// Removes bucket actions for given policy in given statement. +func removeBucketActions(statement Statement, prefix, bucketResource string, readOnlyInUse, writeOnlyInUse bool) Statement { + removeReadOnly := func() { + if !statement.Actions.Intersection(readOnlyBucketActions).Equals(readOnlyBucketActions) { + return + } + + if statement.Conditions == nil { + statement.Actions = statement.Actions.Difference(readOnlyBucketActions) + return + } + + if prefix != "" { + stringEqualsValue := statement.Conditions["StringEquals"] + values := set.NewStringSet() + if stringEqualsValue != nil { + values = stringEqualsValue["s3:prefix"] + if values == nil { + values = set.NewStringSet() + } + } + + values.Remove(prefix) + + if stringEqualsValue != nil { + if values.IsEmpty() { + delete(stringEqualsValue, "s3:prefix") + } + if len(stringEqualsValue) == 0 { + delete(statement.Conditions, "StringEquals") + } + } + + if len(statement.Conditions) == 0 { + statement.Conditions = nil + statement.Actions = statement.Actions.Difference(readOnlyBucketActions) + } + } + } + + removeWriteOnly := func() { + if statement.Conditions == nil { + statement.Actions = statement.Actions.Difference(writeOnlyBucketActions) + } + } + + if len(statement.Resources) > 1 { + statement.Resources.Remove(bucketResource) + } else { + if !readOnlyInUse { + removeReadOnly() + } + + if !writeOnlyInUse { + removeWriteOnly() + } + } + + return statement +} + +// Returns statements containing removed actions/statements for given +// policy, bucket name and prefix. +func removeStatements(statements []Statement, bucketName, prefix string) []Statement { + bucketResource := awsResourcePrefix + bucketName + objectResource := awsResourcePrefix + bucketName + "/" + prefix + "*" + readOnlyInUse, writeOnlyInUse := getInUsePolicy(statements, bucketName, prefix) + + out := []Statement{} + readOnlyBucketStatements := []Statement{} + s3PrefixValues := set.NewStringSet() + + for _, statement := range statements { + if !isValidStatement(statement, bucketName) { + out = append(out, statement) + continue + } + + if statement.Resources.Contains(bucketResource) { + if statement.Conditions != nil { + statement = removeBucketActions(statement, prefix, bucketResource, false, false) + } else { + statement = removeBucketActions(statement, prefix, bucketResource, readOnlyInUse, writeOnlyInUse) + } + } else if statement.Resources.Contains(objectResource) { + statement = removeObjectActions(statement, objectResource) + } + + if !statement.Actions.IsEmpty() { + if statement.Resources.Contains(bucketResource) && + statement.Actions.Intersection(readOnlyBucketActions).Equals(readOnlyBucketActions) && + statement.Effect == "Allow" && + statement.Principal.AWS.Contains("*") { + if statement.Conditions != nil { + stringEqualsValue := statement.Conditions["StringEquals"] + values := set.NewStringSet() + if stringEqualsValue != nil { + values = stringEqualsValue["s3:prefix"] + if values == nil { + values = set.NewStringSet() + } + } + s3PrefixValues = s3PrefixValues.Union(values.ApplyFunc(func(v string) string { + return bucketResource + "/" + v + "*" + })) + } else if !s3PrefixValues.IsEmpty() { + readOnlyBucketStatements = append(readOnlyBucketStatements, statement) + continue + } + } + out = append(out, statement) + } + } + + skipBucketStatement := true + resourcePrefix := awsResourcePrefix + bucketName + "/" + for _, statement := range out { + if !statement.Resources.FuncMatch(startsWithFunc, resourcePrefix).IsEmpty() && + s3PrefixValues.Intersection(statement.Resources).IsEmpty() { + skipBucketStatement = false + break + } + } + + for _, statement := range readOnlyBucketStatements { + if skipBucketStatement && + statement.Resources.Contains(bucketResource) && + statement.Effect == "Allow" && + statement.Principal.AWS.Contains("*") && + statement.Conditions == nil { + continue + } + + out = append(out, statement) + } + + if len(out) == 1 { + statement := out[0] + if statement.Resources.Contains(bucketResource) && + statement.Actions.Intersection(commonBucketActions).Equals(commonBucketActions) && + statement.Effect == "Allow" && + statement.Principal.AWS.Contains("*") && + statement.Conditions == nil { + out = []Statement{} + } + } + + return out +} + +// Appends given statement into statement list to have unique statements. +// - If statement already exists in statement list, it ignores. +// - If statement exists with different conditions, they are merged. +// - Else the statement is appended to statement list. +func appendStatement(statements []Statement, statement Statement) []Statement { + for i, s := range statements { + if s.Actions.Equals(statement.Actions) && + s.Effect == statement.Effect && + s.Principal.AWS.Equals(statement.Principal.AWS) && + reflect.DeepEqual(s.Conditions, statement.Conditions) { + statements[i].Resources = s.Resources.Union(statement.Resources) + return statements + } else if s.Resources.Equals(statement.Resources) && + s.Effect == statement.Effect && + s.Principal.AWS.Equals(statement.Principal.AWS) && + reflect.DeepEqual(s.Conditions, statement.Conditions) { + statements[i].Actions = s.Actions.Union(statement.Actions) + return statements + } + + if s.Resources.Intersection(statement.Resources).Equals(statement.Resources) && + s.Actions.Intersection(statement.Actions).Equals(statement.Actions) && + s.Effect == statement.Effect && + s.Principal.AWS.Intersection(statement.Principal.AWS).Equals(statement.Principal.AWS) { + if reflect.DeepEqual(s.Conditions, statement.Conditions) { + return statements + } + if s.Conditions != nil && statement.Conditions != nil { + if s.Resources.Equals(statement.Resources) { + statements[i].Conditions = mergeConditionMap(s.Conditions, statement.Conditions) + return statements + } + } + } + } + + if !statement.Actions.IsEmpty() || !statement.Resources.IsEmpty() { + return append(statements, statement) + } + + return statements +} + +// Appends two statement lists. +func appendStatements(statements, appendStatements []Statement) []Statement { + for _, s := range appendStatements { + statements = appendStatement(statements, s) + } + + return statements +} + +// Returns policy of given bucket statement. +func getBucketPolicy(statement Statement, prefix string) (commonFound, readOnly, writeOnly bool) { + if statement.Effect != "Allow" || !statement.Principal.AWS.Contains("*") { + return commonFound, readOnly, writeOnly + } + + if statement.Actions.Intersection(commonBucketActions).Equals(commonBucketActions) && + statement.Conditions == nil { + commonFound = true + } + + if statement.Actions.Intersection(writeOnlyBucketActions).Equals(writeOnlyBucketActions) && + statement.Conditions == nil { + writeOnly = true + } + + if statement.Actions.Intersection(readOnlyBucketActions).Equals(readOnlyBucketActions) { + if prefix != "" && statement.Conditions != nil { + if stringEqualsValue, ok := statement.Conditions["StringEquals"]; ok { + if s3PrefixValues, ok := stringEqualsValue["s3:prefix"]; ok { + if s3PrefixValues.Contains(prefix) { + readOnly = true + } + } + } else if stringNotEqualsValue, ok := statement.Conditions["StringNotEquals"]; ok { + if s3PrefixValues, ok := stringNotEqualsValue["s3:prefix"]; ok { + if !s3PrefixValues.Contains(prefix) { + readOnly = true + } + } + } else if stringLikeValue, ok := statement.Conditions["StringLike"]; ok { + if s3PrefixValues, ok := stringLikeValue["s3:prefix"]; ok { + if s3PrefixValues.Contains(prefix + "*") { + readOnly = true + } + } + } else if stringNotLikeValue, ok := statement.Conditions["StringNotLike"]; ok { + if s3PrefixValues, ok := stringNotLikeValue["s3:prefix"]; ok { + if !s3PrefixValues.Contains(prefix + "*") { + readOnly = true + } + } + } + } else if prefix == "" && statement.Conditions == nil { + readOnly = true + } else if prefix != "" && statement.Conditions == nil { + readOnly = true + } + } + + return commonFound, readOnly, writeOnly +} + +// Returns policy of given object statement. +func getObjectPolicy(statement Statement) (readOnly, writeOnly bool) { + if statement.Effect == "Allow" && + statement.Principal.AWS.Contains("*") && + statement.Conditions == nil { + if statement.Actions.Intersection(readOnlyObjectActions).Equals(readOnlyObjectActions) { + readOnly = true + } + if statement.Actions.Intersection(writeOnlyObjectActions).Equals(writeOnlyObjectActions) { + writeOnly = true + } + } + + return readOnly, writeOnly +} + +// GetPolicy - Returns policy of given bucket name, prefix in given statements. +func GetPolicy(statements []Statement, bucketName, prefix string) BucketPolicy { + bucketResource := awsResourcePrefix + bucketName + objectResource := awsResourcePrefix + bucketName + "/" + prefix + "*" + + bucketCommonFound := false + bucketReadOnly := false + bucketWriteOnly := false + matchedResource := "" + objReadOnly := false + objWriteOnly := false + + for _, s := range statements { + matchedObjResources := set.NewStringSet() + if s.Resources.Contains(objectResource) { + matchedObjResources.Add(objectResource) + } else { + matchedObjResources = s.Resources.FuncMatch(resourceMatch, objectResource) + } + if !matchedObjResources.IsEmpty() { + readOnly, writeOnly := getObjectPolicy(s) + for resource := range matchedObjResources { + if len(matchedResource) < len(resource) { + objReadOnly = readOnly + objWriteOnly = writeOnly + matchedResource = resource + } else if len(matchedResource) == len(resource) { + objReadOnly = objReadOnly || readOnly + objWriteOnly = objWriteOnly || writeOnly + matchedResource = resource + } + } + } + if s.Resources.Contains(bucketResource) { + commonFound, readOnly, writeOnly := getBucketPolicy(s, prefix) + bucketCommonFound = bucketCommonFound || commonFound + bucketReadOnly = bucketReadOnly || readOnly + bucketWriteOnly = bucketWriteOnly || writeOnly + } + } + + policy := BucketPolicyNone + if bucketCommonFound { + if bucketReadOnly && bucketWriteOnly && objReadOnly && objWriteOnly { + policy = BucketPolicyReadWrite + } else if bucketReadOnly && objReadOnly { + policy = BucketPolicyReadOnly + } else if bucketWriteOnly && objWriteOnly { + policy = BucketPolicyWriteOnly + } + } + + return policy +} + +// GetPolicies - returns a map of policies of given bucket name, prefix in given statements. +func GetPolicies(statements []Statement, bucketName, prefix string) map[string]BucketPolicy { + policyRules := map[string]BucketPolicy{} + objResources := set.NewStringSet() + // Search all resources related to objects policy + for _, s := range statements { + for r := range s.Resources { + if strings.HasPrefix(r, awsResourcePrefix+bucketName+"/"+prefix) { + objResources.Add(r) + } + } + } + + // Pretend that policy resource as an actual object and fetch its policy + for r := range objResources { + // Put trailing * if exists in asterisk + asterisk := "" + if strings.HasSuffix(r, "*") { + r = r[:len(r)-1] + asterisk = "*" + } + var objectPath string + if len(r) >= len(awsResourcePrefix+bucketName)+1 { + objectPath = r[len(awsResourcePrefix+bucketName)+1:] + } + p := GetPolicy(statements, bucketName, objectPath) + policyRules[bucketName+"/"+objectPath+asterisk] = p + } + return policyRules +} + +// SetPolicy - Returns new statements containing policy of given bucket name and prefix are appended. +func SetPolicy(statements []Statement, policy BucketPolicy, bucketName, prefix string) []Statement { + out := removeStatements(statements, bucketName, prefix) + // fmt.Println("out = ") + // printstatement(out) + ns := newStatements(policy, bucketName, prefix) + // fmt.Println("ns = ") + // printstatement(ns) + + rv := appendStatements(out, ns) + // fmt.Println("rv = ") + // printstatement(rv) + + return rv +} + +// Match function matches wild cards in 'pattern' for resource. +func resourceMatch(pattern, resource string) bool { + if pattern == "" { + return resource == pattern + } + if pattern == "*" { + return true + } + parts := strings.Split(pattern, "*") + if len(parts) == 1 { + return resource == pattern + } + tGlob := strings.HasSuffix(pattern, "*") + end := len(parts) - 1 + if !strings.HasPrefix(resource, parts[0]) { + return false + } + for i := 1; i < end; i++ { + if !strings.Contains(resource, parts[i]) { + return false + } + idx := strings.Index(resource, parts[i]) + len(parts[i]) + resource = resource[idx:] + } + return tGlob || strings.HasSuffix(resource, parts[end]) +} diff --git a/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming-unsigned-trailer.go b/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming-unsigned-trailer.go index e18002b8d53..35c50b0c4d3 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming-unsigned-trailer.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming-unsigned-trailer.go @@ -61,10 +61,10 @@ func getUSStreamLength(dataLen, chunkSize int64, trailers http.Header) int64 { return streamLen } -// prepareStreamingRequest - prepares a request with appropriate -// headers before computing the seed signature. +// prepareUSStreamingRequest - prepares a request with the headers +// required for an unsigned aws-chunked streaming upload. func prepareUSStreamingRequest(req *http.Request, sessionToken string, dataLen int64, timestamp time.Time) { - req.TransferEncoding = []string{"aws-chunked"} + setAwsChunkedContentEncoding(req) if sessionToken != "" { req.Header.Set("X-Amz-Security-Token", sessionToken) } diff --git a/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming.go b/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming.go index 4fe0debf5cb..8d86d4f15e2 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-streaming.go @@ -132,8 +132,8 @@ func prepareStreamingRequest(req *http.Request, sessionToken string, dataLen int for k := range req.Trailer { req.Header.Add("X-Amz-Trailer", strings.ToLower(k)) } - req.TransferEncoding = []string{"aws-chunked"} } + setAwsChunkedContentEncoding(req) if sessionToken != "" { req.Header.Set("X-Amz-Security-Token", sessionToken) diff --git a/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-v4.go b/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-v4.go index 2a060c6e792..0ae2256d306 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-v4.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/signer/request-signature-v4.go @@ -331,7 +331,7 @@ func signV4(req http.Request, accessKeyID, secretAccessKey, sessionToken, locati req.Header.Add("X-Amz-Trailer", strings.ToLower(k)) } - req.Header.Set("Content-Encoding", "aws-chunked") + setAwsChunkedContentEncoding(&req) req.Header.Set("x-amz-decoded-content-length", strconv.FormatInt(req.ContentLength, 10)) } @@ -395,7 +395,7 @@ func UnsignedTrailer(req http.Request, trailer http.Header) *http.Request { req.Header.Add("X-Amz-Trailer", strings.ToLower(k)) } - req.Header.Set("Content-Encoding", "aws-chunked") + setAwsChunkedContentEncoding(&req) req.Header.Set("x-amz-decoded-content-length", strconv.FormatInt(req.ContentLength, 10)) // Use custom chunked encoding. diff --git a/vendor/github.com/minio/minio-go/v7/pkg/signer/utils.go b/vendor/github.com/minio/minio-go/v7/pkg/signer/utils.go index 87c99398913..20172c2fb64 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/signer/utils.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/signer/utils.go @@ -22,6 +22,8 @@ import ( "crypto/sha256" "net/http" "strings" + + "golang.org/x/net/http/httpguts" ) // unsignedPayload - value to be set to X-Amz-Content-Sha256 header when @@ -60,3 +62,26 @@ func signV4TrimAll(input string) string { // unicode.IsSpace() internally here) to one space and return return strings.Join(strings.Fields(input), " ") } + +// awsChunkedEncoding is the content coding AWS SigV4 streaming uploads +// declare on the Content-Encoding header. +const awsChunkedEncoding = "aws-chunked" + +// setAwsChunkedContentEncoding marks the request payload as aws-chunked +// encoded, keeping any content encoding the caller already set, for example +// "aws-chunked,gzip". AWS SigV4 streaming uploads require this header. +// Assigning "aws-chunked" to http.Request.TransferEncoding never reaches +// the wire — net/http silently drops assigned values other than "chunked" — +// so this header is the only signal that declares the aws-chunked framing. +func setAwsChunkedContentEncoding(req *http.Request) { + encodings := req.Header.Values("Content-Encoding") + if httpguts.HeaderValuesContainsToken(encodings, awsChunkedEncoding) { + return + } + existing := strings.TrimSpace(strings.Join(encodings, ",")) + if existing == "" { + req.Header.Set("Content-Encoding", awsChunkedEncoding) + return + } + req.Header.Set("Content-Encoding", awsChunkedEncoding+","+existing) +} diff --git a/vendor/github.com/minio/minio-go/v7/pkg/singleflight/singleflight.go b/vendor/github.com/minio/minio-go/v7/pkg/singleflight/singleflight.go index 49260327f28..ece42b9e66e 100644 --- a/vendor/github.com/minio/minio-go/v7/pkg/singleflight/singleflight.go +++ b/vendor/github.com/minio/minio-go/v7/pkg/singleflight/singleflight.go @@ -172,10 +172,12 @@ func (g *Group[K, V]) doCall(c *call[V], key K, fn func() (V, error)) { } else { panic(e) } - } else if c.err == errGoexit { - // Already in the process of goexit, no need to call again } else { - // Normal return + // Normal return, and runtime.Goexit, which reaches here with + // c.err set to errGoexit. This goroutine is already being torn + // down and must not call runtime.Goexit again: Do callers + // re-Goexit themselves once they see c.err, but DoChan callers + // hold a channel and have nothing else to wake them. for _, ch := range c.chans { ch <- Result[V]{c.val, c.err, c.dups > 0} } diff --git a/vendor/github.com/minio/minio-go/v7/rdma.go b/vendor/github.com/minio/minio-go/v7/rdma.go index 450c9620e5d..48d2c87fab8 100644 --- a/vendor/github.com/minio/minio-go/v7/rdma.go +++ b/vendor/github.com/minio/minio-go/v7/rdma.go @@ -26,6 +26,25 @@ import ( var ErrRDMANotConnected = errors.New("RDMA infrastructure not connected") +// maxRDMABufferSize is the largest transfer a single RDMA descriptor can +// describe: the x-amz-rdma-token carries the window size in a 32-bit field. +// libminiocpp itself does not fail on a larger buffer: it skips RDMA and +// transfers it over one ordinary HTTP request. The guards below reject it +// instead, so an oversize buffer does not silently become a much slower HTTP +// transfer on a path the caller explicitly opted into for RDMA. Keep this in +// step with kRDMAMaxMemoryRegSize in minio-cpp -- a value even one byte larger +// lets a buffer through here that libminiocpp then declines. The lower bound +// also stops a negative size from wrapping to a huge C.size_t. +const maxRDMABufferSize int64 = 1<<32 - 1 // 4 GiB - 1 + +// rdmaBufferSizeInRange reports whether a descriptor can name this many bytes. +// Both entry points gate on it before converting to C.size_t, so it is the one +// place the bound is expressed -- and the only part of the guard that can be +// exercised without an RDMA device. +func rdmaBufferSizeInRange(size int) bool { + return size >= 0 && int64(size) <= maxRDMABufferSize +} + type rdmaClientHandle struct { cptr *C.miniocpp_client } @@ -63,6 +82,12 @@ func newRDMAClient(c *Client) (*rdmaClientHandle, error) { func (c *Client) putObjectRDMA(_ context.Context, bucketName, objectName string, opts PutObjectOptions, ) (UploadInfo, error) { + if !rdmaBufferSizeInRange(opts.RDMABufferSize) { + return UploadInfo{}, fmt.Errorf( + "RDMA put: buffer size %d must be between 0 and the %d bytes an RDMA descriptor can describe", + opts.RDMABufferSize, maxRDMABufferSize) + } + h, err := c.rdma() if err != nil { return UploadInfo{}, err @@ -93,6 +118,12 @@ func (c *Client) putObjectRDMA(_ context.Context, bucketName, objectName string, func (c *Client) getObjectRDMA(_ context.Context, bucketName, objectName string, opts GetObjectOptions, ) (int64, error) { + if !rdmaBufferSizeInRange(opts.RDMABufferSize) { + return 0, fmt.Errorf( + "RDMA get: buffer size %d must be between 0 and the %d bytes an RDMA descriptor can describe", + opts.RDMABufferSize, maxRDMABufferSize) + } + h, err := c.rdma() if err != nil { return 0, err @@ -136,5 +167,7 @@ func AlignedBuffer(n int) unsafe.Pointer { // FreeAlignedBuffer releases a buffer from AlignedBuffer. func FreeAlignedBuffer(p unsafe.Pointer) { C.miniocpp_free_aligned(p) } -// IsRDMAAvailable reports whether cuObj is connected to a cuObjServer. +// IsRDMAAvailable reports whether this host has a usable RDMA device, so an +// RDMA transfer is worth attempting. Whether the server serves RDMA for a +// given object is answered per request, by x-amz-rdma-reply. func IsRDMAAvailable() bool { return C.miniocpp_rdma_available() != 0 } diff --git a/vendor/github.com/minio/minio-go/v7/s3-error.go b/vendor/github.com/minio/minio-go/v7/s3-error.go index 4bcc47d80a0..4ff34156d61 100644 --- a/vendor/github.com/minio/minio-go/v7/s3-error.go +++ b/vendor/github.com/minio/minio-go/v7/s3-error.go @@ -62,6 +62,7 @@ const ( InvalidDuration = "InvalidDuration" XAmzContentSHA256Mismatch = "XAmzContentSHA256Mismatch" XMinioInvalidObjectName = "XMinioInvalidObjectName" + XMinioPaidTierLicenseRequired = "XMinioPaidTierLicenseRequired" NoSuchCORSConfiguration = "NoSuchCORSConfiguration" BucketAlreadyExists = "BucketAlreadyExists" NoSuchVersion = "NoSuchVersion" diff --git a/vendor/github.com/minio/minio-go/v7/utils.go b/vendor/github.com/minio/minio-go/v7/utils.go index 3361464c5dc..48e4a47b618 100644 --- a/vendor/github.com/minio/minio-go/v7/utils.go +++ b/vendor/github.com/minio/minio-go/v7/utils.go @@ -33,6 +33,7 @@ import ( "mime" "net" "net/http" + "net/textproto" "net/url" "regexp" "strconv" @@ -63,7 +64,7 @@ func amzExpirationToExpiryDateRuleID(expiration string) (time.Time, string) { return time.Time{}, "" } -var restoreRegex = regexp.MustCompile(`ongoing-request="(.*?)"(, expiry-date="(.*?)")?`) +var restoreRegex = regexp.MustCompile(`ongoing-request="(.*?)"(, ?expiry-date="(.*?)")?`) func amzRestoreToStruct(restore string) (ongoing bool, expTime time.Time, err error) { matches := restoreRegex.FindStringSubmatch(restore) @@ -105,8 +106,32 @@ func sumMD5Base64(data []byte) string { return base64.StdEncoding.EncodeToString(hash.Sum(nil)) } -// getEndpointURL - construct a new endpoint. +// getEndpointURL - construct a new endpoint from a host[:port] endpoint +// or an http(s):// URL whose scheme agrees with the secure option. func getEndpointURL(endpoint string, secure bool) (*url.URL, error) { + // An endpoint that already carries a scheme is parsed directly instead + // of prefixing another scheme. It must agree with the secure option + // since signing and transport behavior are derived from that option. + // A "://" preceded by a path, query, or fragment delimiter is endpoint + // data rather than a scheme, so such endpoints keep the scheme-less path. + if i := strings.Index(endpoint, "://"); i == 0 || (i > 0 && !strings.ContainsAny(endpoint[:i], "/?#")) { + scheme := strings.ToLower(endpoint[:i]) + if scheme != "http" && scheme != "https" { + return nil, errInvalidArgument("Endpoint url scheme \"" + scheme + "\" is unsupported; use http or https or omit the scheme.") + } + endpointURL, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + if secure != (endpointURL.Scheme == "https") { + return nil, errInvalidArgument("Endpoint url scheme \"" + endpointURL.Scheme + "\" conflicts with the secure option; remove the scheme from the endpoint or align the secure option.") + } + if err := isValidEndpointURL(*endpointURL); err != nil { + return nil, err + } + return endpointURL, nil + } + // If secure is false, use 'http' scheme. scheme := "https" if !secure { @@ -199,6 +224,9 @@ func isValidExpiry(expires time.Duration) error { return nil } +// amzMetaPrefix is the canonical prefix of S3 user metadata headers. +const amzMetaPrefix = "X-Amz-Meta-" + // Extract only necessary metadata header key/values by // filtering them out with a list of custom header keys. func extractObjMetadata(header http.Header) http.Header { @@ -215,7 +243,7 @@ func extractObjMetadata(header http.Header) http.Header { "X-Amz-Website-Redirect-Location", "X-Amz-Server-Side-Encryption", "X-Amz-Tagging-Count", - "X-Amz-Meta-", + amzMetaPrefix, "X-Minio-Meta-", // Add new headers to be preserved. // if you add new headers here, please extend @@ -230,7 +258,7 @@ func extractObjMetadata(header http.Header) http.Header { continue } found = true - if prefix == "X-Amz-Meta-" || prefix == "X-Minio-Meta-" { + if prefix == amzMetaPrefix || prefix == "X-Minio-Meta-" { for index, val := range v { if strings.HasPrefix(val, "=?") { decoder := mime.WordDecoder{} @@ -249,8 +277,29 @@ func extractObjMetadata(header http.Header) http.Header { return filteredHeader } +// stripUserMetadata converts the raw element of MinIO list +// responses into the keyed form StatObject and GetObject return in +// ObjectInfo.UserMetadata: only "X-Amz-Meta-*" entries are kept, with the +// prefix stripped and values passed through verbatim (list responses carry +// the stored values, so no decoding applies). Returns nil if raw contains +// no user metadata. +func stripUserMetadata(raw StringMap) StringMap { + var stripped StringMap + for k, v := range raw { + k = textproto.CanonicalMIMEHeaderKey(k) + if !strings.HasPrefix(k, amzMetaPrefix) { + continue + } + if stripped == nil { + stripped = make(StringMap, len(raw)) + } + stripped[strings.TrimPrefix(k, amzMetaPrefix)] = v + } + return stripped +} + const ( - // RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT + // RFC 7231#section-7.1.1.1 timestamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT rfc822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT" rfc822TimeFormatSingleDigitDay = "Mon, _2 Jan 2006 15:04:05 GMT" rfc822TimeFormatSingleDigitDayTwoDigitYear = "Mon, _2 Jan 06 15:04:05 GMT" @@ -351,8 +400,8 @@ func ToObjectInfo(bucketName, objectName string, h http.Header) (ObjectInfo, err metadata := extractObjMetadata(h) userMetadata := make(map[string]string) for k, v := range metadata { - if strings.HasPrefix(k, "X-Amz-Meta-") { - userMetadata[strings.TrimPrefix(k, "X-Amz-Meta-")] = v[0] + if strings.HasPrefix(k, amzMetaPrefix) { + userMetadata[strings.TrimPrefix(k, amzMetaPrefix)] = v[0] } } @@ -412,6 +461,7 @@ func ToObjectInfo(bucketName, objectName string, h http.Header) (ObjectInfo, err // following function filters out a list of standard set of keys // which are not part of object metadata. Metadata: metadata, + Headers: h, UserMetadata: userMetadata, UserTags: userTags.ToMap(), UserTagCount: tagCount, diff --git a/vendor/github.com/oklog/ulid/v2/ulid.go b/vendor/github.com/oklog/ulid/v2/ulid.go index 77e9ddd6349..e07e1a68183 100644 --- a/vendor/github.com/oklog/ulid/v2/ulid.go +++ b/vendor/github.com/oklog/ulid/v2/ulid.go @@ -505,7 +505,16 @@ func (id *ULID) Scan(src interface{}) error { case string: return id.UnmarshalText([]byte(x)) case []byte: - return id.UnmarshalBinary(x) + // Drivers often return text/varchar columns as []byte. Accept both + // the 16-byte binary form and the 26-character text encoding. + switch len(x) { + case len(*id): + return id.UnmarshalBinary(x) + case EncodedSize: + return id.UnmarshalText(x) + default: + return ErrDataSize + } } return ErrScanValue diff --git a/vendor/github.com/parquet-go/parquet-go/bloom.go b/vendor/github.com/parquet-go/parquet-go/bloom.go index 75dbaee4053..735d411ebbe 100644 --- a/vendor/github.com/parquet-go/parquet-go/bloom.go +++ b/vendor/github.com/parquet-go/parquet-go/bloom.go @@ -64,18 +64,30 @@ func (v Value) hash(h bloom.Hash) uint64 { } } +// The bloom filter spec only defines one algorithm and one hash function; a +// header carrying anything else comes from a writer we do not understand. +func isSplitBlockAlgorithm(header *format.BloomFilterHeader) bool { + _, ok := header.Algorithm.Value.(*format.SplitBlockAlgorithm) + return ok +} + +func isXxHash(header *format.BloomFilterHeader) bool { + _, ok := header.Hash.Value.(*format.XxHash) + return ok +} + func newBloomFilter(file io.ReaderAt, offset int64, header *format.BloomFilterHeader) (*FileBloomFilter, error) { - if header.Algorithm.Block == nil || header.Hash.XxHash == nil { + if !isSplitBlockAlgorithm(header) || !isXxHash(header) { return nil, nil } - switch { - case header.Compression.Uncompressed != nil: + switch header.Compression.Value.(type) { + case *format.BloomFilterUncompressed: return &FileBloomFilter{ SectionReader: *io.NewSectionReader(file, offset, int64(header.NumBytes)), hash: bloom.XXH64{}, check: bloom.CheckSplitBlock, }, nil - case header.Compression.GZip != nil: + case *format.BloomFilterGzip: // Decompress lazily on the first Check call so that opening a file with // PrefetchBloomFilters(false) does not perform any extra I/O at open time. compressedSize := int64(header.NumBytes) @@ -120,18 +132,18 @@ func newBloomFilter(file io.ReaderAt, offset int64, header *format.BloomFilterHe // fails, we return nil so the read silently skips the filter rather than // failing the whole file open. func newBloomFilterFromBytes(header *format.BloomFilterHeader, bits []byte) *FileBloomFilter { - if header.Algorithm.Block == nil || header.Hash.XxHash == nil { + if !isSplitBlockAlgorithm(header) || !isXxHash(header) { return nil } - switch { - case header.Compression.Uncompressed != nil: + switch header.Compression.Value.(type) { + case *format.BloomFilterUncompressed: r := bytes.NewReader(bits) return &FileBloomFilter{ SectionReader: *io.NewSectionReader(r, 0, int64(len(bits))), hash: bloom.XXH64{}, check: bloom.CheckSplitBlock, } - case header.Compression.GZip != nil: + case *format.BloomFilterGzip: decompressed, err := LookupCompressionCodec(format.Gzip).Decode(nil, bits) if err != nil { return nil @@ -202,16 +214,16 @@ func (f splitBlockFilter) Size(numValues int64) int { func bloomFilterHeader(filter BloomFilterColumn, codec compress.Codec) (header format.BloomFilterHeader) { switch filter.(type) { case splitBlockFilter: - header.Algorithm.Block = &format.SplitBlockAlgorithm{} + header.Algorithm.Value = &format.SplitBlockAlgorithm{} } switch filter.Hash().(type) { case bloom.XXH64: - header.Hash.XxHash = &format.XxHash{} + header.Hash.Value = &format.XxHash{} } if codec != nil && codec.CompressionCodec() == format.Gzip { - header.Compression.GZip = &format.BloomFilterGzip{} + header.Compression.Value = &format.BloomFilterGzip{} } else { - header.Compression.Uncompressed = &format.BloomFilterUncompressed{} + header.Compression.Value = &format.BloomFilterUncompressed{} } return header } diff --git a/vendor/github.com/parquet-go/parquet-go/buffer.go b/vendor/github.com/parquet-go/parquet-go/buffer.go index 2bb2dea7449..28ae8b5cd58 100644 --- a/vendor/github.com/parquet-go/parquet-go/buffer.go +++ b/vendor/github.com/parquet-go/parquet-go/buffer.go @@ -144,6 +144,10 @@ func (buf *GenericBuffer[T]) Rows() Rows { return buf.base.Rows() } +// chunkTransparentRowGroup marks GenericBuffer as safe for the chunk-level +// write fast paths, for the same reasons as Buffer. +func (buf *GenericBuffer[T]) chunkTransparentRowGroup() {} + func (buf *GenericBuffer[T]) Schema() *Schema { return buf.base.Schema() } @@ -437,6 +441,11 @@ func (buf *Buffer) WriteRowGroup(rowGroup RowGroup) (int64, error) { // concurrently to reading rows may result in non-deterministic behavior. func (buf *Buffer) Rows() Rows { return NewRowGroupRowReader(buf) } +// chunkTransparentRowGroup marks Buffer as safe for the chunk-level write fast +// paths: its Rows() reads the column buffers in order, and sorting reorders all +// columns together, so column-wise reads preserve row order. +func (buf *Buffer) chunkTransparentRowGroup() {} + // bufferWriter is an adapter for Buffer which implements both RowWriter and // PageWriter to enable optimizations in CopyRows for types that support writing // rows by copying whole pages instead of calling WriteRow repeatedly. diff --git a/vendor/github.com/parquet-go/parquet-go/buffer_pool.go b/vendor/github.com/parquet-go/parquet-go/buffer_pool.go index d2260a652d1..171fc6a6a19 100644 --- a/vendor/github.com/parquet-go/parquet-go/buffer_pool.go +++ b/vendor/github.com/parquet-go/parquet-go/buffer_pool.go @@ -1,6 +1,7 @@ package parquet import ( + "errors" "io" "os" "path/filepath" @@ -133,8 +134,11 @@ func (r *readerAt) ReadAt(b []byte, off int64) (int, error) { } r.offset = off } - n, err := r.reader.Read(b) + n, err := io.ReadFull(r.reader, b) r.offset += int64(n) + if errors.Is(err, io.ErrUnexpectedEOF) { + err = io.EOF + } return n, err } diff --git a/vendor/github.com/parquet-go/parquet-go/column.go b/vendor/github.com/parquet-go/parquet-go/column.go index e3ae1714f1c..6df3fcbf6d4 100644 --- a/vendor/github.com/parquet-go/parquet-go/column.go +++ b/vendor/github.com/parquet-go/parquet-go/column.go @@ -210,6 +210,7 @@ func (c *Column) forEachLeaf(do func(*Column)) { func openColumns(file *File, metadata *format.FileMetaData, columnIndexes []format.ColumnIndex, offsetIndexes []format.OffsetIndex) (*Column, error) { cl := columnLoader{} + cl.reserve(metadata, columnIndexes, offsetIndexes) c, err := cl.open(file, metadata, columnIndexes, offsetIndexes, nil) if err != nil { @@ -282,14 +283,104 @@ type columnLoader struct { schemaIndex int columnOrderIndex int rowGroupColumnIndex int + + // The shape of the column tree is fully determined by the schema, so its + // parts are allocated once here and handed out in slices as the tree is + // built. A file with C schema elements, L of them leaves, and R row groups + // used to cost C + 2*(C-1) + 3*L allocations; it now costs six. + columns []Column + children []*Column + fields []Field + chunks []*format.ColumnChunk + columnIndex []*format.ColumnIndex + offsetIndex []*format.OffsetIndex + // paths backs every column's path. A column's path is its parent's path + // plus its own name, so the segments across the whole tree sum to a size + // the schema determines up front. + paths []string +} + +func (cl *columnLoader) reserve(metadata *format.FileMetaData, columnIndexes []format.ColumnIndex, offsetIndexes []format.OffsetIndex) { + numColumns := len(metadata.Schema) + if numColumns == 0 { + return + } + // Walk the schema in its depth-first order to count leaves and to sum the + // path lengths: a node at depth d has a path of d+1 names, and remaining + // tracks how many children are still open at each ancestor level, so its + // length is the current depth. + numLeaves := 0 + pathSegments := 0 + // remaining tracks the open-children counts per ancestor level; its cap + // keeps the common shallow schema on the stack, a deeper one grows to heap. + remaining := make([]int32, 0, 16) + for i := range metadata.Schema { + pathSegments += len(remaining) + 1 + if isLeafSchemaElement(&metadata.Schema[i]) { + numLeaves++ + } + if n := metadata.Schema[i].NumChildren; n.Valid && n.V > 0 { + remaining = append(remaining, n.V) + } else { + // A leaf closes itself and any ancestors whose last child it was. + for len(remaining) > 0 { + remaining[len(remaining)-1]-- + if remaining[len(remaining)-1] > 0 { + break + } + remaining = remaining[:len(remaining)-1] + } + } + } + numRowGroups := len(metadata.RowGroups) + + cl.columns = make([]Column, numColumns) + // Every column but the root is a child of exactly one group, and appears + // once in that group's fields. + cl.children = make([]*Column, numColumns-1) + cl.fields = make([]Field, numColumns-1) + cl.paths = make([]string, pathSegments) + + if n := numLeaves * numRowGroups; n > 0 { + cl.chunks = make([]*format.ColumnChunk, n) + if len(columnIndexes) > 0 { + cl.columnIndex = make([]*format.ColumnIndex, n) + } + if len(offsetIndexes) > 0 { + cl.offsetIndex = make([]*format.OffsetIndex, n) + } + } +} + +// allocate cuts the first n elements off the front of the slab and returns them +// with their capacity clamped, so that appending to the result cannot reach into +// the rest of the slab. +// +// The caller must have reserved room for n; a slab shorter than that is a +// programming error and panics. Every slab is sized from the schema, and the +// only value the schema does not bound is a group's NumChildren, which open +// checks against the children slab before allocating from it. +func allocate[T any](slab *[]T, n int) []T { + taken := (*slab)[:n:n] + *slab = (*slab)[n:] + return taken } func (cl *columnLoader) open(file *File, metadata *format.FileMetaData, columnIndexes []format.ColumnIndex, offsetIndexes []format.OffsetIndex, path []string) (*Column, error) { - c := &Column{ - file: file, - schema: &metadata.Schema[cl.schemaIndex], + if cl.schemaIndex >= len(cl.columns) { + return nil, fmt.Errorf("column schema index %d is out of range: %d >= %d", + cl.schemaIndex, cl.schemaIndex, len(cl.columns)) } - c.path = columnPath(path).append(c.schema.Name) + c := &cl.columns[cl.schemaIndex] + c.file = file + c.schema = &metadata.Schema[cl.schemaIndex] + + // A column's path is its parent's path plus its own name, cut from the + // shared slab rather than concatenated into a fresh slice per column. + p := allocate(&cl.paths, len(path)+1) + copy(p, path) + p[len(path)] = c.schema.Name + c.path = columnPath(p) cl.schemaIndex++ numChildren := 0 @@ -309,32 +400,32 @@ func (cl *columnLoader) open(file *File, metadata *format.FileMetaData, columnIn rowGroupColumnIndex := cl.rowGroupColumnIndex cl.rowGroupColumnIndex++ - c.chunks = make([]*format.ColumnChunk, 0, len(rowGroups)) - c.columnIndex = make([]*format.ColumnIndex, 0, len(rowGroups)) - c.offsetIndex = make([]*format.OffsetIndex, 0, len(rowGroups)) + c.chunks = allocate(&cl.chunks, len(rowGroups)) for i, rowGroup := range rowGroups { if rowGroupColumnIndex >= len(rowGroup.Columns) { return nil, fmt.Errorf("row group at index %d does not have enough columns", i) } - c.chunks = append(c.chunks, &rowGroup.Columns[rowGroupColumnIndex]) + c.chunks[i] = &rowGroup.Columns[rowGroupColumnIndex] } if len(columnIndexes) > 0 { + c.columnIndex = allocate(&cl.columnIndex, len(rowGroups)) for i := range rowGroups { if rowGroupColumnIndex >= len(columnIndexes) { return nil, fmt.Errorf("row group at index %d does not have enough column index pages", i) } - c.columnIndex = append(c.columnIndex, &columnIndexes[rowGroupColumnIndex]) + c.columnIndex[i] = &columnIndexes[rowGroupColumnIndex] } } if len(offsetIndexes) > 0 { + c.offsetIndex = allocate(&cl.offsetIndex, len(rowGroups)) for i := range rowGroups { if rowGroupColumnIndex >= len(offsetIndexes) { return nil, fmt.Errorf("row group at index %d does not have enough offset index pages", i) } - c.offsetIndex = append(c.offsetIndex, &offsetIndexes[rowGroupColumnIndex]) + c.offsetIndex[i] = &offsetIndexes[rowGroupColumnIndex] } } @@ -351,6 +442,17 @@ func (cl *columnLoader) open(file *File, metadata *format.FileMetaData, columnIn // the page headers to determine which compression and encodings are // applied. for _, encoding := range c.chunks[0].MetaData.Encoding { + // BIT_PACKED appears in the encodings list when the + // deprecated bit-packed encoding was used for repetition + // or definition levels. Encodings.md: "Note that the + // BIT_PACKED encoding method is only supported for + // encoding repetition and definition levels." It is never + // a data page encoding, so it must not be reported as the + // column encoding (it would make schemas derived from + // this file unwritable). + if encoding == format.BitPacked { + continue + } if c.encoding == nil { c.encoding = LookupEncoding(encoding) } @@ -366,21 +468,37 @@ func (cl *columnLoader) open(file *File, metadata *format.FileMetaData, columnIn } c.typ = &groupType{} - if lt := c.schema.LogicalType; lt.Valid && lt.V.Map != nil { + switch c.schema.LogicalType.Value.(type) { + case *format.MapType: c.typ = &mapType{} - } else if lt.Valid && lt.V.List != nil { + case *format.ListType: c.typ = &listType{} - } else if lt.Valid && lt.V.Variant != nil { + case *format.VariantType: c.typ = &variantType{} - } else if ct := c.schema.ConvertedType; ct.Valid { - switch ct.V { - case deprecated.Map: - c.typ = &mapType{} - case deprecated.List: - c.typ = &listType{} + default: + // Fall back on the deprecated converted type when the schema element + // carries no logical type annotation we recognize. + if ct := c.schema.ConvertedType; ct.Valid { + switch ct.V { + case deprecated.Map: + c.typ = &mapType{} + case deprecated.List: + c.typ = &listType{} + } } } - c.columns = make([]*Column, numChildren) + // Bound NumChildren by what the children slab has left rather than by the + // schema elements that remain. Only the slab bounds the total across every + // group: a schema where each group's claim fits the elements after it can + // still claim more children in total than the schema has to give. + if numChildren > len(cl.children) { + return nil, fmt.Errorf("column %q declares %d children but only %d schema elements are left to be children", + c.schema.Name, numChildren, len(cl.children)) + } + + // Reserve this group's children before recursing, so that a child's own + // children are cut from the slab after ours rather than overlapping them. + c.columns = allocate(&cl.children, numChildren) for i := range c.columns { if cl.schemaIndex >= len(metadata.Schema) { @@ -395,7 +513,7 @@ func (cl *columnLoader) open(file *File, metadata *format.FileMetaData, columnIn } } - c.fields = make([]Field, len(c.columns)) + c.fields = allocate(&cl.fields, len(c.columns)) for i, column := range c.columns { c.fields[i] = column } @@ -414,66 +532,63 @@ func isLeafSchemaElement(element *format.SchemaElement) bool { } func schemaElementTypeOf(s *format.SchemaElement) Type { - if s.LogicalType.Valid { - lt := &s.LogicalType.V - // A logical type exists, the Type interface implementations in this - // package are all based on the logical parquet types declared in the - // format sub-package so we can return them directly via a pointer type - // conversion. - switch { - case lt.UTF8 != nil: - return (*stringType)(lt.UTF8) - case lt.Map != nil: - return (*mapType)(lt.Map) - case lt.List != nil: - return (*listType)(lt.List) - case lt.Enum != nil: - return (*enumType)(lt.Enum) - case lt.Decimal != nil: - // A parquet decimal can be one of several different physical types. - if s.Type.Valid { - var typ Type - switch kind := Kind(s.Type.V); kind { - case Int32: - typ = Int32Type - case Int64: - typ = Int64Type - case ByteArray: - typ = ByteArrayType - case FixedLenByteArray: - if !s.TypeLength.Valid { - panic("DECIMAL using FIXED_LEN_BYTE_ARRAY must specify a length") - } - typ = FixedLenByteArrayType(int(s.TypeLength.V)) - default: - panic("DECIMAL must be of type INT32, INT64, BYTE_ARRAY or FIXED_LEN_BYTE_ARRAY but got " + kind.String()) - } - return &decimalType{ - decimal: *lt.Decimal, - Type: typ, + // A logical type exists, the Type interface implementations in this + // package are all based on the logical parquet types declared in the + // format sub-package so we can return them directly via a pointer type + // conversion. + switch lt := s.LogicalType.Value.(type) { + case *format.StringType: + return (*stringType)(lt) + case *format.MapType: + return (*mapType)(lt) + case *format.ListType: + return (*listType)(lt) + case *format.EnumType: + return (*enumType)(lt) + case *format.DecimalType: + // A parquet decimal can be one of several different physical types. + if s.Type.Valid { + var typ Type + switch kind := Kind(s.Type.V); kind { + case Int32: + typ = Int32Type + case Int64: + typ = Int64Type + case ByteArray: + typ = ByteArrayType + case FixedLenByteArray: + if !s.TypeLength.Valid { + panic("DECIMAL using FIXED_LEN_BYTE_ARRAY must specify a length") } + typ = FixedLenByteArrayType(int(s.TypeLength.V)) + default: + panic("DECIMAL must be of type INT32, INT64, BYTE_ARRAY or FIXED_LEN_BYTE_ARRAY but got " + kind.String()) + } + return &decimalType{ + decimal: *lt, + Type: typ, } - case lt.Date != nil: - return (*dateType)(lt.Date) - case lt.Time != nil: - return (*timeType)(lt.Time) - case lt.Timestamp != nil: - return (*timestampType)(lt.Timestamp) - case lt.Integer != nil: - return (*intType)(lt.Integer) - case lt.Unknown != nil: - return (*nullType)(lt.Unknown) - case lt.Json != nil: - return (*jsonType)(lt.Json) - case lt.Bson != nil: - return (*bsonType)(lt.Bson) - case lt.UUID != nil: - return (*uuidType)(lt.UUID) - case lt.Geometry != nil: - return (*geometryType)(lt.Geometry) - case lt.Geography != nil: - return (*geographyType)(lt.Geography) } + case *format.DateType: + return (*dateType)(lt) + case *format.TimeType: + return canonicalTimeType(lt) + case *format.TimestampType: + return canonicalTimestampType(lt) + case *format.IntType: + return canonicalIntType(lt) + case *format.NullType: + return (*nullType)(lt) + case *format.JsonType: + return (*jsonType)(lt) + case *format.BsonType: + return (*bsonType)(lt) + case *format.UUIDType: + return (*uuidType)(lt) + case *format.GeometryType: + return (*geometryType)(lt) + case *format.GeographyType: + return (*geographyType)(lt) } if s.ConvertedType.Valid { @@ -768,6 +883,12 @@ func (c *Column) decodeDataPage(header DataPageHeader, numValues int, repetition return nil, err } + if !isDictionaryEncoding(pageEncoding) { + if err := checkPageDataCapacity(pageKind, c.Type().Length(), numValues, values); err != nil { + return nil, err + } + } + newPage := pageType.NewPage(c.Index(), numValues, values) switch { case c.maxRepetitionLevel > 0: @@ -865,7 +986,35 @@ func (c *Column) decodeDictionary(header DictionaryPageHeader, page *buffer[byte if err != nil { return nil, err } + if err := checkPageDataCapacity(pageType.Kind(), pageType.Length(), numValues, values); err != nil { + return nil, err + } return pageType.NewDictionary(int(c.index), numValues, values), nil } +// check data buffer has enough capacity for the nubmer of values & value type +func checkPageDataCapacity(kind Kind, typeLength, numValues int, values encoding.Values) error { + n := int64(numValues) + var need int64 + switch kind { + case Boolean: // bit packed + need = (n + 7) / 8 + case Int32, Float: + need = 4 * n + case Int64, Double: + need = 8 * n + case Int96: + need = 12 * n + case FixedLenByteArray: + need = int64(typeLength) * n + default: + return nil + } + data, _ := values.Data() + if int64(cap(data)) < need { + return fmt.Errorf("page header declares %d values requiring %d bytes but decoded buffer holds only %d: %w", numValues, need, cap(data), ErrCorrupted) + } + return nil +} + var _ Node = (*Column)(nil) diff --git a/vendor/github.com/parquet-go/parquet-go/column_buffer_geometry.go b/vendor/github.com/parquet-go/parquet-go/column_buffer_geometry.go index 50d83cd00b9..b86757610f4 100644 --- a/vendor/github.com/parquet-go/parquet-go/column_buffer_geometry.go +++ b/vendor/github.com/parquet-go/parquet-go/column_buffer_geometry.go @@ -3,6 +3,7 @@ package parquet import ( "fmt" + "github.com/parquet-go/parquet-go/format" "github.com/twpayne/go-geom" "github.com/twpayne/go-geom/encoding/wkb" ) @@ -14,9 +15,8 @@ func writeGeometry(col ColumnBuffer, levels columnLevels, value geom.T, node Nod } if logicalType := node.Type().LogicalType(); logicalType != nil { - switch { - case logicalType.Geometry != nil: - case logicalType.Geography != nil: + switch logicalType.Value.(type) { + case *format.GeometryType, *format.GeographyType: // valid default: panic("invalid logical type for value of type geom.T, must be Geometry or Geography") diff --git a/vendor/github.com/parquet-go/parquet-go/column_buffer_json.go b/vendor/github.com/parquet-go/parquet-go/column_buffer_json.go index efea249d312..4f444be3c3d 100644 --- a/vendor/github.com/parquet-go/parquet-go/column_buffer_json.go +++ b/vendor/github.com/parquet-go/parquet-go/column_buffer_json.go @@ -10,6 +10,7 @@ import ( "github.com/parquet-go/bitpack/unsafecast" "github.com/parquet-go/jsonlite" + "github.com/parquet-go/parquet-go/format" ) var jsonNull jsonlite.Value @@ -29,7 +30,7 @@ func jsonParse(data []byte) (*jsonlite.Value, error) { func writeJSONToLeaf(col ColumnBuffer, levels columnLevels, val *jsonlite.Value, node Node) { typ := node.Type() if typ.Kind() == ByteArray { - if logicalType := typ.LogicalType(); logicalType != nil && logicalType.Json != nil { + if logicalType := typ.LogicalType(); logicalTypeIs[*format.JsonType](logicalType) { writeJSONToByteArray(col, levels, val, node) return } @@ -103,8 +104,8 @@ func writeJSONString(col ColumnBuffer, levels columnLevels, str string, node Nod typ := node.Type() if logicalType := typ.LogicalType(); logicalType != nil { - switch { - case logicalType.Timestamp != nil: + switch logicalType.Value.(type) { + case *format.TimestampType: t, err := time.Parse(time.RFC3339, str) if err != nil { panic(fmt.Errorf("cannot parse JSON string %q as timestamp: %w", str, err)) @@ -112,7 +113,7 @@ func writeJSONString(col ColumnBuffer, levels columnLevels, str string, node Nod writeTime(col, levels, t, node) return - case logicalType.Date != nil: + case *format.DateType: t, err := time.Parse("2006-01-02", str) if err != nil { panic(fmt.Errorf("cannot parse JSON string %q as date: %w", str, err)) @@ -120,7 +121,7 @@ func writeJSONString(col ColumnBuffer, levels columnLevels, str string, node Nod writeTime(col, levels, t, node) return - case logicalType.Time != nil: + case *format.TimeType: t, err := time.Parse("15:04:05.000000000", str) if err != nil { panic(fmt.Errorf("cannot parse JSON string %q as time: %w", str, err)) @@ -132,7 +133,7 @@ func writeJSONString(col ColumnBuffer, levels columnLevels, str string, node Nod writeDuration(col, levels, d, node) return - case logicalType.UUID != nil: + case *format.UUIDType: // Only parse UUID strings when writing to binary UUID columns // (FIXED_LEN_BYTE_ARRAY with 16 bytes). If writing to a STRING // column with UUID logical type, write the string as-is. @@ -149,8 +150,8 @@ func writeJSONNumber(col ColumnBuffer, levels columnLevels, num json.Number, nod str := num.String() if logicalType := typ.LogicalType(); logicalType != nil { - switch { - case logicalType.Timestamp != nil: + switch logicalType.Value.(type) { + case *format.TimestampType: // Interpret number as seconds since Unix epoch (with sub-second precision) f, err := num.Float64() if err != nil { @@ -161,7 +162,7 @@ func writeJSONNumber(col ColumnBuffer, levels columnLevels, num json.Number, nod writeTime(col, levels, t, node) return - case logicalType.Date != nil: + case *format.DateType: // Interpret number as seconds since Unix epoch i, err := num.Int64() if err != nil { @@ -171,7 +172,7 @@ func writeJSONNumber(col ColumnBuffer, levels columnLevels, num json.Number, nod writeTime(col, levels, t, node) return - case logicalType.Time != nil: + case *format.TimeType: // Interpret number as seconds since midnight f, err := num.Float64() if err != nil { diff --git a/vendor/github.com/parquet-go/parquet-go/column_buffer_proto.go b/vendor/github.com/parquet-go/parquet-go/column_buffer_proto.go index 31bb7f1147c..abcd5338960 100644 --- a/vendor/github.com/parquet-go/parquet-go/column_buffer_proto.go +++ b/vendor/github.com/parquet-go/parquet-go/column_buffer_proto.go @@ -24,17 +24,17 @@ func writeProtoTimestamp(col ColumnBuffer, levels columnLevels, ts *timestamppb. } var typ = node.Type() var unit format.TimeUnit - if lt := typ.LogicalType(); lt != nil && lt.Timestamp != nil { - unit = lt.Timestamp.Unit + if timestamp, ok := logicalTypeOf[*format.TimestampType](typ.LogicalType()); ok { + unit = timestamp.Unit } else { unit = Nanosecond.TimeUnit() } var t = ts.AsTime() var value int64 - switch { - case unit.Millis != nil: + switch unit.Value.(type) { + case *format.MilliSeconds: value = t.UnixMilli() - case unit.Micros != nil: + case *format.MicroSeconds: value = t.UnixMicro() default: value = t.UnixNano() diff --git a/vendor/github.com/parquet-go/parquet-go/column_buffer_reflect.go b/vendor/github.com/parquet-go/parquet-go/column_buffer_reflect.go index c472f533cba..0eedcda062c 100644 --- a/vendor/github.com/parquet-go/parquet-go/column_buffer_reflect.go +++ b/vendor/github.com/parquet-go/parquet-go/column_buffer_reflect.go @@ -20,6 +20,7 @@ import ( "github.com/google/uuid" "github.com/parquet-go/jsonlite" "github.com/parquet-go/parquet-go/deprecated" + "github.com/parquet-go/parquet-go/format" "github.com/parquet-go/parquet-go/internal/memory" "github.com/parquet-go/parquet-go/sparse" "github.com/twpayne/go-geom" @@ -218,15 +219,15 @@ func writeTime(col ColumnBuffer, levels columnLevels, t time.Time, node Node) { typ := node.Type() if logicalType := typ.LogicalType(); logicalType != nil { - switch { - case logicalType.Timestamp != nil: + switch lt := logicalType.Value.(type) { + case *format.TimestampType: // TIMESTAMP logical type -> write to int64 - unit := logicalType.Timestamp.Unit + unit := lt.Unit var val int64 - switch { - case unit.Millis != nil: + switch unit.Value.(type) { + case *format.MilliSeconds: val = t.UnixMilli() - case unit.Micros != nil: + case *format.MicroSeconds: val = t.UnixMicro() default: val = t.UnixNano() @@ -234,19 +235,19 @@ func writeTime(col ColumnBuffer, levels columnLevels, t time.Time, node Node) { col.writeInt64(levels, val) return - case logicalType.Date != nil: + case *format.DateType: // DATE logical type -> write to int32 col.writeInt32(levels, int32(daysSinceUnixEpoch(t))) return - case logicalType.Time != nil: + case *format.TimeType: // TIME logical type -> write time of day - unit := logicalType.Time.Unit + unit := lt.Unit nanos := timeOfDayNanos(t) - switch { - case unit.Millis != nil: + switch unit.Value.(type) { + case *format.MilliSeconds: col.writeInt32(levels, int32(nanos/1e6)) - case unit.Micros != nil: + case *format.MicroSeconds: col.writeInt64(levels, nanos/1e3) default: col.writeInt64(levels, nanos) @@ -281,13 +282,13 @@ func writeTime(col ColumnBuffer, levels columnLevels, t time.Time, node Node) { func writeDuration(col ColumnBuffer, levels columnLevels, d time.Duration, node Node) { typ := node.Type() - if logicalType := typ.LogicalType(); logicalType != nil && logicalType.Time != nil { + if lt, ok := logicalTypeOf[*format.TimeType](typ.LogicalType()); ok { // TIME logical type - unit := logicalType.Time.Unit - switch { - case unit.Millis != nil: + unit := lt.Unit + switch unit.Value.(type) { + case *format.MilliSeconds: col.writeInt32(levels, int32(d.Milliseconds())) - case unit.Micros != nil: + case *format.MicroSeconds: col.writeInt64(levels, d.Microseconds()) default: col.writeInt64(levels, d.Nanoseconds()) @@ -808,9 +809,8 @@ func writeValueFuncOfLeaf(columnIndex uint16, node Node) (uint16, writeValueFunc case reflect.Float32: typ := node.Type() - logicalType := typ.LogicalType() - if logicalType != nil && logicalType.Decimal != nil { - decimalValue(col, levels, typ, value, logicalType.Decimal.Scale) + if decimal, ok := logicalTypeOf[*format.DecimalType](typ.LogicalType()); ok { + decimalValue(col, levels, typ, value, decimal.Scale) return } col.writeFloat(levels, float32(value.Float())) @@ -818,9 +818,8 @@ func writeValueFuncOfLeaf(columnIndex uint16, node Node) (uint16, writeValueFunc case reflect.Float64: typ := node.Type() - logicalType := typ.LogicalType() - if logicalType != nil && logicalType.Decimal != nil { - decimalValue(col, levels, typ, value, logicalType.Decimal.Scale) + if decimal, ok := logicalTypeOf[*format.DecimalType](typ.LogicalType()); ok { + decimalValue(col, levels, typ, value, decimal.Scale) return } @@ -834,8 +833,7 @@ func writeValueFuncOfLeaf(columnIndex uint16, node Node) (uint16, writeValueFunc writeJSONNumber(col, levels, json.Number(v), node) default: typ := node.Type() - logicalType := typ.LogicalType() - if logicalType != nil && logicalType.UUID != nil { + if logicalTypeIs[*format.UUIDType](typ.LogicalType()) { writeUUID(col, levels, v, typ) return } @@ -972,15 +970,15 @@ func numberToByteArray(data any) []byte { func writeBigFloat(col ColumnBuffer, levels columnLevels, f *big.Float, node Node) { typ := node.Type() - logicalType := typ.LogicalType() - if logicalType == nil || logicalType.Decimal == nil { + decimal, ok := logicalTypeOf[*format.DecimalType](typ.LogicalType()) + if !ok { panic("writeBigFloat requires a decimal logical type") } - scale := int(logicalType.Decimal.Scale) + scale := int(decimal.Scale) // Compute minimum precision needed: decimal precision * log2(10) ≈ precision * 3.32 // We use precision * 4 + 64 for safety margin - minPrec := uint(logicalType.Decimal.Precision)*4 + 64 + minPrec := uint(decimal.Precision)*4 + 64 prec := max(f.Prec(), minPrec) scaleFactor := new(big.Float).SetPrec(prec) scaleFactor.SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(scale)), nil)) diff --git a/vendor/github.com/parquet-go/parquet-go/column_buffer_variant.go b/vendor/github.com/parquet-go/parquet-go/column_buffer_variant.go index 2c1b982835e..d611755b952 100644 --- a/vendor/github.com/parquet-go/parquet-go/column_buffer_variant.go +++ b/vendor/github.com/parquet-go/parquet-go/column_buffer_variant.go @@ -7,8 +7,6 @@ import ( "github.com/parquet-go/parquet-go/variant" ) -// writeValueFuncOfVariant handles writing Go values to variant column buffers. -// Dispatches to unshredded or shredded variant handling. func writeValueFuncOfVariant(columnIndex uint16, node Node) (uint16, writeValueFunc) { if isUnshreddedVariant(node) { return writeValueFuncOfUnshreddedVariant(columnIndex, node) @@ -16,7 +14,6 @@ func writeValueFuncOfVariant(columnIndex uint16, node Node) (uint16, writeValueF return writeValueFuncOfShreddedVariant(columnIndex, node) } -// writeValueFuncOfUnshreddedVariant handles the simple 2-column variant. func writeValueFuncOfUnshreddedVariant(columnIndex uint16, node Node) (uint16, writeValueFunc) { metadataColumnIndex := columnIndex valueColumnIndex := columnIndex + 1 @@ -29,127 +26,102 @@ func writeValueFuncOfUnshreddedVariant(columnIndex uint16, node Node) (uint16, w } } -// writeValueFuncOfShreddedVariant handles the 3-field shredded variant. +// writeValueFuncOfShreddedVariant writes Go values into a shredded variant +// group per the Variant Shredding specification. It shares the shredding +// logic with the row-based write path (variant_shredded_write.go) by +// shredding into a scratch column buffer and flushing the resulting values +// with their levels to the column buffers. func writeValueFuncOfShreddedVariant(columnIndex uint16, node Node) (uint16, writeValueFunc) { - // Fields are sorted alphabetically: metadata, typed_value, value - var metadataColumnIndex, valueColumnIndex, typedValueStartColumn uint16 - var typedValueLeafCount uint16 - var typedValueNode Node - - col := columnIndex - for _, f := range node.Fields() { - n := numLeafColumnsOf(f) - switch f.Name() { - case "metadata": - metadataColumnIndex = col - col += n - case "typed_value": - typedValueStartColumn = col - typedValueNode = f - typedValueLeafCount = n - col += n - case "value": - valueColumnIndex = col - col += n + // Schemas that cannot be written to (e.g. missing the metadata column) + // may still be read from; fail when a row is written, not at build time. + group, err := buildShreddedVariantGroup(node, 0, 0, 0) + if err == nil && group.metadataCol < 0 { + err = fmt.Errorf("variant: shredded variant group has no metadata field") + } + if err != nil { + numCols := numLeafColumnsOf(node) + return columnIndex + numCols, func([]ColumnBuffer, columnLevels, reflect.Value) { + panic(fmt.Sprintf("invalid shredded variant schema: %v", err)) } } - nextColumnIndex := col - - typedInner := Required(typedValueNode) - matcher := buildShreddedMatcher(typedInner) + nextColumnIndex := columnIndex + uint16(group.numCols) return nextColumnIndex, func(columns []ColumnBuffer, levels columnLevels, value reflect.Value) { - metadata, val := variantMarshalOrNull(value) - columns[metadataColumnIndex].writeByteArray(levels, metadata) + // An invalid value means an enclosing optional/repeated wrapper is + // null for this row: the whole variant group is null. + if !value.IsValid() { + for col := range group.numCols { + columns[columnIndex+uint16(col)].writeNull(levels) + } + return + } - goVal := extractGoValue(value) - if goVal != nil && matcher.canShred(goVal) { - // Write null to value column - columns[valueColumnIndex].writeNull(levels) - // Write typed value (increment def level for optional wrapper) - typedLevels := levels - typedLevels.definitionLevel++ - writeShredded(columns, typedLevels, typedValueStartColumn, &matcher, goVal) + var v variant.Value + if metaBytes, valBytes, ok := extractRawVariantStruct(value); ok { + m, err := variant.DecodeMetadata(metaBytes) + if err != nil { + panic(fmt.Sprintf("variant metadata: %v", err)) + } + if v, err = variant.Decode(m, valBytes); err != nil { + panic(fmt.Sprintf("variant decode: %v", err)) + } } else { - // Write variant bytes to value column - valueLevels := levels - valueLevels.definitionLevel++ - columns[valueColumnIndex].writeByteArray(valueLevels, val) - // Write null to all typed_value columns - for col := typedValueStartColumn; col < typedValueStartColumn+typedValueLeafCount; col++ { - columns[col].writeNull(levels) + var err error + if v, err = variant.ValueOf(extractGoValue(value)); err != nil { + panic(fmt.Sprintf("variant marshal: %v", err)) } } - } -} -// writeShredded writes a shredded value to the column buffers. -func writeShredded(columns []ColumnBuffer, levels columnLevels, startColumn uint16, m *shreddedMatcher, v any) { - if m.isPrimitive() { - pv := goValueToParquetValue(v, m.kind()) - col := columns[startColumn] - switch m.kind() { - case Boolean: - col.writeBoolean(levels, pv.Boolean()) - case Int32: - col.writeInt32(levels, pv.Int32()) - case Int64: - col.writeInt64(levels, pv.Int64()) - case Float: - col.writeFloat(levels, pv.Float()) - case Double: - col.writeDouble(levels, pv.Double()) - case ByteArray: - col.writeByteArray(levels, pv.ByteArray()) - default: - col.writeByteArray(levels, pv.ByteArray()) - } - return - } - if m.isGroup() { - writeShreddedObject(columns, levels, startColumn, m, v) - } -} + var b variant.MetadataBuilder + addVariantFieldNames(&b, v) -func writeShreddedObject(columns []ColumnBuffer, levels columnLevels, startColumn uint16, m *shreddedMatcher, v any) { - obj, ok := v.(map[string]any) - if !ok { - return - } + // One backing slab gives every scratch column capacity for the + // common one-value-per-column case without a per-column allocation; + // only columns under a repeated list can grow past it. + scratch := make([][]Value, group.numCols) + slab := make([]Value, len(scratch)) + for i := range scratch { + scratch[i] = slab[i : i : i+1] + } + group.write(scratch, 0, &b, v, true, shredLevels{ + baseDef: int(levels.definitionLevel), + baseRep: int(levels.repetitionDepth), + rep: levels.repetitionLevel, + }) - col := startColumn - for _, f := range m.fields { - // Within each field's sub-group, fields are sorted alphabetically: - // typed_value comes before value. - typedValueCol := col - typedCount := f.matcher.leafCount - valueCol := col + typedCount - nextFieldCol := valueCol + 1 + _, metadata := b.Build() + columns[columnIndex+uint16(group.metadataCol)].writeByteArray(levels, metadata) - fieldVal, exists := obj[f.name] - if exists && fieldVal != nil && f.matcher.canShred(fieldVal) { - columns[valueCol].writeNull(levels) - typedLevels := levels - typedLevels.definitionLevel++ - writeShredded(columns, typedLevels, typedValueCol, &f.matcher, fieldVal) - } else if exists && fieldVal != nil { - valueLevels := levels - valueLevels.definitionLevel++ - metadata, val, err := variant.Marshal(fieldVal) - if err != nil { - panic(fmt.Sprintf("variant marshal field %q: %v", f.name, err)) + for col, values := range scratch { + if col == group.metadataCol { + continue } - combined := encodeFieldVariant(metadata, val) - columns[valueCol].writeByteArray(valueLevels, combined) - for c := typedValueCol; c < typedValueCol+typedCount; c++ { - columns[c].writeNull(levels) - } - } else { - for c := typedValueCol; c < nextFieldCol; c++ { - columns[c].writeNull(levels) + buffer := columns[columnIndex+uint16(col)] + for _, val := range values { + valueLevels := columnLevels{ + repetitionDepth: levels.repetitionDepth, + repetitionLevel: val.repetitionLevel, + definitionLevel: val.definitionLevel, + } + if val.IsNull() { + buffer.writeNull(valueLevels) + continue + } + switch val.Kind() { + case Boolean: + buffer.writeBoolean(valueLevels, val.Boolean()) + case Int32: + buffer.writeInt32(valueLevels, val.Int32()) + case Int64: + buffer.writeInt64(valueLevels, val.Int64()) + case Float: + buffer.writeFloat(valueLevels, val.Float()) + case Double: + buffer.writeDouble(valueLevels, val.Double()) + default: + buffer.writeByteArray(valueLevels, val.ByteArray()) + } } } - - col = nextFieldCol } } diff --git a/vendor/github.com/parquet-go/parquet-go/column_buffer_write.go b/vendor/github.com/parquet-go/parquet-go/column_buffer_write.go index dbe1413b458..fcdce3883b8 100644 --- a/vendor/github.com/parquet-go/parquet-go/column_buffer_write.go +++ b/vendor/github.com/parquet-go/parquet-go/column_buffer_write.go @@ -12,6 +12,7 @@ import ( "github.com/parquet-go/jsonlite" "github.com/parquet-go/parquet-go/deprecated" + "github.com/parquet-go/parquet-go/format" "github.com/parquet-go/parquet-go/internal/memory" "github.com/parquet-go/parquet-go/sparse" "google.golang.org/protobuf/types/known/structpb" @@ -34,7 +35,7 @@ type writeRowsFunc func(columns []ColumnBuffer, levels columnLevels, rows sparse func writeRowsFuncOf(t reflect.Type, schema *Schema, path columnPath, tagReplacements []StructTagOption) writeRowsFunc { if leaf, exists := schema.Lookup(path...); exists { logicalType := leaf.Node.Type().LogicalType() - if logicalType != nil && logicalType.Json != nil { + if logicalTypeIs[*format.JsonType](logicalType) { return writeRowsFuncOfJSON(t, schema, path) } } @@ -918,21 +919,21 @@ func writeRowsFuncOfJSON(t reflect.Type, schema *Schema, path columnPath) writeR func writeRowsFuncOfTime(_ reflect.Type, schema *Schema, path columnPath, tagReplacements []StructTagOption) writeRowsFunc { t := reflect.TypeFor[int64]() - elemSize := uintptr(t.Size()) writeRows := writeRowsFuncOf(t, schema, path, tagReplacements) col, _ := schema.Lookup(path...) unit := Nanosecond.TimeUnit() lt := col.Node.Type().LogicalType() - if lt != nil && lt.Timestamp != nil { - unit = lt.Timestamp.Unit + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok { + unit = ts.Unit } // Check if the column is optional isOptional := col.Node.Optional() return func(columns []ColumnBuffer, levels columnLevels, rows sparse.Array) { - if rows.Len() == 0 { + n := rows.Len() + if n == 0 { writeRows(columns, levels, rows) return } @@ -945,38 +946,53 @@ func writeRowsFuncOfTime(_ reflect.Type, schema *Schema, path columnPath, tagRep // definitionLevel starts at 0. alreadyHandled := isOptional && levels.definitionLevel > 0 - times := rows.TimeArray() - for i := range times.Len() { - t := times.Index(i) + buf := wideIntBufPool.Get( + func() *wideIntBuf { return new(wideIntBuf) }, + func(b *wideIntBuf) { b.values = b.values[:0] }, + ) + buf.values = slices.Grow(buf.values, n)[:n] + defer wideIntBufPool.Put(buf) - // For optional fields, check if the value is zero - // (unless already handled by pointer wrapper). - elemLevels := levels - if isOptional && !alreadyHandled && t.IsZero() { - // Write as NULL (don't increment definition level). - empty := sparse.Array{} - writeRows(columns, elemLevels, empty) - continue + times := rows.TimeArray() + switch unit.Value.(type) { + case *format.MilliSeconds: + for i := range n { + buf.values[i] = times.Index(i).UnixMilli() } - - // For optional non-zero values, increment definition level - // (unless already handled). - if isOptional && !alreadyHandled { - elemLevels.definitionLevel++ + case *format.MicroSeconds: + for i := range n { + buf.values[i] = times.Index(i).UnixMicro() } + default: + for i := range n { + buf.values[i] = times.Index(i).UnixNano() + } + } - var val int64 - switch { - case unit.Millis != nil: - val = t.UnixMilli() - case unit.Micros != nil: - val = t.UnixMicro() - default: - val = t.UnixNano() + if !isOptional || alreadyHandled { + writeRows(columns, levels, sparse.MakeInt64Array(buf.values).UnsafeArray()) + return + } + + i := 0 + empty := sparse.Array{} + for i < n { + j := i + isNull := times.Index(i).IsZero() + for j < n && times.Index(j).IsZero() == isNull { + j++ } - a := makeArray(reflectValueData(reflect.ValueOf(val)), 1, elemSize) - writeRows(columns, elemLevels, a) + if isNull { + for k := i; k < j; k++ { + writeRows(columns, levels, empty) + } + } else { + elemLevels := levels + elemLevels.definitionLevel++ + writeRows(columns, elemLevels, sparse.MakeInt64Array(buf.values[i:j]).UnsafeArray()) + } + i = j } } } diff --git a/vendor/github.com/parquet-go/parquet-go/compare.go b/vendor/github.com/parquet-go/parquet-go/compare.go index c37f2f7e066..49817afbce8 100644 --- a/vendor/github.com/parquet-go/parquet-go/compare.go +++ b/vendor/github.com/parquet-go/parquet-go/compare.go @@ -1,6 +1,7 @@ package parquet import ( + "bytes" "encoding/binary" "github.com/parquet-go/parquet-go/deprecated" @@ -226,12 +227,170 @@ func compareRowsFuncOfIndexColumns(compareFuncs []func(Row, Row) int) func(Row, //go:noinline func compareRowsFuncOfIndexAscending(columnIndex uint16, typ Type) func(Row, Row) int { - return func(row1, row2 Row) int { return typ.Compare(row1[columnIndex], row2[columnIndex]) } + switch t := typ.(type) { + case int32Type: + return func(row1, row2 Row) int { + return compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + case uint32Type: + return func(row1, row2 Row) int { + return compareUint32(row1[columnIndex].uint32(), row2[columnIndex].uint32()) + } + case int64Type: + return func(row1, row2 Row) int { + return compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + case uint64Type: + return func(row1, row2 Row) int { + return compareUint64(row1[columnIndex].uint64(), row2[columnIndex].uint64()) + } + case floatType: + return func(row1, row2 Row) int { + return compareFloat32(row1[columnIndex].float(), row2[columnIndex].float()) + } + case doubleType: + return func(row1, row2 Row) int { + return compareFloat64(row1[columnIndex].double(), row2[columnIndex].double()) + } + case booleanType: + return func(row1, row2 Row) int { + return compareBool(row1[columnIndex].boolean(), row2[columnIndex].boolean()) + } + case byteArrayType, *stringType, fixedLenByteArrayType, *enumType, *geographyType, *bsonType, *geometryType, *jsonType: + return func(row1, row2 Row) int { + return bytes.Compare(row1[columnIndex].byteArray(), row2[columnIndex].byteArray()) + } + case be128Type, *uuidType: + return func(row1, row2 Row) int { + return compareBE128(row1[columnIndex].be128(), row2[columnIndex].be128()) + } + case *dateType: + return func(row1, row2 Row) int { + return compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + case *timestampType: + return func(row1, row2 Row) int { + return compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + case *timeType: + if t.useInt32() { + return func(row1, row2 Row) int { + return compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + } else { + return func(row1, row2 Row) int { + return compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + } + case *intType: + if t.BitWidth == 64 { + if t.IsSigned { + return func(row1, row2 Row) int { + return compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + } else { + return func(row1, row2 Row) int { + return compareUint64(row1[columnIndex].uint64(), row2[columnIndex].uint64()) + } + } + } else { + if t.IsSigned { + return func(row1, row2 Row) int { + return compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + } else { + return func(row1, row2 Row) int { + return compareUint32(row1[columnIndex].uint32(), row2[columnIndex].uint32()) + } + } + } + default: + return func(row1, row2 Row) int { return typ.Compare(row1[columnIndex], row2[columnIndex]) } + } } //go:noinline func compareRowsFuncOfIndexDescending(columnIndex uint16, typ Type) func(Row, Row) int { - return func(row1, row2 Row) int { return -typ.Compare(row1[columnIndex], row2[columnIndex]) } + switch t := typ.(type) { + case int32Type: + return func(row1, row2 Row) int { + return -compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + case uint32Type: + return func(row1, row2 Row) int { + return -compareUint32(row1[columnIndex].uint32(), row2[columnIndex].uint32()) + } + case int64Type: + return func(row1, row2 Row) int { + return -compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + case uint64Type: + return func(row1, row2 Row) int { + return -compareUint64(row1[columnIndex].uint64(), row2[columnIndex].uint64()) + } + case floatType: + return func(row1, row2 Row) int { + return -compareFloat32(row1[columnIndex].float(), row2[columnIndex].float()) + } + case doubleType: + return func(row1, row2 Row) int { + return -compareFloat64(row1[columnIndex].double(), row2[columnIndex].double()) + } + case booleanType: + return func(row1, row2 Row) int { + return -compareBool(row1[columnIndex].boolean(), row2[columnIndex].boolean()) + } + case byteArrayType, *stringType, fixedLenByteArrayType, *enumType, *geographyType, *bsonType, *geometryType, *jsonType: + return func(row1, row2 Row) int { + return -bytes.Compare(row1[columnIndex].byteArray(), row2[columnIndex].byteArray()) + } + case be128Type, *uuidType: + return func(row1, row2 Row) int { + return -compareBE128(row1[columnIndex].be128(), row2[columnIndex].be128()) + } + case *dateType: + return func(row1, row2 Row) int { + return -compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + case *timestampType: + return func(row1, row2 Row) int { + return -compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + case *timeType: + if t.useInt32() { + return func(row1, row2 Row) int { + return -compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + } else { + return func(row1, row2 Row) int { + return -compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + } + case *intType: + if t.BitWidth == 64 { + if t.IsSigned { + return func(row1, row2 Row) int { + return -compareInt64(row1[columnIndex].int64(), row2[columnIndex].int64()) + } + } else { + return func(row1, row2 Row) int { + return -compareUint64(row1[columnIndex].uint64(), row2[columnIndex].uint64()) + } + } + } else { + if t.IsSigned { + return func(row1, row2 Row) int { + return -compareInt32(row1[columnIndex].int32(), row2[columnIndex].int32()) + } + } else { + return func(row1, row2 Row) int { + return -compareUint32(row1[columnIndex].uint32(), row2[columnIndex].uint32()) + } + } + } + default: + return func(row1, row2 Row) int { return -typ.Compare(row1[columnIndex], row2[columnIndex]) } + } } //go:noinline diff --git a/vendor/github.com/parquet-go/parquet-go/config.go b/vendor/github.com/parquet-go/parquet-go/config.go index 6492d07c798..a21f3ed2fac 100644 --- a/vendor/github.com/parquet-go/parquet-go/config.go +++ b/vendor/github.com/parquet-go/parquet-go/config.go @@ -319,6 +319,7 @@ func (c *WriterConfig) ConfigureWriter(config *WriterConfig) { SkipPageBounds: coalesceSlices(c.SkipPageBounds, config.SkipPageBounds), SkipPageStatistics: coalesceSlices(c.SkipPageStatistics, config.SkipPageStatistics), Encodings: encodings, + DictionaryMaxBytes: cmp.Or(c.DictionaryMaxBytes, config.DictionaryMaxBytes), SchemaConfig: cmp.Or(c.SchemaConfig, config.SchemaConfig), Encryption: cmp.Or(c.Encryption, config.Encryption), } diff --git a/vendor/github.com/parquet-go/parquet-go/convert.go b/vendor/github.com/parquet-go/parquet-go/convert.go index a1d0439945b..93195d04a49 100644 --- a/vendor/github.com/parquet-go/parquet-go/convert.go +++ b/vendor/github.com/parquet-go/parquet-go/convert.go @@ -62,8 +62,11 @@ type Conversion interface { type conversion struct { columns []conversionColumn - schema *Schema - buffers memory.Pool[conversionBuffer] + // Shredded variant columns of the source being reconstructed to + // unshredded variant columns of the target (see convert_variant.go). + variants []variantConversion + schema *Schema + buffers memory.Pool[conversionBuffer] // This field is used to size the column buffers held in the memory.Pool since // they are intended to store the source rows being converted from. numberOfSourceColumns int @@ -71,6 +74,9 @@ type conversion struct { type conversionBuffer struct { columns [][]Value + // Per-variant-conversion scratch space, reused across rows (see + // convert_variant.go). + variants []variantScratch } type conversionColumn struct { @@ -78,6 +84,11 @@ type conversionColumn struct { convertValues conversionFunc targetKind Kind // Target column kind for creating proper null values isOptional bool // Whether the target column is optional (for null handling) + // Index in conversion.variants of the variant conversion producing this + // column, or -1; variantOutput selects its metadata (0) or value (1) + // output column. + variantIndex int + variantOutput int } type conversionFunc func([]Value) error @@ -189,6 +200,17 @@ func convertToLevels(repetitionLevels, definitionLevels []byte) conversionFunc { for i := range column { r := column[i].repetitionLevel d := column[i].definitionLevel + // Source levels that exceed the lookup-table size can be produced + // when maskMissingRowGroupColumns or sibling-fallback synthesizes + // values for schemas where source and target disagree on optionality + // or nesting depth. Without this guard, the convertedRows reader + // panics with "index out of range" inside this hot loop. Treat the + // value as null so downstream Reconstruct skips it instead of + // dereferencing a placeholder's nil byte-array pointer. + if int(r) >= len(repetitionLevels) || int(d) >= len(definitionLevels) { + column[i] = Value{} + continue + } column[i].repetitionLevel = repetitionLevels[r] column[i].definitionLevel = definitionLevels[d] } @@ -218,7 +240,8 @@ func (c *conversion) getBuffer() *conversionBuffer { return c.buffers.Get( func() *conversionBuffer { b := &conversionBuffer{ - columns: make([][]Value, c.numberOfSourceColumns), + columns: make([][]Value, c.numberOfSourceColumns), + variants: make([]variantScratch, len(c.variants)), } values := make([]Value, c.numberOfSourceColumns) for i := range b.columns { @@ -250,7 +273,26 @@ func (c *conversion) Convert(rows []Row) (int, error) { }) row = row[:0] + // Reconstruct shredded variant columns once per row; the column + // loop below picks up the metadata and value outputs. + for k := range c.variants { + if err := c.variants[k].convert(source.columns, &source.variants[k]); err != nil { + return n, err + } + } + for columnIndex, conv := range c.columns { + if conv.variantIndex >= 0 { + // Values already carry final levels and column indexes. + scratch := &source.variants[conv.variantIndex] + if conv.variantOutput == 0 { + row = append(row, scratch.metas...) + } else { + row = append(row, scratch.values...) + } + continue + } + columnOffset := len(row) // Get source values if available @@ -318,6 +360,11 @@ func (id identity) Schema() *Schema { return id.schema } // stripped out of the rows. Extra columns in the target schema will be set to // null or zero values. // +// Variant columns that the target declares unshredded but the source stores +// shredded are reconstructed with the construct_variant algorithm of the +// Variant Shredding specification instead of being mapped column-by-column +// (see convert_variant.go). +// // The returned function is intended to be used to append the converted source // row to the destination buffer. func Convert(to, from Node) (conv Conversion, err error) { @@ -330,6 +377,34 @@ func Convert(to, from Node) (conv Conversion, err error) { return identity{schema}, nil } + // Variant columns that the target declares unshredded but the source + // stores shredded are reconstructed, not mapped column-by-column (see + // convert_variant.go). + variants := findVariantConversions(to, from) + variantColumns := make(map[int]conversionColumn, 2*len(variants)) + for k := range variants { + vc := &variants[k] + metaSource, valueSource := 0, 0 + if vc.group != nil { + metaSource = vc.group.metadataCol + // Shredded groups without a value column are legal; any column + // of the group keeps the source chunk mapping meaningful. + valueSource = max(vc.group.valueCol, 0) + } + variantColumns[vc.targetMetaCol] = conversionColumn{ + sourceIndex: vc.sourceStart + metaSource, + targetKind: ByteArray, + variantIndex: k, + variantOutput: 0, + } + variantColumns[vc.targetValueCol] = conversionColumn{ + sourceIndex: vc.sourceStart + valueSource, + targetKind: ByteArray, + variantIndex: k, + variantOutput: 1, + } + } + targetMapping, targetColumns := columnMappingOf(to) sourceMapping, sourceColumns := columnMappingOf(from) columns := make([]conversionColumn, len(targetColumns)) @@ -352,6 +427,11 @@ func Convert(to, from Node) (conv Conversion, err error) { } for i, path := range targetColumns { + if cc, ok := variantColumns[i]; ok { + columns[i] = cc + continue + } + targetColumn := targetMapping.lookup(path) sourceColumn := sourceMapping.lookup(path) @@ -455,11 +535,13 @@ func Convert(to, from Node) (conv Conversion, err error) { convertValues: multiConversionFunc(conversions), targetKind: targetType.Kind(), // Store target kind for null value creation isOptional: isOptional, + variantIndex: -1, } } c := &conversion{ columns: columns, + variants: variants, schema: schema, numberOfSourceColumns: len(sourceColumns), } @@ -648,6 +730,17 @@ func maskMissingRowGroupColumns(r RowGroup, numColumns int, conv Conversion) Row } } + // Shredded variant reconstruction reads every leaf column of the + // variant group, not just the ones mapped to target columns. + if c, ok := conv.(*conversion); ok { + for k := range c.variants { + vc := &c.variants[k] + for j := vc.sourceStart; j < vc.sourceStart+vc.numCols && j < len(columns); j++ { + columns[j] = rowGroupColumns[j] + } + } + } + return &rowGroup{ schema: r.Schema(), numRows: numRows, @@ -1570,15 +1663,13 @@ func timestamp(v Value, u format.TimeUnit, tz *time.Location) time.Time { return unixEpoch.In(tz).Add(time.Duration(v.int64()) * timeUnitDuration(u)) } +// timeUnitDuration returns the precision of unit, defaulting to nanoseconds +// when the unit is unset (an unknown unit written by a newer implementation). func timeUnitDuration(unit format.TimeUnit) time.Duration { - switch { - case unit.Millis != nil: - return time.Millisecond - case unit.Micros != nil: - return time.Microsecond - default: + if unit.Value == nil { return time.Nanosecond } + return unit.Value.Duration() } func invalidConversion(value Value, from, to string) error { diff --git a/vendor/github.com/parquet-go/parquet-go/convert_variant.go b/vendor/github.com/parquet-go/parquet-go/convert_variant.go new file mode 100644 index 00000000000..48b53afadea --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/convert_variant.go @@ -0,0 +1,235 @@ +package parquet + +import ( + "fmt" + + "github.com/parquet-go/parquet-go/variant" +) + +// This file teaches schema conversion to read shredded variant columns. +// When the target schema declares an unshredded variant group (metadata, +// value) and the source schema stores the column shredded (metadata, value, +// typed_value), the conversion reconstructs each value with the +// construct_variant algorithm (see variant_shredded_read.go) and emits the +// re-encoded variant binary. Without this, the generic column mapping would +// silently drop the typed_value columns, losing every shredded value. +// +// Because every read path funnels through Convert when the reader and file +// schemas differ, this single integration point makes shredded files +// readable by any reader that declares a plain variant column. + +// variantConversion reconstructs one shredded variant column during row +// conversion. +type variantConversion struct { + group *shreddedVariantGroup + // A source group that cannot be reconstructed (e.g. an unsupported + // shredded type) fails when rows are read, not when the conversion is + // constructed, matching how readers report other malformed files. + err error + numCols int // leaf columns of the source variant group + sourceStart int // first source leaf column of the variant group + + targetMetaCol int + targetValueCol int + targetDef byte // definition level of the target leaves when present + + sourceGroupDef int // definition level at which the source group is present + sourceGroupRep int // repetition level of the source group + + // Source-to-target level mappings for the path down to the variant + // group, used for occurrences where the group is null because of a + // null enclosing level. + defLevels []byte + repLevels []byte +} + +// findVariantConversions walks the target and source schemas in parallel +// and returns a conversion for every variant column that the target +// declares unshredded and the source stores shredded. +func findVariantConversions(to, from Node) []variantConversion { + var conversions []variantConversion + walkVariantConversions(to, from, 0, 0, 0, 0, 0, 0, []byte{0}, []byte{0}, &conversions) + return conversions +} + +func walkVariantConversions(t, s Node, tCol, sCol int, tRep, tDef, sRep, sDef byte, repLevels, defLevels []byte, conversions *[]variantConversion) { + if isVariant(t) && isVariant(s) && isUnshreddedVariant(t) && !isUnshreddedVariant(s) { + if vc := makeVariantConversion(t, s, tCol, sCol, tDef, sDef, sRep, repLevels, defLevels); vc != nil { + *conversions = append(*conversions, *vc) + } + return + } + if t.Leaf() || s.Leaf() { + return + } + sColOf := make(map[string]int, len(s.Fields())) + sFieldOf := make(map[string]Field, len(s.Fields())) + col := sCol + for _, sf := range s.Fields() { + sColOf[sf.Name()] = col + sFieldOf[sf.Name()] = sf + col += int(numLeafColumnsOf(sf)) + } + for _, tf := range t.Fields() { + if sf, ok := sFieldOf[tf.Name()]; ok { + tr, td := applyFieldRepetitionType(fieldRepetitionTypeOf(tf), tRep, tDef) + sr, sd := applyFieldRepetitionType(fieldRepetitionTypeOf(sf), sRep, sDef) + walkVariantConversions( + tf, sf, + tCol, sColOf[tf.Name()], + tr, td, sr, sd, + setLevelMapping(repLevels, sr, tr), + setLevelMapping(defLevels, sd, td), + conversions, + ) + } + tCol += int(numLeafColumnsOf(tf)) + } +} + +// makeVariantConversion builds the conversion for one variant column. The +// level arguments are those of the variant group nodes themselves. A nil +// result means the target group does not have the expected metadata and +// value leaves and the generic column mapping applies. +func makeVariantConversion(t, s Node, tCol, sCol int, tDef, sDef, sRep byte, repLevels, defLevels []byte) *variantConversion { + vc := &variantConversion{ + numCols: int(numLeafColumnsOf(s)), + sourceStart: sCol, + targetMetaCol: -1, + targetValueCol: -1, + targetDef: tDef, + sourceGroupDef: int(sDef), + sourceGroupRep: int(sRep), + defLevels: defLevels, + repLevels: repLevels, + } + col := tCol + for _, tf := range t.Fields() { + if !tf.Leaf() || tf.Type().Kind() != ByteArray || tf.Optional() { + return nil + } + switch tf.Name() { + case "metadata": + vc.targetMetaCol = col + case "value": + vc.targetValueCol = col + } + col++ + } + if vc.targetMetaCol < 0 || vc.targetValueCol < 0 { + return nil + } + + vc.group, vc.err = buildShreddedVariantGroup(s, 0, 0, 0) + if vc.err == nil && vc.group.metadataCol < 0 { + vc.group, vc.err = nil, fmt.Errorf("variant: shredded variant group has no metadata field") + } + return vc +} + +// setLevelMapping returns a copy of the source-to-target level mapping with +// the entry for the source level set, extending the table when the source +// level is new (each schema step adds at most one level). +func setLevelMapping(levels []byte, source, target byte) []byte { + mapping := make([]byte, max(len(levels), int(source)+1)) + copy(mapping, levels) + mapping[source] = target + return mapping +} + +// variantScratch is the per-row state of one variant conversion, pooled in +// conversionBuffer so converting a row does not allocate it anew. +type variantScratch struct { + pos []int + metas []Value + values []Value +} + +// convert reconstructs every occurrence of the variant column in the +// current row from the source columns, leaving the values of the target +// metadata and value columns in the scratch space. +func (vc *variantConversion) convert(source [][]Value, scratch *variantScratch) error { + if vc.err != nil { + return vc.err + } + columns := source[vc.sourceStart : vc.sourceStart+vc.numCols] + if cap(scratch.pos) < len(columns) { + scratch.pos = make([]int, len(columns)) + } + scratch.pos = scratch.pos[:len(columns)] + clear(scratch.pos) + scratch.metas = scratch.metas[:0] + scratch.values = scratch.values[:0] + reader := variantColumnReader{columns: columns, pos: scratch.pos} + metaIdx := ^uint16(vc.targetMetaCol) + valueIdx := ^uint16(vc.targetValueCol) + + for { + metaVal, ok := reader.peek(vc.group.metadataCol) + if !ok { + break + } + + // The level mapping tables cover the levels the schema can + // produce; corrupt files can carry level bytes beyond them, which + // must surface as a decode error rather than a panic. + if int(metaVal.repetitionLevel) >= len(vc.repLevels) || int(metaVal.definitionLevel) >= len(vc.defLevels) { + return fmt.Errorf("variant: metadata column has levels (r=%d, d=%d) outside the schema's levels", + metaVal.repetitionLevel, metaVal.definitionLevel) + } + + if int(metaVal.definitionLevel) < vc.sourceGroupDef { + // The variant group is null at this occurrence; every leaf + // column of the group carries exactly one value at the + // enclosing level to consume. + rep := vc.repLevels[metaVal.repetitionLevel] + def := vc.defLevels[metaVal.definitionLevel] + scratch.metas = append(scratch.metas, Value{repetitionLevel: rep, definitionLevel: def, columnIndex: metaIdx}) + scratch.values = append(scratch.values, Value{repetitionLevel: rep, definitionLevel: def, columnIndex: valueIdx}) + for col := range columns { + reader.next(col) + } + continue + } + + reader.next(vc.group.metadataCol) + m, err := variant.DecodeMetadata(metaVal.ByteArray()) + if err != nil { + return fmt.Errorf("variant metadata: %w", err) + } + v, present, err := vc.group.read(&reader, m, vc.sourceGroupDef, vc.sourceGroupRep) + if err != nil { + return err + } + if !present { + // value and typed_value both null at the top level is invalid + // per the spec; read it as variant null (matching parquet-java). + v = variant.Null() + } + + var b variant.MetadataBuilder + encoded := variant.Encode(&b, v) + _, metadata := b.Build() + rep := vc.repLevels[metaVal.repetitionLevel] + + metaValue := ByteArrayValue(metadata) + metaValue.repetitionLevel = rep + metaValue.definitionLevel = vc.targetDef + metaValue.columnIndex = metaIdx + + valueValue := ByteArrayValue(encoded) + valueValue.repetitionLevel = rep + valueValue.definitionLevel = vc.targetDef + valueValue.columnIndex = valueIdx + + scratch.metas = append(scratch.metas, metaValue) + scratch.values = append(scratch.values, valueValue) + } + if len(scratch.metas) == 0 { + // No values in the source columns for this row; emit a null pair + // to maintain the one-value-per-column invariant. + scratch.metas = append(scratch.metas, Value{columnIndex: metaIdx}) + scratch.values = append(scratch.values, Value{columnIndex: valueIdx}) + } + return nil +} diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/rle/rle.go b/vendor/github.com/parquet-go/parquet-go/encoding/rle/rle.go index 6aef0ae3286..6d7bda6f694 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/rle/rle.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/rle/rle.go @@ -260,6 +260,9 @@ func decodeBits(dst, src []byte) ([]byte, error) { i += n count, bitpacked := uint(u>>1), (u&1) != 0 + if count == 0 { + continue + } if count > maxSupportedValueCount { return dst, fmt.Errorf("decoded run-length block cannot have more than %d values", maxSupportedValueCount) } @@ -305,6 +308,9 @@ func decodeBytes(dst, src []byte, bitWidth uint) ([]byte, error) { i += n count, bitpacked := uint(u>>1), (u&1) != 0 + if count == 0 { + continue + } if count > maxSupportedValueCount { return dst, fmt.Errorf("decoded run-length block cannot have more than %d values", maxSupportedValueCount) } @@ -361,6 +367,9 @@ func decodeInt32(dst, src []byte, bitWidth uint) ([]byte, error) { i += n count, bitpacked := uint(u>>1), (u&1) != 0 + if count == 0 { + continue + } if count > maxSupportedValueCount { return dst, fmt.Errorf("decoded run-length block cannot have more than %d values", maxSupportedValueCount) } diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/binary.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/binary.go index f9798be5a93..6f96bc0473e 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/binary.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/binary.go @@ -18,7 +18,7 @@ type BinaryProtocol struct { NonStrict bool } -func (p *BinaryProtocol) NewReaderFromBytes(b []byte) Reader { +func (p *BinaryProtocol) NewReaderFromBytes(b []byte) BytesReader { return &binaryBytesReader{p: p, data: b} } @@ -400,6 +400,11 @@ type binaryBytesReader struct { offset int } +func (r *binaryBytesReader) ResetBytes(b []byte) { + r.data = b + r.offset = 0 +} + func (r *binaryBytesReader) Protocol() Protocol { return r.p } @@ -408,6 +413,18 @@ func (r *binaryBytesReader) Reader() io.Reader { return bytes.NewReader(r.data[r.offset:]) } +// Discard advances the reader past the next n bytes, reporting how many +// bytes were discarded. Unlike reading through Reader(), it moves the +// reader's own offset, which skip operations rely on. +func (r *binaryBytesReader) Discard(n int) (int, error) { + if remain := len(r.data) - r.offset; remain < n { + r.offset = len(r.data) + return remain, io.ErrUnexpectedEOF + } + r.offset += n + return n, nil +} + func (r *binaryBytesReader) ReadBool() (bool, error) { b, err := r.ReadByte() // Thrift protocol treats both 0 and 2 as false. diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/compact.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/compact.go index 249b3d8b9e8..b17b789c58b 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/compact.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/compact.go @@ -16,7 +16,7 @@ import ( // https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md#integer-encoding type CompactProtocol struct{} -func (p *CompactProtocol) NewReaderFromBytes(b []byte) Reader { +func (p *CompactProtocol) NewReaderFromBytes(b []byte) BytesReader { return &compactBytesReader{protocol: p, data: b} } @@ -372,6 +372,11 @@ type compactBytesReader struct { offset int } +func (r *compactBytesReader) ResetBytes(b []byte) { + r.data = b + r.offset = 0 +} + func (r *compactBytesReader) Protocol() Protocol { return r.protocol } @@ -380,6 +385,18 @@ func (r *compactBytesReader) Reader() io.Reader { return bytes.NewReader(r.data[r.offset:]) } +// Discard advances the reader past the next n bytes, reporting how many +// bytes were discarded. Unlike reading through Reader(), it moves the +// reader's own offset, which skip operations rely on. +func (r *compactBytesReader) Discard(n int) (int, error) { + if remain := len(r.data) - r.offset; remain < n { + r.offset = len(r.data) + return remain, io.ErrUnexpectedEOF + } + r.offset += n + return n, nil +} + func (r *compactBytesReader) ReadBool() (bool, error) { b, err := r.ReadByte() // Thrift protocol treats both 0 and 2 as false. diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/debug.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/debug.go index e8bf5763bf7..f3aa32533f1 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/debug.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/debug.go @@ -128,6 +128,16 @@ func (d *debugReader) BytesRead() int { return d.r.BytesRead() } +// Discard forwards discards to the wrapped reader. Without it, a +// debug-wrapped bytes-backed reader would fall through to a throwaway +// Reader() view and the discard would not advance the wrapped reader's +// offset, silently desynchronizing the stream. +func (d *debugReader) Discard(n int) (int, error) { + v, err := discard(d.r, n) + d.log("Discard", v, err) + return v, err +} + type debugWriter struct { w Writer l *log.Logger diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/decode.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/decode.go index b1e3189297a..2145b768a15 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/decode.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/decode.go @@ -1,7 +1,6 @@ package thrift import ( - "bufio" "fmt" "io" "maps" @@ -18,8 +17,11 @@ import ( // // As an optimization, the value passed in v may be reused across multiple calls // to Unmarshal, allowing the function to reuse objects referenced by pointer -// fields of struct values. When reusing objects, the application is responsible -// for resetting the state of v before calling Unmarshal again. +// fields of struct values: non-nil pointer fields present in the input have +// their pointed-to value zeroed and decoded in place, and pointer fields +// absent from the input are set to nil. When reusing objects, the application +// remains responsible for resetting non-pointer state of v (scalars, strings, +// and slice lengths) before calling Unmarshal again. func Unmarshal(p Protocol, b []byte, v any) error { pr := p.NewReaderFromBytes(slices.Clone(b)) @@ -108,6 +110,10 @@ func DecodeFuncOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { return f } + if isUnion(t) { + return decodeFuncUnionOf(t, seen) + } + // Check if type implements Value interface first if t.Implements(valueType) { zv := reflect.Zero(t).Interface().(Value) @@ -247,7 +253,7 @@ func decodeFuncSliceOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { if flags.Have(Strict) { return &TypeMismatch{item: "list item", Expect: typ, Found: l.Type} } - return nil + return skipListItems(r, l) } size := int(l.Size) @@ -302,14 +308,14 @@ func decodeFuncMapOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { if flags.Have(Strict) { return &TypeMismatch{item: "map key", Expect: keyType, Found: m.Key} } - return nil + return skipMapItems(r, m) } if elemType != m.Value { if flags.Have(Strict) { return &TypeMismatch{item: "map value", Expect: elemType, Found: m.Value} } - return nil + return skipMapItems(r, m) } tmpKey := reflect.New(key).Elem() @@ -363,7 +369,7 @@ func decodeFuncMapAsSetOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { if flags.Have(Strict) { return &TypeMismatch{item: "list item", Expect: typ, Found: s.Type} } - return nil + return skipSetItems(r, s) } tmp := reflect.New(key).Elem() @@ -383,21 +389,29 @@ func decodeFuncMapAsSetOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { type structDecoder struct { fields []structDecoderField - union []int minID int16 - zero reflect.Value required []uint64 + // clears contains the indices (into fields) of pointer-typed and + // union-typed fields. Such fields absent from the input are zeroed + // after decoding, so that reusing a previously decoded value as the + // decode target produces the same result as decoding into a fresh + // value. Without this, stale pointers (or stale union members) from a + // previous decode would survive, which is invisible for regular + // optional fields but corrupts values where "which member is non-nil" + // carries meaning. + clears []int } func (dec *structDecoder) decode(r Reader, v reflect.Value, flags Flags) error { flags = flags.Only(decodeFlags) coalesceBool := flags.Have(coalesceBoolFields) - lastField := reflect.Value{} - union := len(dec.union) > 0 - seen := make([]uint64, 1) - if len(dec.required) > len(seen) { - seen = make([]uint64, len(dec.required)) + // seen tracks which of the (sparse, id-indexed) fields were observed + // in the input; required is sized to the same word count. + var seenBuf [4]uint64 + seen := seenBuf[:] + if n := len(dec.required); n > len(seenBuf) { + seen = make([]uint64, n) } // Inlined readStruct loop to avoid closure overhead @@ -424,7 +438,19 @@ decodeFields: } i := int(f.ID) - int(dec.minID) - if i < 0 || i >= len(dec.fields) || dec.fields[i].decode == nil { + var field *structDecoderField + if i >= 0 && i < len(dec.fields) && dec.fields[i].decode != nil { + field = &dec.fields[i] + } + // Unknown fields and (in non-strict mode) type-mismatched fields + // are consumed so the stream stays aligned, and left unseen: they + // were not decoded, so they must not satisfy the required check nor + // protect a stale pointer from the clearUnseen pass below. + // TODO: implement type conversions? + if field == nil || (f.Type != field.typ && !(f.Type == TRUE && field.typ == BOOL)) { + if field != nil && flags.Have(Strict) { + return &TypeMismatch{item: "field value", Expect: field.typ, Found: f.Type} + } if err := skip(r, f.Type); err != nil { return with(dontExpectEOF(err), &decodeErrorField{cause: f}) } @@ -432,19 +458,8 @@ decodeFields: numFields++ continue decodeFields } - field := &dec.fields[i] seen[i/64] |= 1 << (i % 64) - // TODO: implement type conversions? - if f.Type != field.typ && !(f.Type == TRUE && field.typ == BOOL) { - if flags.Have(Strict) { - return &TypeMismatch{item: "field value", Expect: field.typ, Found: f.Type} - } - lastFieldID = f.ID - numFields++ - continue decodeFields - } - x := v for _, i := range field.index { if x.Kind() == reflect.Ptr { @@ -457,12 +472,6 @@ decodeFields: } } - if union { - v.Set(dec.zero) - } - - lastField = x - if coalesceBool && (f.Type == TRUE || f.Type == FALSE) { for x.Kind() == reflect.Ptr { if x.IsNil() { @@ -503,8 +512,26 @@ decodeFields: } } - if union && lastField.IsValid() { - v.FieldByIndex(dec.union).Set(lastField.Addr()) +clearUnseen: + for _, i := range dec.clears { + if seen[i/64]&(1<<(i%64)) != 0 { + continue + } + x := v + for _, j := range dec.fields[i].index { + if x.Kind() == reflect.Ptr { + if x.IsNil() { + continue clearUnseen + } + x = x.Elem() + } + x = x.Field(j) + } + // x is either a pointer field or a union struct; zeroing a union + // nils its member interface, marking the union unset. + if x.Kind() != reflect.Ptr || !x.IsNil() { + x.SetZero() + } } return nil @@ -515,29 +542,25 @@ type structDecoderField struct { id int16 flags Flags typ Type + isPtr bool decode DecodeFunc } func decodeFuncStructOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { - dec := &structDecoder{ - zero: reflect.Zero(t), - } + dec := &structDecoder{} decode := dec.decode seen[t] = decode fields := make([]structDecoderField, 0, t.NumField()) forEachStructField(t, nil, func(f structField) { - if f.flags.Have(Union) { - dec.union = f.index - } else { - fields = append(fields, structDecoderField{ - index: f.index, - id: f.id, - flags: f.flags, - typ: TypeOf(f.typ), - decode: decodeFuncStructFieldOf(f, seen), - }) - } + fields = append(fields, structDecoderField{ + index: f.index, + id: f.id, + flags: f.flags, + typ: TypeOf(f.typ), + isPtr: f.typ.Kind() == reflect.Ptr, + decode: decodeFuncStructFieldOf(f, seen), + }) }) minID := int16(0) @@ -554,7 +577,7 @@ func decodeFuncStructOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { dec.fields = make([]structDecoderField, (maxID-minID)+1) dec.minID = minID - dec.required = make([]uint64, len(fields)/64+1) + dec.required = make([]uint64, (len(dec.fields)+63)/64) for _, f := range fields { i := f.id - minID @@ -566,6 +589,9 @@ func decodeFuncStructOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { if f.flags.Have(Required) { dec.required[i/64] |= 1 << (i % 64) } + if f.isPtr || f.flags.Have(UnionType) { + dec.clears = append(dec.clears, int(i)) + } } return decode @@ -587,6 +613,11 @@ func decodeFuncPtrOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { return func(r Reader, v reflect.Value, f Flags) error { if v.IsNil() { v.Set(reflect.New(elem)) + } else { + // Reuse the allocation but not the contents: optional fields + // of the pointed-to value that are absent from the input must + // not survive from a previous decode. + v.Elem().SetZero() } return decode(r, v.Elem(), f) } @@ -654,26 +685,34 @@ func skipBinary(r Reader) error { if n == 0 { return nil } - switch x := r.Reader().(type) { - case *bufio.Reader: - _, err = x.Discard(int(n)) - default: - _, err = io.CopyN(io.Discard, x, int64(n)) - } + _, err = discard(r, int(n)) return dontExpectEOF(err) } +type discarder interface{ Discard(int) (int, error) } + +// discard advances r past n bytes. The bytes-backed readers implement +// Discard themselves; their Reader() method returns a throwaway view that +// does not advance the read offset, so discarding through it would silently +// desynchronize the stream. Streaming readers discard through the +// underlying io.Reader when it supports it (*bufio.Reader does). +func discard(r Reader, n int) (int, error) { + if d, ok := r.(discarder); ok { + return d.Discard(n) + } + if d, ok := r.Reader().(discarder); ok { + return d.Discard(n) + } + c, err := io.CopyN(io.Discard, r.Reader(), int64(n)) + return int(c), err +} + func skipList(r Reader) error { l, err := r.ReadList() if err != nil { return err } - for i := range int(l.Size) { - if err := skip(r, l.Type); err != nil { - return with(dontExpectEOF(err), &decodeErrorList{cause: l, index: i}) - } - } - return nil + return skipListItems(r, l) } func skipSet(r Reader) error { @@ -681,12 +720,7 @@ func skipSet(r Reader) error { if err != nil { return err } - for i := range int(s.Size) { - if err := skip(r, s.Type); err != nil { - return with(dontExpectEOF(err), &decodeErrorSet{cause: s, index: i}) - } - } - return nil + return skipSetItems(r, s) } func skipMap(r Reader) error { @@ -694,11 +728,52 @@ func skipMap(r Reader) error { if err != nil { return err } + return skipMapItems(r, m) +} + +// skipItem consumes one container element of the given type. Unlike bool +// fields, whose value compact-protocol encoders coalesce into the field +// type, bool container elements always occupy one byte. +func skipItem(r Reader, t Type) error { + switch t { + case TRUE, FALSE: + _, err := r.ReadBool() + return err + default: + return skip(r, t) + } +} + +// skipListItems, skipSetItems, and skipMapItems consume the elements of a +// container whose header has already been read. They are used both by the +// skip functions above and by the decoders when the elements cannot be +// decoded into the target type: the payload must still be consumed, or the +// reader would desynchronize from the stream. + +func skipListItems(r Reader, l List) error { + for i := range int(l.Size) { + if err := skipItem(r, l.Type); err != nil { + return with(dontExpectEOF(err), &decodeErrorList{cause: l, index: i}) + } + } + return nil +} + +func skipSetItems(r Reader, s Set) error { + for i := range int(s.Size) { + if err := skipItem(r, s.Type); err != nil { + return with(dontExpectEOF(err), &decodeErrorSet{cause: s, index: i}) + } + } + return nil +} + +func skipMapItems(r Reader, m Map) error { for i := range int(m.Size) { - if err := skip(r, m.Key); err != nil { + if err := skipItem(r, m.Key); err != nil { return with(dontExpectEOF(err), &decodeErrorMap{cause: m, index: i}) } - if err := skip(r, m.Value); err != nil { + if err := skipItem(r, m.Value); err != nil { return with(dontExpectEOF(err), &decodeErrorMap{cause: m, index: i}) } } diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/encode.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/encode.go index f9899312b37..b8f4391dc46 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/encode.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/encode.go @@ -79,6 +79,10 @@ func EncodeFuncOf(t reflect.Type, seen EncodeFuncCache) EncodeFunc { return f } + if isUnion(t) { + return encodeFuncUnionOf(t, seen) + } + // Check if type implements Value interface first if t.Implements(valueType) { zv := reflect.Zero(t).Interface().(Value) @@ -258,7 +262,6 @@ func encodeFuncMapAsSetOf(t reflect.Type, seen EncodeFuncCache) EncodeFunc { type structEncoder struct { fields []structEncoderField - union bool } func dereference(v reflect.Value) reflect.Value { @@ -347,20 +350,9 @@ encodeFields: return err } - if numFields > 1 && enc.union { - return fmt.Errorf("thrift union had more than one field with a non-zero value (%d)", numFields) - } - return nil } -func (enc *structEncoder) String() string { - if enc.union { - return "union" - } - return "struct" -} - type structEncoderField struct { index []int id int16 @@ -378,18 +370,14 @@ func encodeFuncStructOf(t reflect.Type, seen EncodeFuncCache) EncodeFunc { seen[t] = encode forEachStructField(t, nil, func(f structField) { - if f.flags.Have(Union) { - enc.union = true - } else { - enc.fields = append(enc.fields, structEncoderField{ - index: f.index, - id: f.id, - flags: f.flags, - typ: TypeOf(f.typ), - encode: encodeFuncStructFieldOf(f, seen), - null: nullFuncOf(f), - }) - } + enc.fields = append(enc.fields, structEncoderField{ + index: f.index, + id: f.id, + flags: f.flags, + typ: TypeOf(f.typ), + encode: encodeFuncStructFieldOf(f, seen), + null: nullFuncOf(f), + }) }) slices.SortStableFunc(enc.fields, func(a, b structEncoderField) int { @@ -423,6 +411,10 @@ func nullFuncOf(f structField) NullFunc { if f.flags.Have(Required) { return neverNull } + // Union structs are unset when their member field is nil. + if f.flags.Have(UnionType) { + return unionLayoutOf(f.typ).nullFunc() + } // Value types: use their NullFunc if f.flags.Have(ValueType) { zv := reflect.Zero(f.typ).Interface().(Value) diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/list.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/list.go index 0fb66c02383..1d743d5a3cd 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/list.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/list.go @@ -69,7 +69,7 @@ func (l Slice[T]) DecodeFunc(cache DecodeFuncCache) DecodeFunc { if flags.Have(Strict) { return &TypeMismatch{item: "list item", Expect: elemType, Found: listHeader.Type} } - return nil + return skipListItems(r, listHeader) } size := int(listHeader.Size) diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/protocol.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/protocol.go index 1640398a833..99242e74842 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/protocol.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/protocol.go @@ -25,7 +25,10 @@ const ( // However, the readers and writer that they instantiates are intended to be // used by a single goroutine. type Protocol interface { - NewReaderFromBytes(b []byte) Reader + // NewReaderFromBytes returns a reader over b. Every reader constructed from + // a byte slice can be repointed at another one, so the concrete BytesReader + // is returned rather than the wider Reader. + NewReaderFromBytes(b []byte) BytesReader NewReader(r io.Reader) Reader NewWriter(w io.Writer) Writer Features() Features @@ -53,6 +56,21 @@ type Reader interface { BytesRead() int } +// BytesReader is a Reader positioned over a fixed byte slice. +// +// ResetBytes repoints the reader at b and rewinds it, so a caller decoding many +// values from a byte buffer can reuse one reader instead of allocating one per +// value. +// +// Values decoded through a BytesReader may alias b: ReadBytes and ReadString +// return sub-slices of it rather than copies. Callers must keep b alive and +// unmodified for as long as the decoded values are used. This is why Unmarshal, +// which makes no such demand of its caller, clones its input. +type BytesReader interface { + Reader + ResetBytes(b []byte) +} + // Writer represents a low-level writer of values encoded according to one of // the thrift protocols. type Writer interface { diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/struct.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/struct.go index 81f0fb2e69e..6b5ec7763d8 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/struct.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/struct.go @@ -13,7 +13,7 @@ type Flags int16 // Flag constants for struct field handling. const ( Enum Flags = 1 << 0 - Union Flags = 1 << 1 + UnionType Flags = 1 << 1 // indicates field implements Union interface Required Flags = 1 << 2 Optional Flags = 1 << 3 Strict Flags = 1 << 4 @@ -91,8 +91,6 @@ func forEachStructField(t reflect.Type, index []int, do func(structField)) { switch opt { case "enum": flags = flags.With(Enum) - case "union": - flags = flags.With(Union) case "required": flags = flags.With(Required) case "optional": @@ -108,21 +106,7 @@ func forEachStructField(t reflect.Type, index []int, do func(structField)) { panic(fmt.Errorf("thrift struct field cannot be both optional and required in `thrift:\"%s\"`", tag)) } - if flags.Have(Union) { - if f.Type.Kind() != reflect.Interface { - panic(fmt.Errorf("thrift union tag found on a field which is not an interface type `thrift:\"%s\"`", tag)) - } - - if tags[0] != "" { - panic(fmt.Errorf("invalid thrift field id on union field `thrift:\"%s\"`", tag)) - } - - do(structField{ - typ: f.Type, - index: fieldIndex, - flags: flags, - }) - } else { + { if flags.Have(Enum) { switch f.Type.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: @@ -132,8 +116,10 @@ func forEachStructField(t reflect.Type, index []int, do func(structField)) { } } - // Detect types implementing Value interface - if f.Type.Implements(valueType) { + // Detect union structs, then types implementing Value interface. + if isUnion(f.Type) { + flags = flags.With(UnionType) + } else if f.Type.Implements(valueType) { flags = flags.With(ValueType) } diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/thrift.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/thrift.go index 861329efdc6..142d0e79aea 100644 --- a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/thrift.go +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/thrift.go @@ -130,6 +130,10 @@ func (m Map) String() string { } func TypeOf(t reflect.Type) Type { + if isUnion(t) { + return STRUCT + } + // Check if type implements Value interface first if t.Implements(valueType) { zv := reflect.Zero(t).Interface().(Value) diff --git a/vendor/github.com/parquet-go/parquet-go/encoding/thrift/union.go b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/union.go new file mode 100644 index 00000000000..14e29cded6c --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/encoding/thrift/union.go @@ -0,0 +1,322 @@ +package thrift + +import ( + "fmt" + "reflect" +) + +// UnionMember is implemented by the concrete member types of a thrift union. +// +// FieldID returns the thrift field id that the member is encoded under. The id +// is intrinsic to the member type, which makes it impossible for a union to +// register the same member under two different ids. +// +// Implementations must declare FieldID on a pointer receiver and must not +// dereference it: unions register their members as typed nil pointers, and the +// codec calls FieldID on those values to build its dispatch table. +type UnionMember interface { + FieldID() int16 +} + +// Union is implemented by structs that encode as a thrift union. +// +// A union struct has exactly one field, of an interface type, holding at most +// one member. A nil field means the union is not set, and the struct is skipped +// when it appears as an optional field of another struct. +// +// UnionMembers returns the members the union may hold, as typed nil pointers: +// +// var logicalTypeMembers = []thrift.UnionMember{ +// (*StringType)(nil), +// (*MapType)(nil), +// } +// +// func (*LogicalType) UnionMembers() []thrift.UnionMember { return logicalTypeMembers } +// +// The returned slice is read once, when the codec for the union is built, so +// implementations should return a package-level value rather than construct it +// on each call. +type Union interface { + UnionMembers() []UnionMember +} + +var unionType = reflect.TypeFor[Union]() + +// isUnion reports whether t is a union struct. +// +// Unlike Value, which is probed on the value type because its implementations +// (Null, Slice) are value wrappers with value receivers, Union is probed on the +// pointer type. Union structs live in packages that declare their methods on +// pointer receivers, and a union only ever appears as an addressable struct +// field, so requiring the value method set would buy nothing and would force +// those packages into a mixed receiver set. +func isUnion(t reflect.Type) bool { + return t.Kind() == reflect.Struct && reflect.PointerTo(t).Implements(unionType) +} + +// unionMember describes one member of a union after validation. +type unionMember struct { + id int16 + // typ is the member struct type, i.e. the element of the registered *T. + typ reflect.Type + // interned holds a shared *T for zero-sized members, which carry no state + // and so can be handed out from every decode without allocating. + interned reflect.Value +} + +// unionLayout is the validated shape of a union struct, independent of whether +// it is being encoded or decoded. +type unionLayout struct { + typ reflect.Type + // field is the index of the interface field holding the member. + field int + members []unionMember + minID int16 + maxID int16 +} + +// unionLayoutOf validates t and describes its shape, panicking on any structural +// problem. Union codecs are built once per type, at the first encode or decode, +// so these panics surface at startup rather than on a hot path. +func unionLayoutOf(t reflect.Type) *unionLayout { + if t.Kind() != reflect.Struct { + panic(fmt.Errorf("thrift union %s is not a struct", t)) + } + if t.NumField() != 1 { + panic(fmt.Errorf("thrift union %s must have exactly one field, found %d", t, t.NumField())) + } + field := t.Field(0) + if field.Type.Kind() != reflect.Interface { + panic(fmt.Errorf("thrift union %s field %s must be an interface, found %s", t, field.Name, field.Type)) + } + + members := reflect.New(t).Interface().(Union).UnionMembers() + if len(members) == 0 { + panic(fmt.Errorf("thrift union %s declares no members", t)) + } + + layout := &unionLayout{typ: t, field: 0} + seen := make(map[int16]reflect.Type, len(members)) + + for _, m := range members { + if m == nil { + panic(fmt.Errorf("thrift union %s declares a nil member", t)) + } + mt := reflect.TypeOf(m) + if mt.Kind() != reflect.Ptr || mt.Elem().Kind() != reflect.Struct { + panic(fmt.Errorf("thrift union %s member %s must be a pointer to a struct", t, mt)) + } + if !mt.AssignableTo(field.Type) { + panic(fmt.Errorf("thrift union %s member %s is not assignable to %s", t, mt, field.Type)) + } + id := m.FieldID() + if id <= 0 { + panic(fmt.Errorf("thrift union %s member %s has an invalid field id %d", t, mt, id)) + } + if prev, ok := seen[id]; ok { + panic(fmt.Errorf("thrift union %s field id %d is present multiple times with types %s and %s", t, id, prev, mt)) + } + seen[id] = mt + + member := unionMember{id: id, typ: mt.Elem()} + if member.typ.Size() == 0 { + member.interned = reflect.New(member.typ) + } + layout.members = append(layout.members, member) + + if layout.minID == 0 || id < layout.minID { + layout.minID = id + } + if id > layout.maxID { + layout.maxID = id + } + } + + return layout +} + +// nullFunc reports the union as unset when its member field is nil. +func (layout *unionLayout) nullFunc() NullFunc { + field := layout.field + return func(v reflect.Value) bool { return v.Field(field).IsNil() } +} + +type unionEncoderMember struct { + id int16 + encode EncodeFunc +} + +type unionEncoder struct { + typ reflect.Type + field int + byType map[reflect.Type]unionEncoderMember +} + +func (enc *unionEncoder) encode(w Writer, v reflect.Value, flags Flags) error { + x := v.Field(enc.field) + + if !x.IsNil() { + p := x.Elem() + + m, ok := enc.byType[p.Type()] + if !ok { + return fmt.Errorf("thrift: %s is not a member of union %s", p.Type(), enc.typ) + } + + field := Field{ID: m.id, Type: STRUCT} + // A union writes a single field, so the previous field id is always + // zero and the delta is the id itself. This mirrors structEncoder so + // that unions and structs produce identical bytes for the same field. + if flags.Have(useDeltaEncoding) && field.ID <= 15 { + field.Delta = true + } + if err := w.WriteField(field); err != nil { + return err + } + + // A typed nil member encodes as an empty struct, matching the way + // encodeFuncPtrOf substitutes the zero value for a nil pointer. + if p.IsNil() { + p = reflect.New(p.Type().Elem()) + } + if err := m.encode(w, p.Elem(), flags); err != nil { + return err + } + } + + return w.WriteField(Field{Type: STOP}) +} + +func encodeFuncUnionOf(t reflect.Type, seen EncodeFuncCache) EncodeFunc { + layout := unionLayoutOf(t) + + enc := &unionEncoder{ + typ: t, + field: layout.field, + byType: make(map[reflect.Type]unionEncoderMember, len(layout.members)), + } + encode := enc.encode + seen[t] = encode + + for _, m := range layout.members { + enc.byType[reflect.PointerTo(m.typ)] = unionEncoderMember{ + id: m.id, + encode: EncodeFuncOf(m.typ, seen), + } + } + + return encode +} + +type unionDecoderMember struct { + // interned is a shared *T for zero-sized members, invalid otherwise. + interned reflect.Value + typ reflect.Type + // ptrTyp is *typ, kept to test whether a previously decoded member can + // be reused as the decode target without allocating. + ptrTyp reflect.Type + decode DecodeFunc +} + +type unionDecoder struct { + field int + minID int16 + members []unionDecoderMember +} + +func (dec *unionDecoder) decode(r Reader, v reflect.Value, flags Flags) error { + flags = flags.Only(decodeFlags) + + // Reset so that decoding into a reused value cannot retain a stale + // member, but remember the previous member: when the input holds a + // member of the same type, its allocation is reused instead of + // allocating a fresh value. + x := v.Field(dec.field) + prev := x.Elem() // invalid when the union was unset + x.SetZero() + + lastFieldID := int16(0) + numFields := 0 + + for { + f, err := r.ReadField() + if err != nil { + if numFields > 0 { + err = dontExpectEOF(err) + } + return err + } + + if f.Type == STOP { + return nil + } + + if f.Delta { + f.ID += lastFieldID + f.Delta = false + } + + i := int(f.ID) - int(dec.minID) + known := i >= 0 && i < len(dec.members) && dec.members[i].decode != nil + + switch { + case !known: + // An id we do not know: a member added by a newer writer. Skip it + // and leave the union unset rather than failing the whole decode. + if err := skip(r, f.Type); err != nil { + return with(dontExpectEOF(err), &decodeErrorField{cause: f}) + } + + case f.Type != STRUCT: + if flags.Have(Strict) { + return &TypeMismatch{item: "union member", Expect: STRUCT, Found: f.Type} + } + if err := skip(r, f.Type); err != nil { + return with(dontExpectEOF(err), &decodeErrorField{cause: f}) + } + + default: + m := &dec.members[i] + + p := m.interned + if !p.IsValid() { + if prev.IsValid() && prev.Type() == m.ptrTyp && !prev.IsNil() { + p = prev + p.Elem().SetZero() + } else { + p = reflect.New(m.typ) + } + } + if err := m.decode(r, p.Elem(), flags); err != nil { + return with(dontExpectEOF(err), &decodeErrorField{cause: f}) + } + x.Set(p) + } + + lastFieldID = f.ID + numFields++ + } +} + +func decodeFuncUnionOf(t reflect.Type, seen DecodeFuncCache) DecodeFunc { + layout := unionLayoutOf(t) + + dec := &unionDecoder{ + field: layout.field, + minID: layout.minID, + members: make([]unionDecoderMember, (layout.maxID-layout.minID)+1), + } + decode := dec.decode + seen[t] = decode + + for _, m := range layout.members { + dec.members[m.id-layout.minID] = unionDecoderMember{ + interned: m.interned, + typ: m.typ, + ptrTyp: reflect.PointerTo(m.typ), + decode: DecodeFuncOf(m.typ, seen), + } + } + + return decode +} diff --git a/vendor/github.com/parquet-go/parquet-go/errors.go b/vendor/github.com/parquet-go/parquet-go/errors.go index 651fe740c88..1d00774673a 100644 --- a/vendor/github.com/parquet-go/parquet-go/errors.go +++ b/vendor/github.com/parquet-go/parquet-go/errors.go @@ -9,7 +9,7 @@ var ( // ErrCorrupted is an error returned by the Err method of ColumnPages // instances when they encountered a mismatch between the CRC checksum // recorded in a page header and the one computed while reading the page - // data. + // data. Also returned on invalid headers / footer decoding. ErrCorrupted = errors.New("corrupted parquet page") // ErrMissingRootColumn is an error returned when opening an invalid parquet diff --git a/vendor/github.com/parquet-go/parquet-go/file.go b/vendor/github.com/parquet-go/parquet-go/file.go index 11c697b0464..d9fab37ff9c 100644 --- a/vendor/github.com/parquet-go/parquet-go/file.go +++ b/vendor/github.com/parquet-go/parquet-go/file.go @@ -142,13 +142,13 @@ func OpenFile(r io.ReaderAt, size int64, options ...FileOption) (*File, error) { // Extract AAD parameters from the encryption algorithm. var fileUnique, aadPrefix []byte - switch { - case cryptoMeta.EncryptionAlgorithm.AesGcmV1 != nil: - fileUnique = cryptoMeta.EncryptionAlgorithm.AesGcmV1.AadFileUnique - aadPrefix = cryptoMeta.EncryptionAlgorithm.AesGcmV1.AadPrefix - case cryptoMeta.EncryptionAlgorithm.AesGcmCtrV1 != nil: - fileUnique = cryptoMeta.EncryptionAlgorithm.AesGcmCtrV1.AadFileUnique - aadPrefix = cryptoMeta.EncryptionAlgorithm.AesGcmCtrV1.AadPrefix + switch algo := cryptoMeta.EncryptionAlgorithm.Value.(type) { + case *format.AesGcmV1: + fileUnique = algo.AadFileUnique + aadPrefix = algo.AadPrefix + case *format.AesGcmCtrV1: + fileUnique = algo.AadFileUnique + aadPrefix = algo.AadPrefix } footerKey, err := c.Decryption.Keys.FooterKey(cryptoMeta.KeyMetadata) @@ -184,15 +184,14 @@ func OpenFile(r io.ReaderAt, size int64, options ...FileOption) (*File, error) { if c.Decryption == nil { return nil, fmt.Errorf("parquet file has a signed footer but no DecryptionConfig was provided") } - algo := &f.metadata.EncryptionAlgorithm var fileUnique, aadPrefix []byte - switch { - case algo.AesGcmV1 != nil: - fileUnique = algo.AesGcmV1.AadFileUnique - aadPrefix = algo.AesGcmV1.AadPrefix - case algo.AesGcmCtrV1 != nil: - fileUnique = algo.AesGcmCtrV1.AadFileUnique - aadPrefix = algo.AesGcmCtrV1.AadPrefix + switch algo := f.metadata.EncryptionAlgorithm.Value.(type) { + case *format.AesGcmV1: + fileUnique = algo.AadFileUnique + aadPrefix = algo.AadPrefix + case *format.AesGcmCtrV1: + fileUnique = algo.AadFileUnique + aadPrefix = algo.AadPrefix } plainFooterBytes := footerData[:pr.BytesRead()] sig := footerData[pr.BytesRead():] @@ -382,7 +381,36 @@ func (f *File) ReadPageIndex() ([]format.ColumnIndex, []format.OffsetIndex, erro columnIndexes := make([]format.ColumnIndex, numColumnChunks) offsetIndexes := make([]format.OffsetIndex, numColumnChunks) - indexBuffer := make([]byte, max(int(columnIndexLength), int(offsetIndexLength))) + + // The column index and the offset index get separate buffers because the + // values decoded below alias them: ColumnIndex.MinValues and MaxValues are + // sub-slices of the bytes they were decoded from. A single shared buffer + // would be overwritten by the offset index read, corrupting the min/max + // statistics of every column. + var columnIndexBuffer, offsetIndexBuffer []byte + if columnIndexOffset > 0 { + columnIndexBuffer = make([]byte, columnIndexLength) + } + if offsetIndexOffset > 0 { + offsetIndexBuffer = make([]byte, offsetIndexLength) + } + + // One reader and one decoder are reused across every column chunk. Decoding + // each chunk with thrift.Unmarshal instead would clone the chunk's bytes and + // allocate a reader for it, twice per column chunk. + reader := f.protocol.NewReaderFromBytes(nil) + decoder := thrift.NewDecoder(reader) + + decode := func(b []byte, v any) error { + reader.ResetBytes(b) + if err := decoder.Decode(v); err != nil { + return err + } + if n := len(b) - reader.BytesRead(); n != 0 { + return fmt.Errorf("unexpected trailing bytes at the end of thrift input: %d", n) + } + return nil + } // pageIndexKey returns the AES key used to decrypt this column's // page-index modules, or nil for plaintext columns. We resolve keys here @@ -392,19 +420,18 @@ func (f *File) ReadPageIndex() ([]format.ColumnIndex, []format.OffsetIndex, erro if f.decryption == nil { return nil, nil } - switch { - case c.CryptoMetadata.EncryptionWithFooterKey != nil: + switch crypto := c.CryptoMetadata.Value.(type) { + case *format.EncryptionWithFooterKey: return f.decryption.Keys.FooterKey(nil) - case c.CryptoMetadata.EncryptionWithColumnKey != nil: - colKey := c.CryptoMetadata.EncryptionWithColumnKey - return f.decryption.Keys.ColumnKey(colKey.PathInSchema, colKey.KeyMetadata) + case *format.EncryptionWithColumnKey: + return f.decryption.Keys.ColumnKey(crypto.PathInSchema, crypto.KeyMetadata) default: return nil, nil } } if columnIndexOffset > 0 { - columnIndexData := indexBuffer[:columnIndexLength] + columnIndexData := columnIndexBuffer if cast, ok := f.reader.(interface{ SetColumnIndexSection(offset, length int64) }); ok { cast.SetColumnIndexSection(columnIndexOffset, columnIndexLength) @@ -437,7 +464,7 @@ func (f *File) ReadPageIndex() ([]format.ColumnIndex, []format.OffsetIndex, erro } buffer = plain } - if err := thrift.Unmarshal(&f.protocol, buffer, &columnIndexes[(i*numColumns)+j]); err != nil { + if err := decode(buffer, &columnIndexes[(i*numColumns)+j]); err != nil { return fmt.Errorf("decoding column index: rowGroup=%d columnChunk=%d/%d: %w", i, j, numColumns, err) } } @@ -449,7 +476,7 @@ func (f *File) ReadPageIndex() ([]format.ColumnIndex, []format.OffsetIndex, erro } if offsetIndexOffset > 0 { - offsetIndexData := indexBuffer[:offsetIndexLength] + offsetIndexData := offsetIndexBuffer if cast, ok := f.reader.(interface{ SetOffsetIndexSection(offset, length int64) }); ok { cast.SetOffsetIndexSection(offsetIndexOffset, offsetIndexLength) @@ -478,7 +505,7 @@ func (f *File) ReadPageIndex() ([]format.ColumnIndex, []format.OffsetIndex, erro } buffer = plain } - if err := thrift.Unmarshal(&f.protocol, buffer, &offsetIndexes[(i*numColumns)+j]); err != nil { + if err := decode(buffer, &offsetIndexes[(i*numColumns)+j]); err != nil { return fmt.Errorf("decoding offset index: rowGroup=%d columnChunk=%d/%d: %w", i, j, numColumns, err) } } @@ -513,17 +540,16 @@ func (f *File) decryptAllColumnMetadata() error { continue } var key []byte - switch { - case chunk.CryptoMetadata.EncryptionWithFooterKey != nil: + switch crypto := chunk.CryptoMetadata.Value.(type) { + case *format.EncryptionWithFooterKey: var err error key, err = f.decryption.Keys.FooterKey(nil) if err != nil { return fmt.Errorf("resolving footer key for column metadata: %w", err) } - case chunk.CryptoMetadata.EncryptionWithColumnKey != nil: - colKey := chunk.CryptoMetadata.EncryptionWithColumnKey + case *format.EncryptionWithColumnKey: var err error - key, err = f.decryption.Keys.ColumnKey(colKey.PathInSchema, colKey.KeyMetadata) + key, err = f.decryption.Keys.ColumnKey(crypto.PathInSchema, crypto.KeyMetadata) if err != nil { // Only treat an explicit ErrKeyNotFound as non-fatal: the // caller intentionally omitted this column's key. Any other @@ -664,16 +690,15 @@ func (g *FileRowGroup) init(file *File, columns []*Column, rowGroup *format.RowG } if file.decryption != nil { chunk := &rowGroup.Columns[i] - switch { - case chunk.CryptoMetadata.EncryptionWithFooterKey != nil: + switch crypto := chunk.CryptoMetadata.Value.(type) { + case *format.EncryptionWithFooterKey: key, err := file.decryption.Keys.FooterKey(nil) if err != nil { return fmt.Errorf("resolving footer key for column %q: %w", columnPathString(columns[i].Path()), err) } fileColumnChunks[i].decryptionKey = key - case chunk.CryptoMetadata.EncryptionWithColumnKey != nil: - colKey := chunk.CryptoMetadata.EncryptionWithColumnKey - key, err := file.decryption.Keys.ColumnKey(colKey.PathInSchema, colKey.KeyMetadata) + case *format.EncryptionWithColumnKey: + key, err := file.decryption.Keys.ColumnKey(crypto.PathInSchema, crypto.KeyMetadata) switch { case err == nil: fileColumnChunks[i].decryptionKey = key @@ -685,7 +710,7 @@ func (g *FileRowGroup) init(file *File, columns []*Column, rowGroup *format.RowG // Real error (KMS failure, bad metadata, …) must surface so // the caller learns the cause instead of seeing later // "decode page header" errors masking the missing key. - return fmt.Errorf("resolving column key for %q: %w", columnPathString(colKey.PathInSchema), err) + return fmt.Errorf("resolving column key for %q: %w", columnPathString(crypto.PathInSchema), err) } } } @@ -739,6 +764,11 @@ func (g *FileRowGroup) Rows() Rows { return NewRowGroupRowReader(rowGroup) } +// chunkTransparentRowGroup marks FileRowGroup as safe for the chunk-level write +// fast paths: its Rows() reads the file column chunks in order with no +// additional semantics. +func (g *FileRowGroup) chunkTransparentRowGroup() {} + type fileSortingColumn struct { column *Column descending bool @@ -1030,9 +1060,10 @@ func (c *FileColumnChunk) readBloomFilter(reader io.ReaderAt) (*FileBloomFilter, if err := decoder.Decode(&header); err != nil { return nil, fmt.Errorf("decoding bloom filter header: %w", err) } - offset, _ = section.Seek(0, io.SeekCurrent) + sectionPos, _ := section.Seek(0, io.SeekCurrent) + dataOffset := offset + sectionPos - int64(rbuf.Buffered()) var err error - filter, err = newBloomFilter(reader, offset, &header) + filter, err = newBloomFilter(reader, dataOffset, &header) if err != nil { return nil, fmt.Errorf("reading bloom filter: %w", err) } @@ -1193,6 +1224,9 @@ func (f *FilePages) ReadPage() (Page, error) { if err = f.decoder.Decode(header); err != nil { return nil, err } + if err = validatePageHeader(header); err != nil { + return nil, err + } // if this is a dictionary page and we've already read and decoded the dictionary we can skip past it. // call f.rbuf.Discard to skip the page data and realign f.rbuf with the next page header @@ -1305,6 +1339,9 @@ func (f *FilePages) readDictionary() error { if err := thrift.NewDecoder(pr).Decode(header); err != nil { return fmt.Errorf("parquet decryption: decoding dict page header: %w", err) } + if err := validatePageHeader(header); err != nil { + return err + } bodyAAD := makeAAD(d.aadPrefix, d.fileUnique, dictPageBodyModule, d.rowGroupOrdinal, d.columnOrdinal, 0) bodyPlain, err := readDecryptedEnvelopeFrom(rbuf, d.key, bodyAAD) if err != nil { @@ -1318,6 +1355,9 @@ func (f *FilePages) readDictionary() error { if err := decoder.Decode(header); err != nil { return err } + if err := validatePageHeader(header); err != nil { + return err + } page = buffers.get(int(header.CompressedPageSize)) page.ref() if _, err := io.ReadFull(rbuf, page.data.Slice()); err != nil { @@ -1368,6 +1408,42 @@ func (f *FilePages) readDataPageV2(header *format.PageHeader, page *buffer[byte] return f.chunk.column.decodeDataPageV2(DataPageHeaderV2{&header.DataPageHeaderV2.V}, page, f.dictionary, header.UncompressedPageSize) } +// validatePageHeader rejects page headers whose size or count fields decoded to +// negative values. Those values end up being trusted by the code later on +// which results in panics if they're off +func validatePageHeader(header *format.PageHeader) error { + reject := func(field string, value int32) error { + return fmt.Errorf("invalid page header: %s=%d: %w", field, value, ErrCorrupted) + } + if header.CompressedPageSize < 0 { + return reject("compressed_page_size", header.CompressedPageSize) + } + if header.UncompressedPageSize < 0 { + return reject("uncompressed_page_size", header.UncompressedPageSize) + } + if h := header.DataPageHeader; h.Valid && h.V.NumValues < 0 { + return reject("data_page_header.num_values", h.V.NumValues) + } + if h := header.DictionaryPageHeader; h.Valid && h.V.NumValues < 0 { + return reject("dictionary_page_header.num_values", h.V.NumValues) + } + if h := header.DataPageHeaderV2; h.Valid { + switch { + case h.V.NumValues < 0: + return reject("data_page_header_v2.num_values", h.V.NumValues) + case h.V.NumNulls < 0: + return reject("data_page_header_v2.num_nulls", h.V.NumNulls) + case h.V.NumRows < 0: + return reject("data_page_header_v2.num_rows", h.V.NumRows) + case h.V.RepetitionLevelsByteLength < 0: + return reject("data_page_header_v2.repetition_levels_byte_length", h.V.RepetitionLevelsByteLength) + case h.V.DefinitionLevelsByteLength < 0: + return reject("data_page_header_v2.definition_levels_byte_length", h.V.DefinitionLevelsByteLength) + } + } + return nil +} + func (f *FilePages) readPage(header *format.PageHeader, reader *bufio.Reader) (*buffer[byte], error) { page := buffers.get(int(header.CompressedPageSize)) defer page.unref() @@ -1448,6 +1524,9 @@ func (f *FilePages) readEncryptedPage() (*format.PageHeader, *buffer[byte], erro if err := thrift.NewDecoder(pr).Decode(header); err != nil { return nil, nil, fmt.Errorf("parquet decryption: decoding page header: %w", err) } + if err := validatePageHeader(header); err != nil { + return nil, nil, err + } bodyAAD := makeAAD(d.aadPrefix, d.fileUnique, bodyModuleType, d.rowGroupOrdinal, d.columnOrdinal, pageOrd) bodyPlain, err := readDecryptedEnvelopeFrom(f.rbuf, d.key, bodyAAD) diff --git a/vendor/github.com/parquet-go/parquet-go/format/footer.go b/vendor/github.com/parquet-go/parquet-go/format/footer.go new file mode 100644 index 00000000000..df439cefe89 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/format/footer.go @@ -0,0 +1,63 @@ +package format + +import ( + "fmt" + + "github.com/parquet-go/parquet-go/encoding/thrift" +) + +// FooterDecoder decodes Parquet file footers (thrift compact protocol) with +// zero steady-state allocations by retaining its input buffer and decoded +// metadata across calls to Decode. +// +// The zero value is ready to use. FooterDecoder values must not be copied +// after first use and are not safe for concurrent use; to amortize +// allocations across goroutines, keep decoders in a sync.Pool. +// +// A decoder never allocates for inputs whose shape fits the capacity +// retained from previous decodes; larger or differently-shaped inputs grow +// the retained state as needed. The retained state never shrinks: one +// unusually large footer sizes the decoder's buffer and metadata tree for +// its remaining lifetime, so long-lived decoders dedicated to a single file +// may prefer to be discarded after use instead of pooled. +type FooterDecoder struct { + buf []byte + meta FileMetaData + reader thrift.BytesReader + decoder *thrift.Decoder +} + +// protocol is stateless and shared by all decoders. +var footerProtocol thrift.CompactProtocol + +// Decode parses the thrift-encoded footer in data and returns the decoded +// metadata along with the number of bytes consumed. Trailing bytes after the +// thrift payload (such as the 28-byte AES-GCM footer signature written by +// encrypted-footer-signing writers) are not an error; callers can detect +// them by comparing the consumed byte count to len(data). +// +// The returned metadata, and all strings and byte slices it references, are +// owned by the decoder and remain valid only until the next call to Decode. +// Callers that need the metadata to outlive the decoder must deep-copy it. +// +// Decode makes a private copy of data; the caller retains ownership of the +// slice and may reuse it immediately. +func (d *FooterDecoder) Decode(data []byte) (*FileMetaData, int, error) { + // The decoded metadata aliases the retained buffer, so the copy below + // would corrupt previously returned values in place. Resetting first + // keeps the "valid until next Decode" contract honest instead of + // leaving values that are subtly wrong. + d.meta.Reset() + d.buf = append(d.buf[:0], data...) + + if d.reader == nil { + d.reader = footerProtocol.NewReaderFromBytes(nil) + d.decoder = thrift.NewDecoder(d.reader) + } + d.reader.ResetBytes(d.buf) + + if err := d.decoder.Decode(&d.meta); err != nil { + return nil, 0, fmt.Errorf("decoding parquet footer: %w", err) + } + return &d.meta, d.reader.BytesRead(), nil +} diff --git a/vendor/github.com/parquet-go/parquet-go/format/parquet.go b/vendor/github.com/parquet-go/parquet-go/format/parquet.go index 26a5de5d2cb..d27f3aa1a50 100644 --- a/vendor/github.com/parquet-go/parquet-go/format/parquet.go +++ b/vendor/github.com/parquet-go/parquet-go/format/parquet.go @@ -3,6 +3,7 @@ package format import ( "fmt" "strings" + "time" "github.com/parquet-go/parquet-go/deprecated" "github.com/parquet-go/parquet-go/encoding/thrift" @@ -103,13 +104,13 @@ type SizeStatistics struct { // // This field may be omitted if max_repetition_level is 0 without loss // of information. - RepetitionLevelHistogram []int64 `thrift:"2,optional"` + RepetitionLevelHistogram thrift.Slice[int64] `thrift:"2,optional"` // Same as repetition_level_histogram except for definition levels. // // This field may be omitted if max_definition_level is 0 or 1 without // loss of information. - DefinitionLevelHistogram []int64 `thrift:"3,optional"` + DefinitionLevelHistogram thrift.Slice[int64] `thrift:"3,optional"` } // Bounding box for GEOMETRY or GEOGRAPHY type in the representation of min/max @@ -130,7 +131,7 @@ type GeospatialStatistics struct { // A bounding box of geospatial instances BBox BoundingBox `thrift:"1,optional"` // Geospatial type codes of all instances, or an empty list if not known - GeoSpatialTypes []int32 `thrift:"2,optional"` + GeoSpatialTypes thrift.Slice[int32] `thrift:"2,optional"` } // Statistics per row group and per page. @@ -181,6 +182,14 @@ func (*EnumType) String() string { return "ENUM" } func (*DateType) String() string { return "DATE" } func (*Float16Type) String() string { return "FLOAT16" } +func (*StringType) FieldID() int16 { return 1 } +func (*MapType) FieldID() int16 { return 2 } +func (*ListType) FieldID() int16 { return 3 } +func (*EnumType) FieldID() int16 { return 4 } +func (*DateType) FieldID() int16 { return 6 } +func (*UUIDType) FieldID() int16 { return 14 } +func (*Float16Type) FieldID() int16 { return 15 } + // Logical type to annotate a column that is always null. // // Sometimes when discovering the schema of existing data, values are always @@ -189,6 +198,7 @@ func (*Float16Type) String() string { return "FLOAT16" } type NullType struct{} func (*NullType) String() string { return "NULL" } +func (*NullType) FieldID() int16 { return 11 } // Decimal logical type annotation // @@ -206,6 +216,8 @@ func (t *DecimalType) String() string { return fmt.Sprintf("DECIMAL(%d,%d)", t.Precision, t.Scale) } +func (*DecimalType) FieldID() int16 { return 5 } + // Time units for logical types. type MilliSeconds struct{} type MicroSeconds struct{} @@ -215,23 +227,44 @@ func (*MilliSeconds) String() string { return "MILLIS" } func (*MicroSeconds) String() string { return "MICROS" } func (*NanoSeconds) String() string { return "NANOS" } +func (*MilliSeconds) FieldID() int16 { return 1 } +func (*MicroSeconds) FieldID() int16 { return 2 } +func (*NanoSeconds) FieldID() int16 { return 3 } + +// Duration returns the precision of the time unit. It is the length of one +// step, so a value stored in this unit is that many of these durations since +// the epoch or midnight. +func (*MilliSeconds) Duration() time.Duration { return time.Millisecond } +func (*MicroSeconds) Duration() time.Duration { return time.Microsecond } +func (*NanoSeconds) Duration() time.Duration { return time.Nanosecond } + +// TimeUnitValue is the set of time units a TimeUnit union may hold. Duration is +// intrinsic to a unit (like its name) and closes the interface: types that are +// not time units, though they satisfy thrift.UnionMember and String, do not +// have a Duration and so cannot be mistaken for a member here. +type TimeUnitValue interface { + thrift.UnionMember + String() string + Duration() time.Duration +} + +var timeUnitMembers = []thrift.UnionMember{ + (*MilliSeconds)(nil), + (*MicroSeconds)(nil), + (*NanoSeconds)(nil), +} + type TimeUnit struct { // union - Millis *MilliSeconds `thrift:"1"` - Micros *MicroSeconds `thrift:"2"` - Nanos *NanoSeconds `thrift:"3"` + Value TimeUnitValue } +func (*TimeUnit) UnionMembers() []thrift.UnionMember { return timeUnitMembers } + func (u *TimeUnit) String() string { - switch { - case u.Millis != nil: - return u.Millis.String() - case u.Micros != nil: - return u.Micros.String() - case u.Nanos != nil: - return u.Nanos.String() - default: + if u.Value == nil { return "" } + return u.Value.String() } // Timestamp logical type annotation @@ -246,6 +279,8 @@ func (t *TimestampType) String() string { return fmt.Sprintf("TIMESTAMP(isAdjustedToUTC=%t,unit=%s)", t.IsAdjustedToUTC, &t.Unit) } +func (*TimestampType) FieldID() int16 { return 8 } + // Time logical type annotation // // Allowed for physical types: INT32 (millis), INT64 (micros, nanos) @@ -258,6 +293,8 @@ func (t *TimeType) String() string { return fmt.Sprintf("TIME(isAdjustedToUTC=%t,unit=%s)", t.IsAdjustedToUTC, &t.Unit) } +func (*TimeType) FieldID() int16 { return 7 } + // Integer logical type annotation // // bitWidth must be 8, 16, 32, or 64. @@ -272,6 +309,8 @@ func (t *IntType) String() string { return fmt.Sprintf("INT(%d,%t)", t.BitWidth, t.IsSigned) } +func (*IntType) FieldID() int16 { return 10 } + // Embedded JSON logical type annotation // // Allowed for physical types: BINARY @@ -279,6 +318,8 @@ type JsonType struct{} func (t *JsonType) String() string { return "JSON" } +func (*JsonType) FieldID() int16 { return 12 } + // Embedded BSON logical type annotation // // Allowed for physical types: BINARY @@ -286,6 +327,8 @@ type BsonType struct{} func (t *BsonType) String() string { return "BSON" } +func (*BsonType) FieldID() int16 { return 13 } + // Embedded Variant logical type annotation // // Allowed for physical types: BYTE_ARRAY (with embedded Variant binary). @@ -306,6 +349,8 @@ type VariantType struct { func (*VariantType) String() string { return "VARIANT" } +func (*VariantType) FieldID() int16 { return 16 } + // Edge interpolation algorithm for Geography logical type type EdgeInterpolationAlgorithm int32 @@ -389,6 +434,8 @@ func (t *GeometryType) String() string { return fmt.Sprintf("GEOMETRY(%q)", crs) } +func (*GeometryType) FieldID() int16 { return 17 } + const GeographyDefaultCRS = defaultCRS // Embedded Geography logical type annotation @@ -419,78 +466,53 @@ func (t *GeographyType) String() string { return fmt.Sprintf("GEOGRAPHY(%q, %s)", crs, t.Algorithm) } +func (*GeographyType) FieldID() int16 { return 18 } + // LogicalType annotations to replace ConvertedType. // // To maintain compatibility, implementations using LogicalType for a // SchemaElement must also set the corresponding ConvertedType (if any) // from the following table. -type LogicalType struct { // union - UTF8 *StringType `thrift:"1"` // use ConvertedType UTF8 - Map *MapType `thrift:"2"` // use ConvertedType Map - List *ListType `thrift:"3"` // use ConvertedType List - Enum *EnumType `thrift:"4"` // use ConvertedType Enum - Decimal *DecimalType `thrift:"5"` // use ConvertedType Decimal + SchemaElement.{Scale, Precision} - Date *DateType `thrift:"6"` // use ConvertedType Date - - // use ConvertedType TimeMicros for Time{IsAdjustedToUTC: *, Unit: Micros} - // use ConvertedType TimeMillis for Time{IsAdjustedToUTC: *, Unit: Millis} - Time *TimeType `thrift:"7"` - - // use ConvertedType TimestampMicros for Timestamp{IsAdjustedToUTC: *, Unit: Micros} - // use ConvertedType TimestampMillis for Timestamp{IsAdjustedToUTC: *, Unit: Millis} - Timestamp *TimestampType `thrift:"8"` +// LogicalTypeValue is the set of annotations a LogicalType union may hold. The +// FieldID method carries each member's thrift field id; see the member list in +// logicalTypeMembers for the full id mapping. +type LogicalTypeValue interface { + thrift.UnionMember + String() string +} +var logicalTypeMembers = []thrift.UnionMember{ + (*StringType)(nil), // 1: use ConvertedType UTF8 + (*MapType)(nil), // 2: use ConvertedType Map + (*ListType)(nil), // 3: use ConvertedType List + (*EnumType)(nil), // 4: use ConvertedType Enum + (*DecimalType)(nil), // 5: use ConvertedType Decimal + SchemaElement.{Scale, Precision} + (*DateType)(nil), // 6: use ConvertedType Date + (*TimeType)(nil), // 7: use ConvertedType TimeMicros or TimeMillis + (*TimestampType)(nil), // 8: use ConvertedType TimestampMicros or TimestampMillis // 9: reserved for Interval - Integer *IntType `thrift:"10"` // use ConvertedType Int* or Uint* - Unknown *NullType `thrift:"11"` // no compatible ConvertedType - Json *JsonType `thrift:"12"` // use ConvertedType JSON - Bson *BsonType `thrift:"13"` // use ConvertedType BSON - UUID *UUIDType `thrift:"14"` // no compatible ConvertedType - Float16 *Float16Type `thrift:"15"` // no compatible ConvertedType - Variant *VariantType `thrift:"16"` // no compatible ConvertedType - Geometry *GeometryType `thrift:"17"` // no compatible ConvertedType - Geography *GeographyType `thrift:"18"` // no compatible ConvertedType + (*IntType)(nil), // 10: use ConvertedType Int* or Uint* + (*NullType)(nil), // 11: no compatible ConvertedType + (*JsonType)(nil), // 12: use ConvertedType JSON + (*BsonType)(nil), // 13: use ConvertedType BSON + (*UUIDType)(nil), // 14: no compatible ConvertedType + (*Float16Type)(nil), // 15: no compatible ConvertedType + (*VariantType)(nil), // 16: no compatible ConvertedType + (*GeometryType)(nil), // 17: no compatible ConvertedType + (*GeographyType)(nil), // 18: no compatible ConvertedType } +type LogicalType struct { // union + Value LogicalTypeValue +} + +func (*LogicalType) UnionMembers() []thrift.UnionMember { return logicalTypeMembers } + func (t *LogicalType) String() string { - switch { - case t.UTF8 != nil: - return t.UTF8.String() - case t.Map != nil: - return t.Map.String() - case t.List != nil: - return t.List.String() - case t.Enum != nil: - return t.Enum.String() - case t.Decimal != nil: - return t.Decimal.String() - case t.Date != nil: - return t.Date.String() - case t.Time != nil: - return t.Time.String() - case t.Timestamp != nil: - return t.Timestamp.String() - case t.Integer != nil: - return t.Integer.String() - case t.Unknown != nil: - return t.Unknown.String() - case t.Json != nil: - return t.Json.String() - case t.Bson != nil: - return t.Bson.String() - case t.UUID != nil: - return t.UUID.String() - case t.Float16 != nil: - return t.Float16.String() - case t.Variant != nil: - return t.Variant.String() - case t.Geometry != nil: - return t.Geometry.String() - case t.Geography != nil: - return t.Geography.String() - default: + if t.Value == nil { return "" } + return t.Value.String() } // Represents a element inside a schema definition. @@ -546,7 +568,7 @@ type SchemaElement struct { // // LogicalType replaces ConvertedType, but ConvertedType is still required // for some logical types to ensure forward-compatibility in format v1. - LogicalType thrift.Null[LogicalType] `thrift:"10,optional"` + LogicalType LogicalType `thrift:"10,optional"` } // Encodings supported by Parquet. Not all encodings are valid for all types. @@ -801,27 +823,75 @@ type DataPageHeaderV2 struct { // Block-based algorithm type annotation. type SplitBlockAlgorithm struct{} +func (*SplitBlockAlgorithm) FieldID() int16 { return 1 } + +// BloomFilterAlgorithmValue is the set of algorithms a BloomFilterAlgorithm +// union may hold. +type BloomFilterAlgorithmValue interface { + thrift.UnionMember +} + +var bloomFilterAlgorithmMembers = []thrift.UnionMember{ + (*SplitBlockAlgorithm)(nil), // 1 +} + // The algorithm used in Bloom filter. type BloomFilterAlgorithm struct { // union - Block *SplitBlockAlgorithm `thrift:"1"` + Value BloomFilterAlgorithmValue +} + +func (*BloomFilterAlgorithm) UnionMembers() []thrift.UnionMember { + return bloomFilterAlgorithmMembers } // Hash strategy type annotation. xxHash is an extremely fast non-cryptographic // hash algorithm. It uses 64 bits version of xxHash. type XxHash struct{} +func (*XxHash) FieldID() int16 { return 1 } + +// BloomFilterHashValue is the set of hash functions a BloomFilterHash union may +// hold. +type BloomFilterHashValue interface { + thrift.UnionMember +} + +var bloomFilterHashMembers = []thrift.UnionMember{ + (*XxHash)(nil), // 1 +} + // The hash function used in Bloom filter. This function takes the hash of a // column value using plain encoding. type BloomFilterHash struct { // union - XxHash *XxHash `thrift:"1"` + Value BloomFilterHashValue } +func (*BloomFilterHash) UnionMembers() []thrift.UnionMember { return bloomFilterHashMembers } + // The compression used in the Bloom filter. type BloomFilterUncompressed struct{} type BloomFilterGzip struct{} + +func (*BloomFilterUncompressed) FieldID() int16 { return 1 } +func (*BloomFilterGzip) FieldID() int16 { return 2 } + +// BloomFilterCompressionValue is the set of compressions a +// BloomFilterCompression union may hold. +type BloomFilterCompressionValue interface { + thrift.UnionMember +} + +var bloomFilterCompressionMembers = []thrift.UnionMember{ + (*BloomFilterUncompressed)(nil), // 1 + (*BloomFilterGzip)(nil), // 2 +} + type BloomFilterCompression struct { // union - Uncompressed *BloomFilterUncompressed `thrift:"1"` - GZip *BloomFilterGzip `thrift:"2"` + Value BloomFilterCompressionValue +} + +func (*BloomFilterCompression) UnionMembers() []thrift.UnionMember { + return bloomFilterCompressionMembers } // Bloom filter header is stored at beginning of Bloom filter data of each column @@ -939,7 +1009,7 @@ type ColumnMetaData struct { TotalCompressedSize int64 `thrift:"7,required"` // Optional key/value metadata. - KeyValueMetadata []KeyValue `thrift:"8,optional"` + KeyValueMetadata thrift.Slice[KeyValue] `thrift:"8,optional"` // Byte offset from beginning of file to first data page. DataPageOffset int64 `thrift:"9,required"` @@ -957,7 +1027,7 @@ type ColumnMetaData struct { // Set of all encodings used for pages in this column chunk. // This information can be used to determine if all data pages are // dictionary encoded for example. - EncodingStats []PageEncodingStats `thrift:"13,optional"` + EncodingStats thrift.Slice[PageEncodingStats] `thrift:"13,optional"` // Byte offset from beginning of file to Bloom filter data. BloomFilterOffset int64 `thrift:"14,optional"` @@ -983,15 +1053,32 @@ type EncryptionWithFooterKey struct{} type EncryptionWithColumnKey struct { // Column path in schema. - PathInSchema []string `thrift:"1,required"` + PathInSchema thrift.Slice[string] `thrift:"1,required"` // Retrieval metadata of column encryption key. KeyMetadata []byte `thrift:"2,optional"` } -type ColumnCryptoMetaData struct { - EncryptionWithFooterKey *EncryptionWithFooterKey `thrift:"1"` - EncryptionWithColumnKey *EncryptionWithColumnKey `thrift:"2"` +func (*EncryptionWithFooterKey) FieldID() int16 { return 1 } +func (*EncryptionWithColumnKey) FieldID() int16 { return 2 } + +// ColumnCryptoMetaDataValue is the set of key references a +// ColumnCryptoMetaData union may hold. +type ColumnCryptoMetaDataValue interface { + thrift.UnionMember +} + +var columnCryptoMetaDataMembers = []thrift.UnionMember{ + (*EncryptionWithFooterKey)(nil), // 1 + (*EncryptionWithColumnKey)(nil), // 2 +} + +type ColumnCryptoMetaData struct { // union + Value ColumnCryptoMetaDataValue +} + +func (*ColumnCryptoMetaData) UnionMembers() []thrift.UnionMember { + return columnCryptoMetaDataMembers } type ColumnChunk struct { @@ -1039,7 +1126,7 @@ type RowGroup struct { // If set, specifies a sort ordering of the rows in this RowGroup. // The sorting columns can be a subset of all the columns. - SortingColumns []SortingColumn `thrift:"4,optional"` + SortingColumns thrift.Slice[SortingColumn] `thrift:"4,optional"` // Byte offset from beginning of file to first page (data or dictionary) // in this row group @@ -1056,20 +1143,38 @@ type RowGroup struct { Ordinal int16 `thrift:"7,optional,writezero"` } +// Reset clears r in place, retaining allocated capacity for reuse. Elements +// of the retained slices are recursively cleared so that values from a +// previous thrift decode cannot leak into the next one (the decoder only +// writes fields present in its input). func (r *RowGroup) Reset() { - r.FileOffset = 0 - r.NumRows = 0 - r.TotalByteSize = 0 - r.SortingColumns = r.SortingColumns[:0] + for i := range r.Columns { + r.Columns[i].Reset() + } r.Columns = r.Columns[:0] - r.Ordinal = 0 r.TotalByteSize = 0 + r.NumRows = 0 + clear(r.SortingColumns) + r.SortingColumns = r.SortingColumns[:0] + r.FileOffset = 0 r.TotalCompressedSize = 0 + r.Ordinal = 0 } // Empty struct to signal the order defined by the physical or logical type. type TypeDefinedOrder struct{} +func (*TypeDefinedOrder) FieldID() int16 { return 1 } + +// ColumnOrderValue is the set of orderings a ColumnOrder union may hold. +type ColumnOrderValue interface { + thrift.UnionMember +} + +var columnOrderMembers = []thrift.UnionMember{ + (*TypeDefinedOrder)(nil), // 1 +} + // Union to specify the order used for the min_value and max_value fields for a // column. This union takes the role of an enhanced enum that allows rich // elements (which will be needed for a collation-based ordering in the future). @@ -1126,9 +1231,11 @@ type ColumnOrder struct { // union // - If the min is +0, the row group may contain -0 values as well. // - If the max is -0, the row group may contain +0 values as well. // - When looking for NaN values, min and max should be ignored. - TypeOrder *TypeDefinedOrder `thrift:"1"` + Value ColumnOrderValue } +func (*ColumnOrder) UnionMembers() []thrift.UnionMember { return columnOrderMembers } + type PageLocation struct { // Offset of the page in the file. Offset int64 `thrift:"1,required"` @@ -1145,13 +1252,13 @@ type PageLocation struct { type OffsetIndex struct { // PageLocations, ordered by increasing PageLocation.offset. It is required // that page_locations[i].first_row_index < page_locations[i+1].first_row_index. - PageLocations []PageLocation `thrift:"1,required"` + PageLocations thrift.Slice[PageLocation] `thrift:"1,required"` // Unencoded/uncompressed size for BYTE_ARRAY types. // // See documention for unencoded_byte_array_data_bytes in SizeStatistics for // more details on this field. - UnencodedByteArrayDataBytes []int64 `thrift:"2,optional"` + UnencodedByteArrayDataBytes thrift.Slice[int64] `thrift:"2,optional"` } func (o *OffsetIndex) Reset() { @@ -1172,7 +1279,7 @@ type ColumnIndex struct { // have to set the corresponding entries in min_values and max_values to // byte[0], so that all lists have the same length. If false, the // corresponding entries in min_values and max_values must be valid. - NullPages []bool `thrift:"1,required"` + NullPages thrift.Slice[bool] `thrift:"1,required"` // Two lists containing lower and upper bounds for the values of each page // determined by the ColumnOrder of the column. These may be the actual @@ -1182,8 +1289,8 @@ type ColumnIndex struct { // Such more compact values must still be valid values within the column's // logical type. Readers must make sure that list entries are populated before // using them by inspecting null_pages. - MinValues [][]byte `thrift:"2,required"` - MaxValues [][]byte `thrift:"3,required"` + MinValues thrift.Slice[[]byte] `thrift:"2,required"` + MaxValues thrift.Slice[[]byte] `thrift:"3,required"` // Stores whether both min_values and max_values are ordered and if so, in // which direction. This allows readers to perform binary searches in both @@ -1195,7 +1302,7 @@ type ColumnIndex struct { // The writezero tag satisfies spec: // "Writers SHOULD always write this field even if no null values are present or the column is not nullable." // https://github.com/apache/parquet-format/blob/apache-parquet-format-2.12.0/src/main/thrift/parquet.thrift#L1197-L1198 - NullCounts []int64 `thrift:"5,optional,writezero"` + NullCounts thrift.Slice[int64] `thrift:"5,optional,writezero"` // Contains repetition level histograms for each page // concatenated together. The repetition_level_histogram field on @@ -1207,10 +1314,10 @@ type ColumnIndex struct { // Element 0 is the first element of the histogram for the first page. // Element (max_repetition_level + 1) is the first element of the histogram // for the second page. - RepetitionLevelHistogram []int64 `thrift:"6,optional"` + RepetitionLevelHistogram thrift.Slice[int64] `thrift:"6,optional"` // Same as repetition_level_histograms except for definitions levels. - DefinitionLevelHistogram []int64 `thrift:"7,optional"` + DefinitionLevelHistogram thrift.Slice[int64] `thrift:"7,optional"` } func (c *ColumnIndex) Reset() { @@ -1253,9 +1360,26 @@ type AesGcmCtrV1 struct { SupplyAadPrefix bool `thrift:"3,optional"` } +func (*AesGcmV1) FieldID() int16 { return 1 } +func (*AesGcmCtrV1) FieldID() int16 { return 2 } + +// EncryptionAlgorithmValue is the set of algorithms an EncryptionAlgorithm +// union may hold. +type EncryptionAlgorithmValue interface { + thrift.UnionMember +} + +var encryptionAlgorithmMembers = []thrift.UnionMember{ + (*AesGcmV1)(nil), // 1 + (*AesGcmCtrV1)(nil), // 2 +} + type EncryptionAlgorithm struct { // union - AesGcmV1 *AesGcmV1 `thrift:"1"` - AesGcmCtrV1 *AesGcmCtrV1 `thrift:"2"` + Value EncryptionAlgorithmValue +} + +func (*EncryptionAlgorithm) UnionMembers() []thrift.UnionMember { + return encryptionAlgorithmMembers } // Description for file metadata. @@ -1278,7 +1402,7 @@ type FileMetaData struct { RowGroups thrift.Slice[RowGroup] `thrift:"4,required"` // Optional key/value metadata. - KeyValueMetadata []KeyValue `thrift:"5,optional"` + KeyValueMetadata thrift.Slice[KeyValue] `thrift:"5,optional"` // String for application that wrote this file. This should be in the format // version (build ). @@ -1299,7 +1423,7 @@ type FileMetaData struct { // // The obsolete min and max fields in the Statistics object are always sorted // by signed comparison regardless of column_orders. - ColumnOrders []ColumnOrder `thrift:"7,optional"` + ColumnOrders thrift.Slice[ColumnOrder] `thrift:"7,optional"` // Encryption algorithm. This field is set only in encrypted files // with plaintext footer. Files with encrypted footer store algorithm id diff --git a/vendor/github.com/parquet-go/parquet-go/format/reset.go b/vendor/github.com/parquet-go/parquet-go/format/reset.go new file mode 100644 index 00000000000..10bbcd4dcfa --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/format/reset.go @@ -0,0 +1,124 @@ +package format + +// The Reset methods in this file clear values in place while retaining +// allocated slice capacity, so that a value can be reused as the decode +// target of multiple thrift deserializations without allocating on each +// decode (see FooterDecoder). +// +// Because the thrift decoder only writes fields that are present in the +// input, Reset must recursively clear the elements of retained slices; +// otherwise fields decoded from a previous input would leak into the next +// decoded value. Union fields are the exception: the decoder itself clears +// unions absent from the input and zeroes reused members, so Reset retains +// their member allocations for the next decode to reuse. +// +// Byte slice and string fields decoded from footers alias the input buffer +// (they are replaced, never reused, by the decoder), so Reset sets them to +// nil or empty instead of truncating, releasing references to the previous +// input buffer. This includes the contents of retained union members whose +// fields alias the buffer: the member allocation is kept for the next +// decode to reuse, but its contents are zeroed so no retained member holds +// a reference into a buffer with unrelated data. + +// Reset clears m in place, retaining allocated capacity for reuse in +// subsequent thrift decodes. +// +// Note that after reuse, optional list fields that are absent from the +// decoded input are left empty but non-nil, whereas decoding into a fresh +// FileMetaData leaves them nil. Both states are semantically equivalent +// (zero-length), but programs distinguishing nil from empty slices, or +// re-encoding the value, can observe the difference. +func (m *FileMetaData) Reset() { + m.Version = 0 + for i := range m.Schema { + m.Schema[i].Reset() + } + m.Schema = m.Schema[:0] + m.NumRows = 0 + for i := range m.RowGroups { + m.RowGroups[i].Reset() + } + m.RowGroups = m.RowGroups[:0] + clear(m.KeyValueMetadata) + m.KeyValueMetadata = m.KeyValueMetadata[:0] + m.CreatedBy = "" + m.ColumnOrders = m.ColumnOrders[:0] + // Retained union member; scrub buffer-aliasing contents (see file header). + switch v := m.EncryptionAlgorithm.Value.(type) { + case *AesGcmV1: + *v = AesGcmV1{} + case *AesGcmCtrV1: + *v = AesGcmCtrV1{} + } + m.FooterSigningKeyMetadata = nil +} + +// Reset clears s in place, retaining allocated capacity for reuse in +// subsequent thrift decodes. +func (s *SchemaElement) Reset() { + s.Type.Reset() + s.TypeLength.Reset() + s.RepetitionType.Reset() + s.Name = "" + s.NumChildren.Reset() + s.ConvertedType.Reset() + s.Scale.Reset() + s.Precision.Reset() + s.FieldID = 0 + // Retained union member; scrub the buffer-aliasing CRS strings of the + // Geometry and Geography members (see file header). + switch m := s.LogicalType.Value.(type) { + case *GeometryType: + *m = GeometryType{} + case *GeographyType: + *m = GeographyType{} + } +} + +// Reset clears c in place, retaining allocated capacity for reuse in +// subsequent thrift decodes. +func (c *ColumnChunk) Reset() { + c.FilePath = "" + c.FileOffset = 0 + c.MetaData.Reset() + c.OffsetIndexOffset = 0 + c.OffsetIndexLength = 0 + c.ColumnIndexOffset = 0 + c.ColumnIndexLength = 0 + // Retained union member; scrub buffer-aliasing contents (see file header). + if v, ok := c.CryptoMetadata.Value.(*EncryptionWithColumnKey); ok { + *v = EncryptionWithColumnKey{} + } + c.EncryptedColumnMetadata = nil +} + +// Reset clears c in place, retaining allocated capacity for reuse in +// subsequent thrift decodes. +func (c *ColumnMetaData) Reset() { + c.Type = 0 + c.Encoding = c.Encoding[:0] + clear(c.PathInSchema) + c.PathInSchema = c.PathInSchema[:0] + c.Codec = 0 + c.NumValues = 0 + c.TotalUncompressedSize = 0 + c.TotalCompressedSize = 0 + clear(c.KeyValueMetadata) + c.KeyValueMetadata = c.KeyValueMetadata[:0] + c.DataPageOffset = 0 + c.IndexPageOffset = 0 + c.DictionaryPageOffset = 0 + // Statistics byte slices alias the input buffer (replaced, never + // appended to), so zero the whole struct instead of truncating. + c.Statistics = Statistics{} + clear(c.EncodingStats) + c.EncodingStats = c.EncodingStats[:0] + c.BloomFilterOffset = 0 + c.BloomFilterLength = 0 + // The histograms and geospatial types retain capacity. + c.SizeStatistics.UnencodedByteArrayDataBytes = 0 + c.SizeStatistics.RepetitionLevelHistogram = c.SizeStatistics.RepetitionLevelHistogram[:0] + c.SizeStatistics.DefinitionLevelHistogram = c.SizeStatistics.DefinitionLevelHistogram[:0] + c.GeospatialStatistics.BBox = BoundingBox{} + c.GeospatialStatistics.GeoSpatialTypes = c.GeospatialStatistics.GeoSpatialTypes[:0] +} diff --git a/vendor/github.com/parquet-go/parquet-go/limits.go b/vendor/github.com/parquet-go/parquet-go/limits.go index be1a08ff7d3..9c3104427ba 100644 --- a/vendor/github.com/parquet-go/parquet-go/limits.go +++ b/vendor/github.com/parquet-go/parquet-go/limits.go @@ -33,30 +33,75 @@ const ( estimatedSizeOfByteArrayValues = 20 ) +// The make* functions below use a single unsigned comparison to bounds-check the +// index (uint(i) > max catches both i < 0 and i > max), and delegate the failure +// to a dedicated out-of-line panic helper. This keeps their inline cost low: the +// previous implementation inlined fmt.Errorf on the failure path, which inflated +// every caller (Value.Level cost 192) and prevented inlining. Keeping the error +// construction out of line lets these helpers inline and lets small callers such +// as Value.WithRepetitionLevel dead-code-eliminate the check when the argument is +// provably in range. + func makeRepetitionLevel(i int) byte { - checkIndexRange("repetition level", i, 0, MaxRepetitionLevel) + if uint(i) > MaxRepetitionLevel { + panicRepetitionLevelOutOfRange(i) + } return byte(i) } func makeDefinitionLevel(i int) byte { - checkIndexRange("definition level", i, 0, MaxDefinitionLevel) + if uint(i) > MaxDefinitionLevel { + panicDefinitionLevelOutOfRange(i) + } return byte(i) } func makeColumnIndex(i int) uint16 { - checkIndexRange("column index", i, 0, MaxColumnIndex) + if uint(i) > MaxColumnIndex { + panicColumnIndexOutOfRange(i) + } return uint16(i) } func makeNumValues(i int) int32 { - checkIndexRange("number of values", i, 0, math.MaxInt32) + if uint(i) > math.MaxInt32 { + panicNumValuesOutOfRange(i) + } return int32(i) } -func checkIndexRange(typ string, i, min, max int) { - if i < min || i > max { - panic(errIndexOutOfRange(typ, i, min, max)) +// The panic helpers are kept out of line (along with the error construction) so +// the make* functions above stay cheap to inline. + +func panicRepetitionLevelOutOfRange(i int) { + panic(errIndexOutOfRange("repetition level", i, 0, MaxRepetitionLevel)) +} + +func panicDefinitionLevelOutOfRange(i int) { + panic(errIndexOutOfRange("definition level", i, 0, MaxDefinitionLevel)) +} + +func panicColumnIndexOutOfRange(i int) { + panic(errIndexOutOfRange("column index", i, 0, MaxColumnIndex)) +} + +func panicNumValuesOutOfRange(i int) { + panic(errIndexOutOfRange("number of values", i, 0, math.MaxInt32)) +} + +// panicLevelOutOfRange performs the fine-grained range check for Value.Level's +// combined fast-path test. It is only called when at least one of the three +// arguments is out of range, so it can afford to recompute which one to produce +// a precise error message. Keeping it out of line lets Value.Level reduce its +// hot path to a single combined comparison and stay cheap enough to inline. +func panicLevelOutOfRange(repetitionLevel, definitionLevel, columnIndex int) { + if uint(repetitionLevel) > MaxRepetitionLevel { + panicRepetitionLevelOutOfRange(repetitionLevel) + } + if uint(definitionLevel) > MaxDefinitionLevel { + panicDefinitionLevelOutOfRange(definitionLevel) } + panicColumnIndexOutOfRange(columnIndex) } func errIndexOutOfRange(typ string, i, min, max int) error { diff --git a/vendor/github.com/parquet-go/parquet-go/merge.go b/vendor/github.com/parquet-go/parquet-go/merge.go index 0c47386b35b..ab3d5d19312 100644 --- a/vendor/github.com/parquet-go/parquet-go/merge.go +++ b/vendor/github.com/parquet-go/parquet-go/merge.go @@ -84,18 +84,38 @@ func MergeRowGroups(rowGroups []RowGroup, options ...RowGroupOption) (RowGroup, dropDuplicatedRows := config.Sorting.DropDuplicatedRows // Optimization: detect non-overlapping row groups and create segments + makeMerged := func(rowGroups []RowGroup) RowGroup { + merged := &mergedRowGroup{ + compare: mergedCompare, + dropDuplicatedRows: dropDuplicatedRows, + } + merged.init(schema, mergedSortingColumns, rowGroups) + return merged + } + rowGroupSegments := make([]RowGroup, 0) for segment := range overlappingRowGroups(mergedRowGroups, schema, mergedSortingColumns, mergedCompare) { if len(segment) == 1 { - rowGroupSegments = append(rowGroupSegments, segment[0]) - } else { - merged := &mergedRowGroup{ - compare: mergedCompare, - dropDuplicatedRows: dropDuplicatedRows, + rowGroupSegments = append(rowGroupSegments, segment[0].rowGroup) + continue + } + // Refine partially overlapping segments: stretches of key space + // covered by a single row group are sliced off as row-range views, + // leaving only the truly overlapping stretches for the merge. Not + // applied when dropping duplicated rows: which physical row of an + // equal-key run survives depends on the interleaving of ties across + // row groups, which refinement does not preserve. + if !dropDuplicatedRows && !disableMergeRefinement { + if refined := refineSegment(newRefineTargets(segment, schema, mergedSortingColumns), mergedCompare, makeMerged); refined != nil { + rowGroupSegments = append(rowGroupSegments, refined...) + continue } - merged.init(schema, mergedSortingColumns, segment) - rowGroupSegments = append(rowGroupSegments, merged) } + rowGroups := make([]RowGroup, len(segment)) + for i := range segment { + rowGroups[i] = segment[i].rowGroup + } + rowGroupSegments = append(rowGroupSegments, makeMerged(rowGroups)) } if len(rowGroupSegments) == 1 { @@ -120,18 +140,20 @@ func MergeRowGroups(rowGroups []RowGroup, options ...RowGroupOption) (RowGroup, }, nil } +// rowGroupRange associates a row group with the bounds of its sorting columns +// (nil when the bounds could not be determined). +type rowGroupRange struct { + rowGroup RowGroup + minRow Row + maxRow Row +} + // overlappingRowGroups analyzes row groups to find non-overlapping segments // Returns groups of row groups where each group either: // 1. Contains a single non-overlapping row group (can be concatenated) // 2. Contains multiple overlapping row groups (need to be merged) -func overlappingRowGroups(rowGroups []RowGroup, schema *Schema, sorting []SortingColumn, compare func(Row, Row) int) iter.Seq[[]RowGroup] { - return func(yield func([]RowGroup) bool) { - type rowGroupRange struct { - rowGroup RowGroup - minRow Row - maxRow Row - } - +func overlappingRowGroups(rowGroups []RowGroup, schema *Schema, sorting []SortingColumn, compare func(Row, Row) int) iter.Seq[[]rowGroupRange] { + return func(yield func([]rowGroupRange) bool) { rowGroupRanges := make([]rowGroupRange, 0, len(rowGroups)) for _, rg := range rowGroups { if rg.NumRows() == 0 { @@ -139,7 +161,13 @@ func overlappingRowGroups(rowGroups []RowGroup, schema *Schema, sorting []Sortin } minRow, maxRow, err := rowGroupRangeOfSortedColumns(rg, schema, sorting) if err != nil { - yield(rowGroups) + // Bounds unavailable: yield all row groups as a single segment + // with nil bounds, which the caller merges without refinement. + all := make([]rowGroupRange, len(rowGroups)) + for i, rg := range rowGroups { + all[i] = rowGroupRange{rowGroup: rg} + } + yield(all) return } rowGroupRanges = append(rowGroupRanges, rowGroupRange{ @@ -152,7 +180,7 @@ func overlappingRowGroups(rowGroups []RowGroup, schema *Schema, sorting []Sortin return } if len(rowGroupRanges) == 1 { - yield([]RowGroup{rowGroupRanges[0].rowGroup}) + yield(rowGroupRanges[:1]) return } @@ -162,29 +190,26 @@ func overlappingRowGroups(rowGroups []RowGroup, schema *Schema, sorting []Sortin }) // Detect overlapping segments - currentSegment := []RowGroup{rowGroupRanges[0].rowGroup} + segmentStart := 0 currentMax := rowGroupRanges[0].maxRow - for _, rr := range rowGroupRanges[1:] { + for i, rr := range rowGroupRanges[1:] { if compare(rr.minRow, currentMax) <= 0 { - // Overlapping - add to current segment and extend max if necessary - currentSegment = append(currentSegment, rr.rowGroup) + // Overlapping - extend max if necessary if compare(rr.maxRow, currentMax) > 0 { currentMax = rr.maxRow } } else { // Non-overlapping - yield current segment - if !yield(currentSegment) { + if !yield(rowGroupRanges[segmentStart : i+1]) { return } - currentSegment = []RowGroup{rr.rowGroup} + segmentStart = i + 1 currentMax = rr.maxRow } } - if len(currentSegment) > 0 { - yield(currentSegment) - } + yield(rowGroupRanges[segmentStart:]) } } @@ -222,18 +247,26 @@ func rowGroupRangeOfSortedColumns(rg RowGroup, schema *Schema, sorting []Sorting return nil, nil, fmt.Errorf("column index not available for sorting column %s", sortingColumnPath) } - // Since data is sorted by sorting columns, we can efficiently get min/max: - // - Min value = min of first non-null page - // - Max value = max of last non-null page + // Since data is sorted by sorting columns, we can bound the first and + // last rows of the row group from the first and last non-null pages of + // the column index. The bounds are expressed in sort order: when the + // column is sorted in descending order, the first row holds the + // largest value and the last row holds the smallest one, so the page + // statistics to read are inverted. numPages := columnIndex.NumPages() + descending := sortingColumn.Descending() - // Find first non-null page for min value - var globalMin Value + // Bound the first row in sort order from the first non-null page + var firstValue Value var found bool for pageIdx := range numPages { if !columnIndex.NullPage(pageIdx) { - if minValue := columnIndex.MinValue(pageIdx); !minValue.IsNull() { - globalMin, found = minValue, true + value := columnIndex.MinValue(pageIdx) + if descending { + value = columnIndex.MaxValue(pageIdx) + } + if !value.IsNull() { + firstValue, found = value, true break } } @@ -242,20 +275,24 @@ func rowGroupRangeOfSortedColumns(rg RowGroup, schema *Schema, sorting []Sorting return nil, nil, fmt.Errorf("no valid pages found in column index for column %s", sortingColumnPath) } - // Find last non-null page for max value - var globalMax Value + // Bound the last row in sort order from the last non-null page + var lastValue Value for pageIdx := numPages - 1; pageIdx >= 0; pageIdx-- { if !columnIndex.NullPage(pageIdx) { - if maxValue := columnIndex.MaxValue(pageIdx); !maxValue.IsNull() { - globalMax = maxValue + value := columnIndex.MaxValue(pageIdx) + if descending { + value = columnIndex.MinValue(pageIdx) + } + if !value.IsNull() { + lastValue = value break } } } // Set the min/max values with proper levels - minValues[sortingColumnIndex] = globalMin.Level(0, 1, sortingColumnIndex) - maxValues[sortingColumnIndex] = globalMax.Level(0, 1, sortingColumnIndex) + minValues[sortingColumnIndex] = firstValue.Level(0, 1, sortingColumnIndex) + maxValues[sortingColumnIndex] = lastValue.Level(0, 1, sortingColumnIndex) } minRow = Row(minValues) @@ -278,6 +315,12 @@ type mergedRowGroup struct { dropDuplicatedRows bool } +// rowGroupSegments opts out of segment splitting: a mergedRowGroup interleaves +// rows from overlapping row groups via a heap merge, so its row groups cannot be +// written independently without losing the merged ordering. It overrides the +// method promoted from the embedded multiRowGroup. +func (m *mergedRowGroup) rowGroupSegments() []RowGroup { return nil } + func (m *mergedRowGroup) Rows() Rows { // The row group needs to respect a sorting order; the merged row reader // uses a heap to merge rows from the row groups. @@ -307,6 +350,18 @@ type sortedSegmentRowGroup struct { dropDuplicatedRows bool } +// rowGroupSegments implements orderedRowGroupSegments: the segments are already +// in sorted order and each segment's own Rows() preserves its internal ordering, +// so writing them in sequence preserves the global order. It returns nil when +// dropping duplicates, because deduplication spans segment boundaries and would +// be lost if segments were written independently. +func (s *sortedSegmentRowGroup) rowGroupSegments() []RowGroup { + if s.dropDuplicatedRows { + return nil + } + return s.segments +} + func (s *sortedSegmentRowGroup) Rows() Rows { readers := make([]Rows, len(s.segments)) for i, seg := range s.segments { @@ -489,14 +544,12 @@ func mergeRowReaders[T RowReader](rows []T, compare func(Row, Row) int) RowReade } default: buffers := make([]bufferedRowReader, len(rows)) - readers := make([]*bufferedRowReader, len(rows)) for i, r := range rows { buffers[i].rows = r - readers[i] = &buffers[i] } return &mergedRowReader{ compare: compare, - readers: readers, + buffers: buffers, } } } @@ -507,6 +560,8 @@ type mergedRowReader2 struct { compare func(Row, Row) int readers [2]*bufferedRowReader buffers [2]bufferedRowReader + prev int // <0 if r0 won the previous game, >0 if r1 won, 0 otherwise + streak int32 // consecutive games won by the same reader initialized bool } @@ -584,15 +639,42 @@ func (m *mergedRowReader2) ReadRows(rows []Row) (n int, err error) { for n < len(rows) { switch cmp := m.compare(r0.head(), r1.head()); { case cmp < 0: - rows[n] = append(rows[n][:0], r0.head()...) - n++ - hasNext0 = r0.next() - hasNext1 = true + if m.prev < 0 { + m.streak++ + } else { + m.streak = 0 + } + m.prev = -1 + if m.streak >= runDetectionStreak { + // r0 has been winning: gallop through its buffered rows + // for the run that sorts strictly before r1's head (ties + // are emitted pairwise by the case below) and emit it in + // bulk. Interleaved inputs rarely reach the streak + // threshold and pay only the cost of the counter. + n, hasNext0 = m.emitRun(rows, n, r0, r1.head()) + hasNext1 = true + } else { + rows[n] = append(rows[n][:0], r0.head()...) + n++ + hasNext0 = r0.next() + hasNext1 = true + } case cmp > 0: - rows[n] = append(rows[n][:0], r1.head()...) - n++ - hasNext0 = true - hasNext1 = r1.next() + if m.prev > 0 { + m.streak++ + } else { + m.streak = 0 + } + m.prev = 1 + if m.streak >= runDetectionStreak { + n, hasNext1 = m.emitRun(rows, n, r1, r0.head()) + hasNext0 = true + } else { + rows[n] = append(rows[n][:0], r1.head()...) + n++ + hasNext0 = true + hasNext1 = r1.next() + } default: rows[n] = append(rows[n][:0], r0.head()...) n++ @@ -602,6 +684,8 @@ func (m *mergedRowReader2) ReadRows(rows []Row) (n int, err error) { n++ hasNext1 = r1.next() } + m.prev = 0 + m.streak = 0 } if !hasNext0 || !hasNext1 { break @@ -612,39 +696,83 @@ func (m *mergedRowReader2) ReadRows(rows []Row) (n int, err error) { return n, nil } +// emitRun bulk-emits the run of buffered rows of r that sort strictly before +// bound; the head of r must already be known to. It returns the new number of +// rows produced and whether r has more rows buffered. +func (m *mergedRowReader2) emitRun(rows []Row, n int, r *bufferedRowReader, bound Row) (int, bool) { + window := r.window() + if max := len(rows) - n; len(window) > max { + window = window[:max] + } + run := 1 + if len(window) > 1 { + run += runLength(window[1:], bound, m.compare, -1) + } + for _, row := range window[:run] { + rows[n] = append(rows[n][:0], row...) + n++ + } + return n, r.advance(int32(run)) +} + +// mergedRowReader merges k buffered row readers using a tournament tree of +// losers, which performs ~log2(k) comparisons per row instead of the ~2*log2(k) +// required to sift down a binary min-heap. +// +// The tree is laid out as the first k positions of a 2k binary heap: internal +// node i stores the loser of the game played at that position, identified by +// the index of its buffer, and the leaf for buffer i sits at implicit position +// k+i. The overall winner is kept out of the tree in the winner field, and its +// leaf position in winnerLeaf. Advancing the merge replays the games on the +// path from the winner's leaf to the root, comparing the new head of the +// winner against the losers stored along the way. Exhausted readers are +// represented by a negative value which loses every game it plays. type mergedRowReader struct { compare func(Row, Row) int - readers []*bufferedRowReader + buffers []bufferedRowReader + losers []int32 + count int + winner int32 + winnerLeaf int32 + streak int32 // consecutive games won by the current winner initialized bool } +// runDetectionStreak is the number of consecutive games the same reader must +// win before the merge switches to run mode. When the merged inputs are mostly +// disjoint (e.g. sorted row groups overlapping only at their boundaries), the +// same reader wins long streaks and replaying ~log2(k) games per row is wasted +// work; run mode computes the second-smallest head once and then emits rows +// with a single comparison each. Interleaved inputs never reach the threshold +// and pay only the cost of maintaining the streak counter. +const runDetectionStreak = 3 + func (m *mergedRowReader) initialize() error { - for i, r := range m.readers { - switch err := r.read(); err { + k := len(m.buffers) + m.losers = make([]int32, k) + m.count = k + + leaves := make([]int32, k) + for i := range leaves { + leaves[i] = int32(i) + } + + for i := range m.buffers { + switch err := m.buffers[i].read(); err { case nil: case io.EOF: - m.readers[i] = nil + leaves[i] = -1 + m.count-- default: - m.readers = nil + m.count = 0 return err } } - n := 0 - for _, r := range m.readers { - if r != nil { - m.readers[n] = r - n++ - } + if m.count > 0 { + m.winner = m.playInitialGames(0, leaves) + m.winnerLeaf = int32(k) + m.winner } - - clear := m.readers[n:] - for i := range clear { - clear[i] = nil - } - - m.readers = m.readers[:n] - m.heapInit() return nil } @@ -657,95 +785,182 @@ func (m *mergedRowReader) ReadRows(rows []Row) (n int, err error) { } } - for n < len(rows) && len(m.readers) != 0 { - r := m.readers[0] - if r.empty() { // This readers buffer has been exhausted, repopulate it. - if err := r.read(); err != nil { - if err == io.EOF { - m.heapPop() - continue + for n < len(rows) && m.count != 0 { + c := &m.buffers[m.winner] + + if c.empty() { // This reader's buffer has been exhausted, repopulate it. + switch err := c.read(); err { + case nil: + case io.EOF: + m.winner = -1 + m.count-- + if m.count == 0 { + break } + default: return n, err - } else { - if !m.heapDown(0, len(m.readers)) { // heap.Fix - m.heapUp(0) - } - continue } + // The winner's head changed (or the winner was exhausted), replay + // the games on the path from its leaf to the root to determine the + // new winner. + prev := m.winner + m.replayGames() + if m.winner != prev { + m.streak = 0 + } + continue } - rows[n] = append(rows[n][:0], r.head()...) + rows[n] = append(rows[n][:0], c.head()...) n++ - if !r.next() { + if !c.next() { return n, nil } - if !m.heapDown(0, len(m.readers)) { // heap.Fix - m.heapUp(0) + + if m.streak >= runDetectionStreak { + // The same reader has been winning; emit its run in bulk. The run + // bound is the second-smallest head across all readers, so the + // winner keeps winning as long as its head does not exceed it + // (ties favor the incumbent, matching the strict comparison in + // replayGames). Other readers are not consumed during the run, so + // the bound remains valid until it is crossed. The length of the + // run within the buffered window is found with O(log n) + // comparisons: a single comparison of the last buffered row + // settles the common case where the whole window is part of the + // run. + bound := m.runBound() + for n < len(rows) { + window := c.window() + if max := len(rows) - n; len(window) > max { + window = window[:max] + } + run := len(window) + if bound != nil { + run = runLength(window, bound, m.compare, 0) + } + for _, row := range window[:run] { + rows[n] = append(rows[n][:0], row...) + n++ + } + if !c.advance(int32(run)) { + return n, nil + } + if run < len(window) { + break // the run bound was crossed + } + } + m.streak = 0 + m.replayGames() + continue + } + + prev := m.winner + m.replayGames() + if m.winner == prev { + m.streak++ + } else { + m.streak = 0 } } - if len(m.readers) == 0 { + if m.count == 0 { err = io.EOF } return n, err } -func (m *mergedRowReader) heapInit() { - n := len(m.readers) - for i := n/2 - 1; i >= 0; i-- { - m.heapDown(i, n) +// runBound returns the second-smallest head among the merged readers, i.e. the +// row that the current winner's head must not exceed for the winner to keep +// winning. In a tournament tree of losers the runner-up necessarily lost its +// game directly against the overall winner, so it is stored at one of the +// nodes on the winner's path from leaf to root; the minimum over those players +// is the runner-up. Returns nil when the winner is the only reader left. +func (m *mergedRowReader) runBound() (bound Row) { + for offset := (m.winnerLeaf - 1) / 2; ; offset = (offset - 1) / 2 { + if player := m.losers[offset]; player >= 0 { + if head := m.buffers[player].head(); bound == nil || m.compare(head, bound) < 0 { + bound = head + } + } + if offset == 0 { + return bound + } } } -func (m *mergedRowReader) heapPop() { - n := len(m.readers) - 1 - m.heapSwap(0, n) - m.heapDown(0, n) - m.readers = m.readers[:n] +// playInitialGames recursively plays the tournament rooted at position i, +// storing the loser of each game at the internal node where it was played, +// and returns the winner of the subtree. +func (m *mergedRowReader) playInitialGames(i int32, leaves []int32) int32 { + k := int32(len(m.buffers)) + if i >= k { // leaf or out of bounds + if i -= k; int(i) < len(leaves) { + return leaves[i] + } + return -1 + } + n1 := m.playInitialGames(2*i+1, leaves) + n2 := m.playInitialGames(2*i+2, leaves) + loser, winner := m.playGame(n1, n2) + m.losers[i] = loser + return winner } -func (m *mergedRowReader) heapUp(j int) { - for { - i := (j - 1) / 2 // parent - if i == j || !(m.compare(m.readers[j].head(), m.readers[i].head()) < 0) { - break - } - m.heapSwap(i, j) - j = i +func (m *mergedRowReader) playGame(n1, n2 int32) (loser, winner int32) { + if n1 < 0 { + return n1, n2 + } + if n2 < 0 { + return n2, n1 } + if m.compare(m.buffers[n1].head(), m.buffers[n2].head()) < 0 { + return n2, n1 + } + return n1, n2 } -func (m *mergedRowReader) heapDown(i0, n int) bool { - i := i0 - for { - j1 := 2*i + 1 - if j1 >= n || j1 < 0 { // j1 < 0 after int overflow - break - } - j := j1 // left child - if j2 := j1 + 1; j2 < n && m.compare(m.readers[j2].head(), m.readers[j1].head()) < 0 { - j = j2 // = 2*i + 2 // right child +// replayGames walks the path from the current winner's leaf to the root, +// playing the winner against the losers stored along the way and exchanging +// them when they win, then records the new overall winner. +func (m *mergedRowReader) replayGames() { + winner := m.winner + for offset := (m.winnerLeaf - 1) / 2; ; offset = (offset - 1) / 2 { + player := m.losers[offset] + + if player >= 0 { + if winner < 0 || m.compare(m.buffers[player].head(), m.buffers[winner].head()) < 0 { + m.losers[offset] = winner + winner = player + } } - if !(m.compare(m.readers[j].head(), m.readers[i].head()) < 0) { + + if offset == 0 { break } - m.heapSwap(i, j) - i = j } - return i > i0 + m.winner = winner + m.winnerLeaf = int32(len(m.buffers)) + winner } -func (m *mergedRowReader) heapSwap(i, j int) { - m.readers[i], m.readers[j] = m.readers[j], m.readers[i] -} +// minRowBufferSize is the initial buffer size of a bufferedRowReader, and +// maxRowBufferSize the size it can grow to. Buffers grow exponentially as +// long as the underlying reader keeps filling them completely, so merges of +// small row groups do not pay for full-size buffers while sustained merges +// amortize refills and extend the reach of the bulk run emission paths, +// which are bounded by the buffered window. +const ( + minRowBufferSize = 24 + maxRowBufferSize = 192 +) type bufferedRowReader struct { rows RowReader off int32 end int32 - buf [24]Row + full bool // the last read filled the buffer completely + buf []Row } func (r *bufferedRowReader) empty() bool { @@ -757,7 +972,17 @@ func (r *bufferedRowReader) head() Row { } func (r *bufferedRowReader) next() bool { - r.off++ + return r.advance(1) +} + +// window returns the buffered rows that have not been consumed yet. +func (r *bufferedRowReader) window() []Row { + return r.buf[r.off:r.end] +} + +// advance consumes n buffered rows and reports whether more remain buffered. +func (r *bufferedRowReader) advance(n int32) bool { + r.off += n hasNext := r.off < r.end if !hasNext { // We need to read more rows, however it is unsafe to do so here because we haven't @@ -769,14 +994,55 @@ func (r *bufferedRowReader) next() bool { } func (r *bufferedRowReader) read() error { + if r.buf == nil { + r.buf = make([]Row, minRowBufferSize) + } else if r.full && r.off == 0 && r.end == 0 && len(r.buf) < maxRowBufferSize { + // The reader keeps filling the buffer completely: grow it to amortize + // refills and extend the bulk run emission paths. The previous rows + // are carried over so their backing arrays keep being reused. + buf := make([]Row, min(2*len(r.buf), maxRowBufferSize)) + copy(buf, r.buf) + r.buf = buf + } n, err := r.rows.ReadRows(r.buf[r.end:]) if err != nil && n == 0 { return err } r.end += int32(n) + r.full = r.end == int32(len(r.buf)) return nil } +// runLength returns the number of leading rows of window whose comparison +// against bound is at most max (0 to include ties, -1 to exclude them). The +// window must be sorted by the same comparison function, so the qualifying +// rows form a prefix; the function checks the first and last rows to settle +// empty and complete runs with a single comparison, then gallops with a +// binary search refinement, costing O(log n) comparisons instead of the O(n) +// of a linear scan. +func runLength(window []Row, bound Row, compare func(Row, Row) int, max int) int { + if len(window) == 0 || compare(window[0], bound) > max { + return 0 + } + if compare(window[len(window)-1], bound) <= max { + return len(window) + } + lo, hi := 0, 1 + for hi < len(window) && compare(window[hi], bound) <= max { + lo = hi + hi *= 2 + } + hi = min(hi, len(window)) + for lo+1 < hi { + if mid := int(uint(lo+hi) >> 1); compare(window[mid], bound) <= max { + lo = mid + } else { + hi = mid + } + } + return hi +} + var ( _ RowReaderWithSchema = (*mergedRowGroupRows)(nil) ) @@ -878,12 +1144,12 @@ func mergeTwoNodes(a, b Node) Node { merged = group if logicalType := b.Type().LogicalType(); logicalType != nil { - switch { - case logicalType.List != nil: + switch logicalType.Value.(type) { + case *format.ListType: merged = &listNode{group} - case logicalType.Map != nil: + case *format.MapType: merged = &mapNode{group} - case logicalType.Variant != nil: + case *format.VariantType: merged = &variantNode{group} } } diff --git a/vendor/github.com/parquet-go/parquet-go/merge_refine.go b/vendor/github.com/parquet-go/parquet-go/merge_refine.go new file mode 100644 index 00000000000..9bb1a1b7959 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/merge_refine.go @@ -0,0 +1,365 @@ +package parquet + +import ( + "slices" + "sort" +) + +// This file refines overlapping merge segments: when sorted row groups overlap +// only in part of their key ranges (e.g. time-ordered files overlapping around +// their boundaries), the stretches of key space covered by a single row group +// do not need to be merged row by row — they can be sliced off as row-range +// views (see row_range.go) and read or written through the column-oriented +// paths, leaving only the truly overlapping stretches for the loser-tree merge. +// +// Cuts are only ever applied to the row group that is alone in a stretch of +// key space (a "lone stretch"), and are validated against the exact +// row-group-level min/max keys of the other row groups. This avoids a subtle +// hazard: page-granular cuts of different row groups at a common boundary key +// land at different actual keys, which could reorder rows across regions. +// Cutting only the lone row group — with the rows of its boundary pages pushed +// into the adjacent merged region — guarantees that every row of a region +// compares at most equal to every row of the following regions, so +// concatenating the regions preserves sorted order. Ties across row groups +// always land in merged regions, whose loser-tree resolves them. +// +// The refined plan is equivalent to the full merge as a sorted sequence: the +// same multiset of rows, with each input row group's rows in their original +// relative order. The interleaving of rows with equal sort keys across row +// groups may differ from the unrefined merge (as it already does between merge +// arities), which is why refinement is not applied when dropping duplicated +// rows: which physical row of an equal-key run survives deduplication depends +// on that interleaving. + +// disableMergeRefinement forces overlapping segments through the unrefined +// merge. It exists only so tests and benchmarks can compare refined plans +// against the reference behavior. +var disableMergeRefinement bool + +// minStreamedRegionRows is the minimum number of rows a lone stretch must span +// to be worth slicing out of the merge. Below this, the overhead of an extra +// segment (a seek per column, a row group boundary when writing) outweighs the +// merge work saved, so the stretch stays in the adjacent merged region. +const minStreamedRegionRows = 1024 + +// refineTarget describes one row group of an overlapping segment for the +// planner. minRow and maxRow are the exact bounds of the sorting columns, as +// computed by rowGroupRangeOfSortedColumns. cutAbove and cutBelow are +// conservative page-granular row lookups on the first sorting column; either +// may be nil when the row group does not support them, in which case the row +// group is never sliced. +type refineTarget struct { + rowGroup RowGroup + minRow Row + maxRow Row + numRows int64 + + // cutAbove returns the smallest row index such that every row at or after + // it has a sort key strictly greater than key, rounded down to a page + // boundary of the first sorting column (the rows of the page containing + // key stay below the cut). + cutAbove func(key Row) int64 + + // cutBelow returns the largest row index such that every row before it + // has a sort key strictly less than key, rounded down to a page boundary + // of the first sorting column (the rows of the page containing key stay + // at or above the cut). + cutBelow func(key Row) int64 +} + +// newRefineTargets builds the planner inputs for one overlapping segment. It +// returns nil when the segment cannot be refined at all (bounds unavailable). +// Individual row groups whose page index does not support cut lookups get nil +// cut functions and are never sliced, but still participate in the plan. +func newRefineTargets(segment []rowGroupRange, schema *Schema, sorting []SortingColumn) []refineTarget { + if len(sorting) == 0 { + return nil + } + + // Locate the leaf column of the first sorting column; cuts are computed on + // its page bounds only. (Strict inequality on the first sort column implies + // strict inequality on the full sorting tuple, so cuts remain conservative + // for multi-column sorts.) + sortingColumnIndex := -1 + sortingColumnPath := columnPath(sorting[0].Path()) + for columnIndex, path := range schema.Columns() { + if slices.Equal(path, sortingColumnPath) { + sortingColumnIndex = columnIndex + break + } + } + if sortingColumnIndex < 0 { + return nil + } + descending := sorting[0].Descending() + + targets := make([]refineTarget, len(segment)) + for i, rr := range segment { + if rr.minRow == nil || rr.maxRow == nil { + return nil + } + targets[i] = refineTarget{ + rowGroup: rr.rowGroup, + minRow: rr.minRow, + maxRow: rr.maxRow, + numRows: rr.rowGroup.NumRows(), + } + targets[i].cutAbove, targets[i].cutBelow = newCutLookups(rr.rowGroup, sortingColumnIndex, descending) + } + return targets +} + +// newCutLookups builds the page-granular row cut lookups for the sorting leaf +// column of a row group, or (nil, nil) when the page index does not support +// them (missing column or offset index, or null pages in the sorting column, +// whose position in the sort order is not knowable from the index). +func newCutLookups(rg RowGroup, columnIndex int, descending bool) (cutAbove, cutBelow func(Row) int64) { + chunks := rg.ColumnChunks() + if columnIndex >= len(chunks) { + return nil, nil + } + chunk := chunks[columnIndex] + columnType := chunk.Type() + + ci, err := chunk.ColumnIndex() + if err != nil || ci == nil || ci.NumPages() == 0 { + return nil, nil + } + oi, err := chunk.OffsetIndex() + if err != nil || oi == nil || oi.NumPages() != ci.NumPages() { + return nil, nil + } + numPages := ci.NumPages() + for p := range numPages { + if ci.NullPage(p) { + return nil, nil + } + } + numRows := rg.NumRows() + + // In-order page bounds: the first value of a page in sort order is its + // minimum for ascending sorts and its maximum for descending sorts. + earliest := ci.MinValue + latest := ci.MaxValue + if descending { + earliest, latest = latest, earliest + } + // orderCompare orders values by the sort direction. + orderCompare := func(a, b Value) int { + return compareValues(a, b, columnType, descending) + } + pageEnd := func(p int) int64 { + if p+1 < numPages { + return oi.FirstRowIndex(p + 1) + } + return numRows + } + + // cutAbove: end of the last page whose earliest value is at or before key + // (every row from the cut on belongs to a later page, whose values are all + // strictly after key). + cutAbove = func(key Row) int64 { + kv := key[columnIndex] + if kv.IsNull() { + return numRows // no safe cut: the slice comes out empty + } + p := sort.Search(numPages, func(p int) bool { + return orderCompare(earliest(p), kv) > 0 + }) + if p == 0 { + return 0 + } + return pageEnd(p - 1) + } + + // cutBelow: start of the first page whose latest value is at or after key + // (every row before the cut belongs to an earlier page, whose values are + // all strictly before key). + cutBelow = func(key Row) int64 { + kv := key[columnIndex] + if kv.IsNull() { + return 0 // no safe cut: the slice comes out empty + } + p := sort.Search(numPages, func(p int) bool { + return orderCompare(latest(p), kv) >= 0 + }) + if p == numPages { + return numRows + } + return oi.FirstRowIndex(p) + } + + return cutAbove, cutBelow +} + +// refineSegment plans the refinement of one overlapping segment, returning the +// refined sub-segments: an alternation of merged regions (built with +// makeMerged from two or more participants) and single-source row groups or +// range views. It returns nil when no refinement applies, in which case the +// caller merges the whole segment as usual. +func refineSegment(targets []refineTarget, compare func(Row, Row) int, makeMerged func([]RowGroup) RowGroup) []RowGroup { + if len(targets) < 2 { + return nil + } + + type event struct { + key Row + start bool + index int + } + + events := make([]event, 0, 2*len(targets)) + for i := range targets { + events = append(events, + event{key: targets[i].minRow, start: true, index: i}, + event{key: targets[i].maxRow, start: false, index: i}, + ) + } + slices.SortStableFunc(events, func(a, b event) int { + if c := compare(a.key, b.key); c != 0 { + return c + } + // Starts sort before ends so that touching ranges (a max equal to + // another's min) produce a merged region for the shared key instead + // of being falsely torn apart. + switch { + case a.start && !b.start: + return -1 + case !a.start && b.start: + return +1 + default: + return 0 + } + }) + + // regionPart tracks the target index of each participant so merged + // regions can list participants deterministically in minRow order. + type regionPart struct { + index int + part RowGroup + } + + var ( + plan []RowGroup + region []regionPart // participants of the merged region being built + cursors map[int]int64 // rows of each target consumed by earlier regions + active map[int]struct{} // targets whose key interval covers the sweep position + sliced bool // whether any lone slice was emitted + + // pendingLone is set while the sweep is inside a stretch of key space + // covered by a single target; leftK is the exclusive lower bound of + // the stretch (nil at the start of the segment). + pendingLone = -1 + pendingLeftK Row + ) + cursors = make(map[int]int64, len(targets)) + active = make(map[int]struct{}, len(targets)) + + remainder := func(i int) (RowGroup, bool) { + t := &targets[i] + off := cursors[i] + if off >= t.numRows { + return nil, false + } + cursors[i] = t.numRows + if off == 0 { + return t.rowGroup, true + } + return newRowRangeRowGroup(t.rowGroup, off, t.numRows-off), true + } + + closeRegion := func() { + switch len(region) { + case 0: + case 1: + plan = append(plan, region[0].part) + default: + slices.SortStableFunc(region, func(a, b regionPart) int { return a.index - b.index }) + parts := make([]RowGroup, len(region)) + for i, p := range region { + parts[i] = p.part + } + plan = append(plan, makeMerged(parts)) + } + region = nil + } + + // resolveLone ends the pending lone stretch, bounded above by rightK (nil + // at the end of the segment). When the stretch is sliceable and large + // enough, the region below it is closed and the slice emitted; otherwise + // the stretch simply remains part of the current region. + resolveLone := func(rightK Row) { + i := pendingLone + pendingLone = -1 + t := &targets[i] + if t.cutAbove == nil || t.cutBelow == nil { + return + } + off := int64(0) + if pendingLeftK != nil { + off = t.cutAbove(pendingLeftK) + } + end := t.numRows + if rightK != nil { + end = t.cutBelow(rightK) + } + off = max(off, cursors[i]) + end = min(end, t.numRows) + if end-off < minStreamedRegionRows { + return + } + + // Close the region below the slice: every participant contributes its + // remaining rows (their key intervals ended inside the region), and + // the lone target contributes its rows before the slice. + if off > cursors[i] { + region = append(region, regionPart{index: i, part: newRowRangeRowGroup(t.rowGroup, cursors[i], off-cursors[i])}) + } + closeRegion() + + if off == 0 && end == t.numRows { + plan = append(plan, t.rowGroup) + } else { + plan = append(plan, newRowRangeRowGroup(t.rowGroup, off, end-off)) + } + cursors[i] = end + sliced = true + } + + for _, ev := range events { + if ev.start { + if pendingLone >= 0 { + resolveLone(ev.key) + } + active[ev.index] = struct{}{} + if len(active) == 1 { + // First target of the segment: it is alone until the next + // start event. + pendingLone = ev.index + pendingLeftK = nil + } + } else { + // If the ending target is the pending lone one, its stretch runs + // to the end of its rows: resolve before consuming the remainder. + if ev.index == pendingLone { + resolveLone(nil) + } + delete(active, ev.index) + if r, ok := remainder(ev.index); ok { + region = append(region, regionPart{index: ev.index, part: r}) + } + if len(active) == 1 && pendingLone < 0 { + for lone := range active { + pendingLone = lone + } + pendingLeftK = ev.key + } + } + } + closeRegion() + + if !sliced { + return nil + } + return plan +} diff --git a/vendor/github.com/parquet-go/parquet-go/multi_row_group.go b/vendor/github.com/parquet-go/parquet-go/multi_row_group.go index 65bf920d0dd..084b3d4d160 100644 --- a/vendor/github.com/parquet-go/parquet-go/multi_row_group.go +++ b/vendor/github.com/parquet-go/parquet-go/multi_row_group.go @@ -126,6 +126,11 @@ func (m *multiRowGroup) Schema() *Schema { return m.schema } func (m *multiRowGroup) Rows() Rows { return NewRowGroupRowReader(m) } +// rowGroupSegments implements orderedRowGroupSegments: a multiRowGroup is the +// in-order concatenation of its row groups, so each may be written independently +// while preserving row order. +func (m *multiRowGroup) rowGroupSegments() []RowGroup { return m.rowGroups } + type multiColumnChunk struct { rowGroup *multiRowGroup column int @@ -213,10 +218,20 @@ func (c *multiColumnChunk) OffsetIndex() (OffsetIndex, error) { offsets[i+1] = offsets[i] + index.NumPages() } - // Build cumulative row offsets for each chunk + // Build cumulative row offsets for each chunk. Use rowCounts when + // available (flattened chunks), otherwise fall back to rowGroups; the + // chunk count can exceed len(rowGroups) when merging already-merged + // row groups. + rowCounts := c.rowCounts rowOffsets := make([]int64, len(c.chunks)+1) for i := range c.chunks { - rowOffsets[i+1] = rowOffsets[i] + c.rowGroup.rowGroups[i].NumRows() + var numRows int64 + if i < len(rowCounts) { + numRows = rowCounts[i] + } else { + numRows = c.rowGroup.rowGroups[i].NumRows() + } + rowOffsets[i+1] = rowOffsets[i] + numRows } return &multiOffsetIndex{ diff --git a/vendor/github.com/parquet-go/parquet-go/node.go b/vendor/github.com/parquet-go/parquet-go/node.go index e92489f3e8e..cf2cc79a595 100644 --- a/vendor/github.com/parquet-go/parquet-go/node.go +++ b/vendor/github.com/parquet-go/parquet-go/node.go @@ -475,17 +475,17 @@ func isValidInGoIdent(r rune) bool { func isList(node Node) bool { logicalType := node.Type().LogicalType() - return logicalType != nil && logicalType.List != nil + return logicalTypeIs[*format.ListType](logicalType) } func isMap(node Node) bool { logicalType := node.Type().LogicalType() - return logicalType != nil && logicalType.Map != nil + return logicalTypeIs[*format.MapType](logicalType) } func isVariant(node Node) bool { logicalType := node.Type().LogicalType() - return logicalType != nil && logicalType.Variant != nil + return logicalTypeIs[*format.VariantType](logicalType) } func numLeafColumnsOf(node Node) uint16 { diff --git a/vendor/github.com/parquet-go/parquet-go/page_be128.go b/vendor/github.com/parquet-go/parquet-go/page_be128.go index 30f62d0f924..d5d6ac6470c 100644 --- a/vendor/github.com/parquet-go/parquet-go/page_be128.go +++ b/vendor/github.com/parquet-go/parquet-go/page_be128.go @@ -3,7 +3,9 @@ package parquet import ( "io" + "github.com/google/uuid" "github.com/parquet-go/parquet-go/encoding" + "github.com/parquet-go/parquet-go/internal/unsafecast" ) type be128Page struct { @@ -97,3 +99,32 @@ func (r *be128PageValues) ReadValues(values []Value) (n int, err error) { } return n, err } + +func (r *be128PageValues) ReadBE128s(values [][16]byte) (n int, err error) { + n = copy(values, r.page.values[r.offset:]) + r.offset += n + if r.offset == len(r.page.values) { + err = io.EOF + } + return n, err +} + +func (col *be128ColumnBuffer) WriteBE128s(values [][16]byte) (int, error) { + col.values = append(col.values, values...) + return len(values), nil +} + +func (r *be128PageValues) ReadUUIDs(values []uuid.UUID) (n int, err error) { + pageValues := unsafecast.Slice[uuid.UUID](r.page.values) + n = copy(values, pageValues[r.offset:]) + r.offset += n + if r.offset == len(pageValues) { + err = io.EOF + } + return n, err +} + +func (col *be128ColumnBuffer) WriteUUIDs(values []uuid.UUID) (int, error) { + col.values = append(col.values, unsafecast.Slice[[16]byte](values)...) + return len(values), nil +} diff --git a/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.go b/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.go index 9cb513b407c..95d250cc414 100644 --- a/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.go +++ b/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.go @@ -38,7 +38,12 @@ package parquet // to running less instructions per loop. The performance starts to equalize // around 256KiB, and degrade beyond 1MiB, so we use this threshold to determine // which approach to prefer. -const combinedBoundsThreshold = 1 * 1024 * 1024 +const ( + combinedBoundsThreshold = 1 * 1024 * 1024 + // ColumnWriter fills pages to 98% of DefaultPageBufferSize. This is the + // first whole INT64 value count that reaches that default page target. + combinedBoundsInt64Threshold = (DefaultPageBufferSize*98/100 + 7) / 8 +) //go:noescape func combinedBoundsBool(data []bool) (min, max bool) @@ -49,6 +54,9 @@ func combinedBoundsInt32(data []int32) (min, max int32) //go:noescape func combinedBoundsInt64(data []int64) (min, max int64) +//go:noescape +func combinedBoundsInt64AVX512(data []int64) (min, max int64) + //go:noescape func combinedBoundsUint32(data []uint32) (min, max uint32) @@ -74,8 +82,13 @@ func boundsInt32(data []int32) (min, max int32) { } func boundsInt64(data []int64) (min, max int64) { - if 8*len(data) >= combinedBoundsThreshold { - return combinedBoundsInt64(data) + if len(data) >= combinedBoundsInt64Threshold { + if hasAVX512VL && 8*len(data) < combinedBoundsThreshold { + return combinedBoundsInt64AVX512(data) + } + if 8*len(data) >= combinedBoundsThreshold { + return combinedBoundsInt64(data) + } } min = minInt64(data) max = maxInt64(data) diff --git a/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.s b/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.s index c6d172a5e1a..bdadc5a26bc 100644 --- a/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.s +++ b/vendor/github.com/parquet-go/parquet-go/page_bounds_amd64.s @@ -212,6 +212,79 @@ done: MOVQ R9, max+32(FP) RET +// func combinedBoundsInt64AVX512(data []int64) (min, max int64) +TEXT ·combinedBoundsInt64AVX512(SB), NOSPLIT, $-40 + MOVQ data_base+0(FP), AX + MOVQ data_len+8(FP), CX + XORQ SI, SI + + MOVQ CX, DI + SHRQ $5, DI + SHLQ $5, DI + VPBROADCASTQ (AX), Z0 + VPBROADCASTQ (AX), Z1 + VPBROADCASTQ (AX), Z2 + VPBROADCASTQ (AX), Z3 +loop32: + VMOVDQU64 (AX)(SI*8), Z4 + VMOVDQU64 64(AX)(SI*8), Z5 + VMOVDQU64 128(AX)(SI*8), Z6 + VMOVDQU64 192(AX)(SI*8), Z7 + VPMINSQ Z4, Z0, Z0 + VPMAXSQ Z4, Z1, Z1 + VPMINSQ Z5, Z2, Z2 + VPMAXSQ Z5, Z3, Z3 + VPMINSQ Z6, Z0, Z0 + VPMAXSQ Z6, Z1, Z1 + VPMINSQ Z7, Z2, Z2 + VPMAXSQ Z7, Z3, Z3 + ADDQ $32, SI + CMPQ SI, DI + JNE loop32 + + VPMINSQ Z2, Z0, Z0 + VPMAXSQ Z3, Z1, Z1 + + VMOVDQU32 swap32+0(SB), Z2 + VMOVDQU32 swap32+0(SB), Z3 + VPERMI2D Z0, Z0, Z2 + VPERMI2D Z1, Z1, Z3 + VPMINSQ Y2, Y0, Y0 + VPMAXSQ Y3, Y1, Y1 + + VMOVDQU32 swap32+32(SB), Y2 + VMOVDQU32 swap32+32(SB), Y3 + VPERMI2D Y0, Y0, Y2 + VPERMI2D Y1, Y1, Y3 + VPMINSQ X2, X0, X0 + VPMAXSQ X3, X1, X1 + + VMOVDQU32 swap32+48(SB), X2 + VMOVDQU32 swap32+48(SB), X3 + VPERMI2D X0, X0, X2 + VPERMI2D X1, X1, X3 + VPMINSQ X2, X0, X0 + VPMAXSQ X3, X1, X1 + VZEROUPPER + + MOVQ X0, R8 + MOVQ X1, R9 + CMPQ SI, CX + JE done +loop: + MOVQ (AX)(SI*8), DX + CMPQ DX, R8 + CMOVQLT DX, R8 + CMPQ DX, R9 + CMOVQGT DX, R9 + INCQ SI + CMPQ SI, CX + JNE loop +done: + MOVQ R8, min+24(FP) + MOVQ R9, max+32(FP) + RET + // func combinedBoundsUint32(data []uint32) (min, max uint32) TEXT ·combinedBoundsUint32(SB), NOSPLIT, $-32 MOVQ data_base+0(FP), AX diff --git a/vendor/github.com/parquet-go/parquet-go/reader.go b/vendor/github.com/parquet-go/parquet-go/reader.go index 29c020892f4..21d54965816 100644 --- a/vendor/github.com/parquet-go/parquet-go/reader.go +++ b/vendor/github.com/parquet-go/parquet-go/reader.go @@ -662,6 +662,9 @@ func makeFileRowGroups(file *File, columns []*Column) ([]FileRowGroup, error) { if err := validateRowGroupOrdinals(rowGroups); err != nil { return nil, err } + if err := validateRowCounts(file.metadata.NumRows, rowGroups); err != nil { + return nil, err + } fileRowGroups := make([]FileRowGroup, len(rowGroups)) for i := range fileRowGroups { @@ -712,3 +715,17 @@ func validateRowGroupOrdinals(rowGroups []format.RowGroup) error { } return nil } + +// validateRowCounts rejects negative row counts in the file footer and row groups +// prevent panics later on that would reach for an invalid slice index +func validateRowCounts(fileNumRows int64, rowGroups []format.RowGroup) error { + if fileNumRows < 0 { + return fmt.Errorf("invalid file metadata: num_rows=%d is negative", fileNumRows) + } + for i := range rowGroups { + if n := rowGroups[i].NumRows; n < 0 { + return fmt.Errorf("invalid file metadata: row group %d num_rows=%d is negative", i, n) + } + } + return nil +} diff --git a/vendor/github.com/parquet-go/parquet-go/row.go b/vendor/github.com/parquet-go/parquet-go/row.go index 190480832c4..c1010525433 100644 --- a/vendor/github.com/parquet-go/parquet-go/row.go +++ b/vendor/github.com/parquet-go/parquet-go/row.go @@ -666,7 +666,8 @@ func reconstructFuncOfRepeated(columnIndex uint16, node Node) (uint16, reconstru return nil } - values := make([][]Value, len(columns)) + b := acquireValuesSliceBuffer() + values := b.reserve(len(columns)) column := columns[0] n := 0 @@ -701,6 +702,7 @@ func reconstructFuncOfRepeated(columnIndex uint16, node Node) (uint16, reconstru } if err := reconstruct(value.Index(i), levels, values); err != nil { + b.release() return err } @@ -711,6 +713,7 @@ func reconstructFuncOfRepeated(columnIndex uint16, node Node) (uint16, reconstru levels.repetitionLevel = levels.repetitionDepth } + b.release() return nil } } @@ -761,7 +764,8 @@ func reconstructFuncOfMap(columnIndex uint16, node Node) (uint16, reconstructFun return nil } - values := make([][]Value, len(columns)) + b := acquireValuesSliceBuffer() + values := b.reserve(len(columns)) column := columns[0] t := value.Type() if t.Kind() == reflect.Interface { @@ -808,6 +812,7 @@ func reconstructFuncOfMap(columnIndex uint16, node Node) (uint16, reconstructFun } if err := reconstruct(elem, levels, values); err != nil { + b.release() return err } @@ -832,6 +837,7 @@ func reconstructFuncOfMap(columnIndex uint16, node Node) (uint16, reconstructFun levels.repetitionLevel = levels.repetitionDepth } + b.release() return nil } } diff --git a/vendor/github.com/parquet-go/parquet-go/row_range.go b/vendor/github.com/parquet-go/parquet-go/row_range.go new file mode 100644 index 00000000000..e70fa490cb8 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/row_range.go @@ -0,0 +1,176 @@ +package parquet + +import ( + "fmt" + "io" +) + +// This file implements row-range views of row groups: a rowRangeRowGroup +// presents rows [off, off+length) of a base row group, with column chunks that +// seek to the range start and stop after the range's row count. Range views are +// produced by the merge planner (see merge_refine.go) to slice partially +// overlapping row groups into disjoint stretches — which stream through the +// writer's column-oriented fast paths — and truly overlapping stretches, which +// go through the loser-tree merge. + +// rowRangeRowGroup is a view of rows [off, off+length) of a base row group. +type rowRangeRowGroup struct { + base RowGroup + off int64 + length int64 + chunks []ColumnChunk +} + +// newRowRangeRowGroup returns a view of rows [off, off+length) of base. The +// caller is responsible for bounds: 0 <= off, off+length <= base.NumRows(), +// length > 0, and for not constructing views that span the whole base row +// group (use the base row group directly instead, which preserves its +// eligibility for the verbatim copy fast path). +func newRowRangeRowGroup(base RowGroup, off, length int64) *rowRangeRowGroup { + baseChunks := base.ColumnChunks() + rg := &rowRangeRowGroup{ + base: base, + off: off, + length: length, + chunks: make([]ColumnChunk, len(baseChunks)), + } + + // The value count of a row range is only knowable from metadata when each + // row holds exactly one value, i.e. for non-repeated columns. + repeated := make([]bool, len(baseChunks)) + if schema := base.Schema(); schema != nil { + forEachLeafColumnOf(schema, func(leaf leafColumn) { + if int(leaf.columnIndex) < len(repeated) { + repeated[leaf.columnIndex] = leaf.maxRepetitionLevel > 0 + } + }) + } + + for i, chunk := range baseChunks { + rg.chunks[i] = &rangeColumnChunk{ + base: chunk, + off: off, + length: length, + exact: !repeated[i], + } + } + return rg +} + +func (rg *rowRangeRowGroup) NumRows() int64 { return rg.length } +func (rg *rowRangeRowGroup) ColumnChunks() []ColumnChunk { return rg.chunks } +func (rg *rowRangeRowGroup) Schema() *Schema { return rg.base.Schema() } +func (rg *rowRangeRowGroup) SortingColumns() []SortingColumn { return rg.base.SortingColumns() } +func (rg *rowRangeRowGroup) Rows() Rows { return NewRowGroupRowReader(rg) } + +// chunkTransparentRowGroup marks range views as safe for the chunk-level write +// fast paths: Rows() is NewRowGroupRowReader over the range chunks, so reading +// the chunks in order is the definition of its row semantics. +func (rg *rowRangeRowGroup) chunkTransparentRowGroup() {} + +// rangeColumnChunk presents rows [off, off+length) of a base column chunk. +type rangeColumnChunk struct { + base ColumnChunk + off int64 + length int64 + exact bool // NumValues is exact (non-repeated column) +} + +func (c *rangeColumnChunk) Type() Type { return c.base.Type() } +func (c *rangeColumnChunk) Column() int { return c.base.Column() } + +func (c *rangeColumnChunk) Pages() Pages { + pages := c.base.Pages() + if err := pages.SeekToRow(c.off); err != nil { + pages.Close() + return &errorPages{err: fmt.Errorf("seeking to start of row range at %d: %w", c.off, err)} + } + return &rangePages{base: pages, off: c.off, length: c.length, remaining: c.length} +} + +// The page index and bloom filter of the base chunk describe all of its rows; +// exposing them for a sub-range would let consumers draw wrong conclusions +// (e.g. bounds that rows in the range never reach), so range views report them +// as absent. +func (c *rangeColumnChunk) ColumnIndex() (ColumnIndex, error) { return nil, ErrMissingColumnIndex } +func (c *rangeColumnChunk) OffsetIndex() (OffsetIndex, error) { return nil, ErrMissingOffsetIndex } +func (c *rangeColumnChunk) BloomFilter() BloomFilter { return nil } + +// NumValues returns the number of values in the row range. For non-repeated +// columns this is exactly the row count; for repeated columns the count is not +// knowable from metadata and the base chunk's total is returned as an upper +// bound (see exactNumValues). +func (c *rangeColumnChunk) NumValues() int64 { + if c.exact { + return c.length + } + return c.base.NumValues() +} + +// exactNumValues reports whether NumValues is exact rather than an upper +// bound. Consumers that size resources from NumValues (bloom filters) must +// check this and fall back when the count is inexact. +func (c *rangeColumnChunk) exactNumValues() bool { return c.exact } + +// rangePages limits a Pages stream positioned inside its base column chunk to +// the rows [off, off+length) of the base, slicing the final page when the +// range ends mid-page. +type rangePages struct { + base Pages + off int64 // start of the range, in base row indexes + length int64 + remaining int64 +} + +func (p *rangePages) ReadPage() (Page, error) { + if p.remaining <= 0 { + return nil, io.EOF + } + page, err := p.base.ReadPage() + if err != nil { + return nil, err + } + numRows := page.NumRows() + if numRows <= p.remaining { + p.remaining -= numRows + return page, nil + } + // The range ends inside this page. The slice shares the page's underlying + // buffers without incrementing their reference counts, so ownership of the + // page transfers to the caller through the slice: the caller's Release of + // the slice releases the shared buffers. + tail := page.Slice(0, p.remaining) + p.remaining = 0 + return tail, nil +} + +// SeekToRow positions the stream on the row at index rowIndex within the +// range (i.e. relative to the start of the range, not of the base chunk). +func (p *rangePages) SeekToRow(rowIndex int64) error { + if rowIndex < 0 || rowIndex > p.length { + return fmt.Errorf("SeekToRow: row index %d out of range of row range view of %d rows", rowIndex, p.length) + } + if err := p.base.SeekToRow(p.off + rowIndex); err != nil { + return err + } + p.remaining = p.length - rowIndex + return nil +} + +func (p *rangePages) Close() error { + p.remaining = 0 + return p.base.Close() +} + +// errorPages is a Pages implementation which returns an error on every read. +type errorPages struct{ err error } + +func (p *errorPages) ReadPage() (Page, error) { return nil, p.err } +func (p *errorPages) SeekToRow(int64) error { return p.err } +func (p *errorPages) Close() error { return nil } + +var ( + _ RowGroup = (*rowRangeRowGroup)(nil) + _ ColumnChunk = (*rangeColumnChunk)(nil) + _ Pages = (*rangePages)(nil) +) diff --git a/vendor/github.com/parquet-go/parquet-go/row_variant.go b/vendor/github.com/parquet-go/parquet-go/row_variant.go index 3fea8b3548f..9914963edf5 100644 --- a/vendor/github.com/parquet-go/parquet-go/row_variant.go +++ b/vendor/github.com/parquet-go/parquet-go/row_variant.go @@ -1,13 +1,10 @@ package parquet import ( - "encoding/binary" "fmt" - "maps" "reflect" "unsafe" - "github.com/google/uuid" "github.com/parquet-go/parquet-go/variant" ) @@ -122,82 +119,76 @@ func deconstructFuncOfUnshreddedVariant(columnIndex uint16, node Node) (uint16, } } -// deconstructFuncOfShreddedVariant handles the 3-field shredded variant: -// metadata (required), value (optional), typed_value (optional). -// -// When the Go value matches the typed_value schema, the value is written to the -// typed_value columns and the value column is set to null. Otherwise, the variant- -// encoded bytes are written to the value column and typed_value columns are null. +// deconstructFuncOfShreddedVariant writes Go values into a shredded variant +// group per the Variant Shredding specification (see +// variant_shredded_write.go): values matching the typed_value schema are +// shredded into typed columns; everything else is encoded as plain variant +// values into the appropriate value column, sharing the row's metadata +// dictionary. // //go:noinline func deconstructFuncOfShreddedVariant(columnIndex uint16, node Node) (uint16, deconstructFunc) { - // Fields are sorted alphabetically: metadata, typed_value, value - var metadataColumnIndex, valueColumnIndex, typedValueStartColumn uint16 - var typedValueLeafCount uint16 - var typedValueNode Node - - col := columnIndex - for _, f := range node.Fields() { - n := numLeafColumnsOf(f) - switch f.Name() { - case "metadata": - metadataColumnIndex = col - col += n - case "typed_value": - typedValueStartColumn = col - typedValueNode = f - typedValueLeafCount = n - col += n - case "value": - valueColumnIndex = col - col += n + // Schemas that cannot be written to (e.g. missing the metadata column) + // may still be read from; fail when a row is written, not at build time. + group, err := buildShreddedVariantGroup(node, 0, 0, 0) + if err == nil && group.metadataCol < 0 { + err = fmt.Errorf("variant: shredded variant group has no metadata field") + } + if err != nil { + numCols := numLeafColumnsOf(node) + return columnIndex + numCols, func([][]Value, columnLevels, reflect.Value) { + panic(fmt.Sprintf("invalid shredded variant schema: %v", err)) } } - nextColumnIndex := col - - // Determine the shredded type structure - typedInner := Required(typedValueNode) - matcher := buildShreddedMatcher(typedInner) + nextColumnIndex := columnIndex + uint16(group.numCols) return nextColumnIndex, func(columns [][]Value, levels columnLevels, value reflect.Value) { - metaIdx := ^metadataColumnIndex - valIdx := ^valueColumnIndex + // An invalid value means an enclosing optional/repeated wrapper is + // null for this row: the whole variant group is null. + if !value.IsValid() { + appendShreddedNulls(columns, columnIndex, 0, group.numCols, levels.definitionLevel, levels.repetitionLevel) + return + } + + // Convert the Go value to a variant value tree. Raw variant structs + // (Metadata/Value []byte fields) are decoded so their contents can + // be shredded like any other value. + var v variant.Value + if metaBytes, valBytes, ok := extractRawVariantStruct(value); ok { + m, err := variant.DecodeMetadata(metaBytes) + if err != nil { + panic(fmt.Sprintf("variant metadata: %v", err)) + } + if v, err = variant.Decode(m, valBytes); err != nil { + panic(fmt.Sprintf("variant decode: %v", err)) + } + } else { + var err error + if v, err = variant.ValueOf(extractGoValue(value)); err != nil { + panic(fmt.Sprintf("variant marshal: %v", err)) + } + } - metadata, val := variantMarshalOrNull(value) + // The row's metadata dictionary contains every object field name of + // the value, shredded or not. + var b variant.MetadataBuilder + addVariantFieldNames(&b, v) + + group.write(columns, columnIndex, &b, v, true, shredLevels{ + baseDef: int(levels.definitionLevel), + baseRep: int(levels.repetitionDepth), + rep: levels.repetitionLevel, + }) - // Always write metadata + // The metadata column is written last so the dictionary includes + // the field IDs assigned while encoding residual values. + _, metadata := b.Build() + metaCol := columnIndex + uint16(group.metadataCol) metaValue := makeValueByteArray(ByteArray, unsafe.SliceData(metadata), len(metadata)) metaValue.repetitionLevel = levels.repetitionLevel metaValue.definitionLevel = levels.definitionLevel - metaValue.columnIndex = metaIdx - columns[metadataColumnIndex] = append(columns[metadataColumnIndex], metaValue) - - // Try to shred the value - goVal := extractGoValue(value) - if goVal != nil && matcher.canShred(goVal) { - // Write null to value column (optional, def level not incremented) - columns[valueColumnIndex] = append(columns[valueColumnIndex], Value{ - repetitionLevel: levels.repetitionLevel, - definitionLevel: levels.definitionLevel, - columnIndex: valIdx, - }) - // Write typed value (increment def level for optional typed_value wrapper) - typedLevels := levels - typedLevels.definitionLevel++ - matcher.shred(columns, typedLevels, typedValueStartColumn, goVal) - } else { - // Write variant bytes to value column (increment def level for optional wrapper) - valueLevels := levels - valueLevels.definitionLevel++ - valValue := makeValueByteArray(ByteArray, unsafe.SliceData(val), len(val)) - valValue.repetitionLevel = valueLevels.repetitionLevel - valValue.definitionLevel = valueLevels.definitionLevel - valValue.columnIndex = valIdx - columns[valueColumnIndex] = append(columns[valueColumnIndex], valValue) - - // Write null to all typed_value columns - writeNullLeaves(columns, typedValueStartColumn, typedValueStartColumn+typedValueLeafCount, levels) - } + metaValue.columnIndex = ^metaCol + columns[metaCol] = append(columns[metaCol], metaValue) } } @@ -217,366 +208,6 @@ func extractGoValue(value reflect.Value) any { return v.Interface() } -// writeNullLeaves writes null values to all leaf columns in the range [start, end). -func writeNullLeaves(columns [][]Value, start, end uint16, levels columnLevels) { - for col := start; col < end; col++ { - columns[col] = append(columns[col], Value{ - repetitionLevel: levels.repetitionLevel, - definitionLevel: levels.definitionLevel, - columnIndex: ^col, - }) - } -} - -// shreddedMatcher determines if a Go value can be shredded into a typed_value -// column and performs the shredding. -// -// A matcher is one of three kinds: -// - primitive: typ is set (leaf column) -// - group: fields is set (object with per-field matchers) -// - unsupported: neither (e.g., LIST — values go to the fallback column) -// -// leafCount is always set to the number of leaf columns occupied. -type shreddedMatcher struct { - typ Type // non-nil for primitive typed_value (leaf node) - fields []shreddedFieldMatcher // non-nil for group typed_value (object node) - leafCount uint16 -} - -func (m *shreddedMatcher) isPrimitive() bool { return m.typ != nil } -func (m *shreddedMatcher) isGroup() bool { return len(m.fields) > 0 } -func (m *shreddedMatcher) kind() Kind { return m.typ.Kind() } -func (m *shreddedMatcher) isString() bool { - lt := m.typ.LogicalType() - return lt != nil && lt.UTF8 != nil -} -func (m *shreddedMatcher) isUUID() bool { - lt := m.typ.LogicalType() - return lt != nil && lt.UUID != nil -} - -type shreddedFieldMatcher struct { - name string - matcher shreddedMatcher -} - -func buildShreddedMatcher(node Node) shreddedMatcher { - if node.Leaf() { - return shreddedMatcher{ - typ: node.Type(), - leafCount: 1, - } - } - - // Check if this is a group with (value, typed_value) pairs for each field - fields := node.Fields() - matchers := make([]shreddedFieldMatcher, 0, len(fields)) - for _, f := range fields { - subFields := f.Fields() - if len(subFields) == 2 { - // This is a (value, typed_value) pair for a named field - valueNode := fieldByName(f, "value") - typedNode := fieldByName(f, "typed_value") - if valueNode != nil && typedNode != nil { - matchers = append(matchers, shreddedFieldMatcher{ - name: f.Name(), - matcher: buildShreddedMatcher(Required(typedNode)), - }) - } - } - } - - if len(matchers) > 0 { - return shreddedMatcher{ - fields: matchers, - leafCount: countMatcherLeaves(matchers), - } - } - - // Unsupported typed_value structure (e.g., LIST). Return a matcher - // that never shreds so values always go to the value column. - // Still compute leaf count so column offsets are correct. - return shreddedMatcher{ - leafCount: numLeafColumnsOf(node), - } -} - -func (m *shreddedMatcher) canShred(v any) bool { - if v == nil { - return false - } - if m.isPrimitive() { - return canShredPrimitive(v, m) - } - if m.isGroup() { - return canShredObject(v, m.fields) - } - return false -} - -func canShredPrimitive(v any, m *shreddedMatcher) bool { - switch m.kind() { - case ByteArray: - if m.isString() { - switch v.(type) { - case string: - return true - } - } else { - switch v.(type) { - case []byte: - return true - } - } - case Int32: - switch v.(type) { - case int8, int16, int32, uint8, uint16: - return true - } - case Int64: - switch v.(type) { - case int8, int16, int32, int64, int, uint8, uint16, uint32: - return true - } - case Float: - switch v.(type) { - case float32: - return true - } - case Double: - switch v.(type) { - case float32, float64: - return true - } - case Boolean: - switch v.(type) { - case bool: - return true - } - case FixedLenByteArray: - if m.isUUID() { - switch v.(type) { - case uuid.UUID, [16]byte: - return true - } - } else { - switch v.(type) { - case [16]byte: - return true - } - } - } - return false -} - -func canShredObject(v any, fields []shreddedFieldMatcher) bool { - m, ok := v.(map[string]any) - if !ok { - return false - } - // An object can be shredded if ALL its fields exist in the shredded schema - for key := range m { - found := false - for _, f := range fields { - if f.name == key { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func (m *shreddedMatcher) shred(columns [][]Value, levels columnLevels, startColumn uint16, v any) { - if m.isPrimitive() { - col := startColumn - pv := goValueToParquetValue(v, m.kind()) - pv.repetitionLevel = levels.repetitionLevel - pv.definitionLevel = levels.definitionLevel - pv.columnIndex = ^col - columns[col] = append(columns[col], pv) - return - } - if m.isGroup() { - m.shredObject(columns, levels, startColumn, v) - } -} - -func (m *shreddedMatcher) shredObject(columns [][]Value, levels columnLevels, startColumn uint16, v any) { - obj, ok := v.(map[string]any) - if !ok { - // Should not happen if canShred returned true - return - } - - col := startColumn - for _, f := range m.fields { - // Within each field's sub-group, fields are sorted alphabetically: - // typed_value comes before value. - typedValueCol := col - typedCount := f.matcher.leafCount - valueCol := col + typedCount - nextFieldCol := valueCol + 1 - - fieldVal, exists := obj[f.name] - if exists && fieldVal != nil && f.matcher.canShred(fieldVal) { - // Write null to field's value column - columns[valueCol] = append(columns[valueCol], Value{ - repetitionLevel: levels.repetitionLevel, - definitionLevel: levels.definitionLevel, - columnIndex: ^valueCol, - }) - // Write typed value (increment def for optional typed_value) - typedLevels := levels - typedLevels.definitionLevel++ - f.matcher.shred(columns, typedLevels, typedValueCol, fieldVal) - } else if exists && fieldVal != nil { - // Value doesn't match typed schema: write variant to field's value. - // Encode metadata+value together so nested objects can be decoded later. - valueLevels := levels - valueLevels.definitionLevel++ - metadata, val, err := variant.Marshal(fieldVal) - if err != nil { - panic(fmt.Sprintf("variant marshal field %q: %v", f.name, err)) - } - combined := encodeFieldVariant(metadata, val) - valValue := makeValueByteArray(ByteArray, unsafe.SliceData(combined), len(combined)) - valValue.repetitionLevel = valueLevels.repetitionLevel - valValue.definitionLevel = valueLevels.definitionLevel - valValue.columnIndex = ^valueCol - columns[valueCol] = append(columns[valueCol], valValue) - // Write null to typed_value columns - writeNullLeaves(columns, typedValueCol, typedValueCol+typedCount, levels) - } else { - // Field not present or null: write null to both - writeNullLeaves(columns, typedValueCol, nextFieldCol, levels) - } - - col = nextFieldCol - } -} - -// encodeFieldVariant encodes metadata and value bytes together for per-field -// fallback storage. Format: 4-byte LE metadata length + metadata + value. -// This ensures nested objects retain their metadata dictionary for decoding. -func encodeFieldVariant(metadata, value []byte) []byte { - mLen := len(metadata) - buf := make([]byte, 4+mLen+len(value)) - binary.LittleEndian.PutUint32(buf, uint32(mLen)) - copy(buf[4:], metadata) - copy(buf[4+mLen:], value) - return buf -} - -// decodeFieldVariant splits per-field variant bytes back into metadata and value. -func decodeFieldVariant(data []byte) (metadata, value []byte, ok bool) { - if len(data) < 4 { - return nil, data, false - } - mLen := int(binary.LittleEndian.Uint32(data)) - if 4+mLen > len(data) { - return nil, data, false - } - return data[4 : 4+mLen], data[4+mLen:], true -} - -// countMatcherColumns returns the total number of leaf columns for a matcher, -// including the value column for each field in a group. -func countMatcherColumns(m *shreddedMatcher) uint16 { - if m.isGroup() { - return countMatcherLeaves(m.fields) - } - return m.leafCount -} - -// countMatcherLeaves sums the leaf columns for a list of field matchers. -// Each field contributes its typed_value leaf count plus one value column. -func countMatcherLeaves(fields []shreddedFieldMatcher) uint16 { - var count uint16 - for _, f := range fields { - count += f.matcher.leafCount + 1 // typed_value leaves + value column - } - return count -} - -func goValueToParquetValue(v any, kind Kind) Value { - switch kind { - case Boolean: - return BooleanValue(v.(bool)) - case Int32: - switch val := v.(type) { - case int8: - return Int32Value(int32(val)) - case int16: - return Int32Value(int32(val)) - case int32: - return Int32Value(val) - case uint8: - return Int32Value(int32(val)) - case uint16: - return Int32Value(int32(val)) - default: - return Int32Value(0) - } - case Int64: - switch val := v.(type) { - case int8: - return Int64Value(int64(val)) - case int16: - return Int64Value(int64(val)) - case int32: - return Int64Value(int64(val)) - case int64: - return Int64Value(val) - case int: - return Int64Value(int64(val)) - case uint8: - return Int64Value(int64(val)) - case uint16: - return Int64Value(int64(val)) - case uint32: - return Int64Value(int64(val)) - default: - return Int64Value(0) - } - case Float: - return FloatValue(v.(float32)) - case Double: - switch val := v.(type) { - case float32: - return DoubleValue(float64(val)) - case float64: - return DoubleValue(val) - default: - return DoubleValue(0) - } - case ByteArray: - switch val := v.(type) { - case string: - return ByteArrayValue([]byte(val)) - case []byte: - return ByteArrayValue(val) - default: - return ByteArrayValue(nil) - } - case FixedLenByteArray: - switch val := v.(type) { - case uuid.UUID: - b := [16]byte(val) - return FixedLenByteArrayValue(b[:]) - case [16]byte: - return FixedLenByteArrayValue(val[:]) - default: - return FixedLenByteArrayValue(nil) - } - default: - return Value{} - } -} - // reconstructFuncOfVariant handles reconstruction of variant columns back into // Go values. Dispatches to unshredded or shredded variant handling. // @@ -641,110 +272,70 @@ func reconstructFuncOfUnshreddedVariant(columnIndex uint16, node Node) (uint16, } } -// reconstructFuncOfShreddedVariant handles the 3-field shredded variant. +// reconstructFuncOfShreddedVariant reconstructs Go values from a shredded +// variant group using the construct_variant algorithm of the Variant +// Shredding specification (see variant_shredded_read.go). // //go:noinline func reconstructFuncOfShreddedVariant(columnIndex uint16, node Node) (uint16, reconstructFunc) { - // Fields are sorted alphabetically: metadata, typed_value, value - var metadataOffset, valueOffset, typedValueOffset uint16 - var typedValueLeafCount uint16 - var typedValueNode Node - - col := uint16(0) - for _, f := range node.Fields() { - n := numLeafColumnsOf(f) - switch f.Name() { - case "metadata": - metadataOffset = col - col += n - case "typed_value": - typedValueOffset = col - typedValueNode = f - typedValueLeafCount = n - col += n - case "value": - valueOffset = col - col += n + group, err := buildShreddedVariantGroup(node, 0, 0, 0) + if err != nil { + numCols := numLeafColumnsOf(node) + return columnIndex + numCols, func(reflect.Value, columnLevels, [][]Value) error { + return err } } - totalCols := int(col) - nextColumnIndex := columnIndex + col - - typedInner := Required(typedValueNode) - extractor := buildShreddedExtractor(typedInner) + nextColumnIndex := columnIndex + uint16(group.numCols) return nextColumnIndex, func(value reflect.Value, levels columnLevels, columns [][]Value) error { - if len(columns) < totalCols { - return fmt.Errorf("shredded variant reconstruction: expected %d columns, got %d", totalCols, len(columns)) + if len(columns) < group.numCols { + return fmt.Errorf("shredded variant reconstruction: expected %d columns, got %d", group.numCols, len(columns)) } - - metaCol := columns[metadataOffset] - valCol := columns[valueOffset] - typedColumns := columns[typedValueOffset : typedValueOffset+typedValueLeafCount] - - if len(metaCol) == 0 { - return fmt.Errorf("variant reconstruction: no values in metadata column %d", columnIndex) + if group.metadataCol < 0 { + return fmt.Errorf("shredded variant reconstruction: missing metadata column") } - metaVal := metaCol[0] - hasValue := len(valCol) > 0 && !valCol[0].IsNull() - hasTypedValue := hasNonNullInColumns(typedColumns) + reader := &variantColumnReader{ + columns: columns, + pos: make([]int, len(columns)), + } - if metaVal.IsNull() && !hasValue && !hasTypedValue { - // All null: missing/null + metaVal, ok := reader.next(group.metadataCol) + if !ok || metaVal.IsNull() || int(metaVal.definitionLevel) < int(levels.definitionLevel) { + // The variant group itself is null for this row. value.Set(reflect.Zero(value.Type())) return nil } - - if hasValue && !hasTypedValue { - // Unshredded value - valBytes := valCol[0].ByteArray() - if len(valBytes) == 0 { - value.Set(reflect.Zero(value.Type())) - return nil - } - metaBytes := metaVal.ByteArray() - if setRawVariantStruct(value, metaBytes, valBytes) { - return nil - } - goVal, err := variant.Unmarshal(metaBytes, valBytes) - if err != nil { - return fmt.Errorf("variant unmarshal: %w", err) - } - return setVariantGoValue(value, goVal) - } - - if !hasValue && hasTypedValue { - // Shredded value: extract from typed columns - goVal := extractor.extract(typedColumns) - return setVariantGoValue(value, goVal) + metaBytes := metaVal.ByteArray() + m, err := variant.DecodeMetadata(metaBytes) + if err != nil { + return fmt.Errorf("variant metadata: %w", err) } - if hasValue && hasTypedValue { - // Partially shredded: typed_value has some fields, value has the rest - typedVal := extractor.extract(typedColumns) - valBytes := valCol[0].ByteArray() - metaBytes := metaVal.ByteArray() - unshreddedVal, err := variant.Unmarshal(metaBytes, valBytes) - if err != nil { - return fmt.Errorf("variant unmarshal: %w", err) + v, present, err := group.read(reader, m, int(levels.definitionLevel), int(levels.repetitionDepth)) + if err != nil { + return err + } + if !present { + // value and typed_value both null at the top level is invalid + // per the spec; read it as variant null (matching + // parquet-java's behavior). + v = variant.Null() + } + + // If the target is a raw variant struct (Metadata/Value []byte + // fields), re-encode the reconstructed value. + if isRawVariantStructTarget(value) { + var b variant.MetadataBuilder + encoded := variant.Encode(&b, v) + _, metadata := b.Build() + if setRawVariantStruct(value, metadata, encoded) { + return nil } - merged := mergeVariantObjects(typedVal, unshreddedVal) - return setVariantGoValue(value, merged) } - value.Set(reflect.Zero(value.Type())) - return nil - } -} - -func hasNonNullInColumns(columns [][]Value) bool { - for _, col := range columns { - if len(col) > 0 && !col[0].IsNull() { - return true - } + return setVariantGoValue(value, v.GoValue()) } - return false } // setRawVariantStruct checks if the target value is a struct with Metadata and @@ -794,186 +385,19 @@ func setVariantGoValue(value reflect.Value, goVal any) error { return nil } -// shreddedExtractor reconstructs Go values from typed_value columns. -// Same three-kind structure as shreddedMatcher: primitive (typ set), -// group (fields set), or unsupported (neither). -type shreddedExtractor struct { - typ Type // non-nil for primitive (leaf column) - fields []shreddedFieldExtractor // non-nil for group (object) - leafCount int -} - -func (e *shreddedExtractor) isPrimitive() bool { return e.typ != nil } -func (e *shreddedExtractor) isGroup() bool { return len(e.fields) > 0 } -func (e *shreddedExtractor) kind() Kind { return e.typ.Kind() } -func (e *shreddedExtractor) isString() bool { - lt := e.typ.LogicalType() - return lt != nil && lt.UTF8 != nil -} -func (e *shreddedExtractor) isUUID() bool { - lt := e.typ.LogicalType() - return lt != nil && lt.UUID != nil -} - -type shreddedFieldExtractor struct { - name string - extractor shreddedExtractor -} - -func buildShreddedExtractor(node Node) shreddedExtractor { - if node.Leaf() { - return shreddedExtractor{ - typ: node.Type(), - leafCount: 1, - } - } - - fields := node.Fields() - extractors := make([]shreddedFieldExtractor, 0, len(fields)) - for _, f := range fields { - subFields := f.Fields() - if len(subFields) == 2 { - typedNode := fieldByName(f, "typed_value") - if typedNode != nil { - extractors = append(extractors, shreddedFieldExtractor{ - name: f.Name(), - extractor: buildShreddedExtractor(Required(typedNode)), - }) - } - } - } - - if len(extractors) > 0 { - leaves := 0 - for _, f := range extractors { - leaves += f.extractor.leafCount + 1 // typed_value leaves + value column - } - return shreddedExtractor{ - fields: extractors, - leafCount: leaves, - } - } - - // Unsupported typed_value structure (e.g., LIST). Return an extractor - // that always returns nil so values are read from the value column. - return shreddedExtractor{ - leafCount: int(numLeafColumnsOf(node)), +// isRawVariantStructTarget reports whether the reconstruction target is a +// struct with Metadata and Value []byte fields (raw variant passthrough). +func isRawVariantStructTarget(value reflect.Value) bool { + t := value.Type() + for t.Kind() == reflect.Ptr { + t = t.Elem() } -} - -func (e *shreddedExtractor) extract(columns [][]Value) any { - if e.isPrimitive() { - if len(columns) == 0 || len(columns[0]) == 0 || columns[0][0].IsNull() { - return nil - } - return parquetValueToGo(columns[0][0], e) - } - if e.isGroup() { - return e.extractObject(columns) - } - return nil -} - -func (e *shreddedExtractor) extractObject(columns [][]Value) any { - result := make(map[string]any) - col := 0 - for _, f := range e.fields { - // Within each field's sub-group, fields are sorted alphabetically: - // typed_value comes before value. - typedStart := col - typedCount := f.extractor.leafCount - valueCol := col + typedCount - nextFieldCol := valueCol + 1 - - hasValue := valueCol < len(columns) && len(columns[valueCol]) > 0 && !columns[valueCol][0].IsNull() - hasTyped := hasNonNullInRange(columns, typedStart, typedStart+typedCount) - - if hasTyped { - val := f.extractor.extract(columns[typedStart : typedStart+typedCount]) - if val != nil { - result[f.name] = val - } - } else if hasValue { - // Field stored as unshredded variant with metadata+value encoded together. - data := columns[valueCol][0].ByteArray() - metaBytes, valBytes, ok := decodeFieldVariant(data) - if ok { - goVal, err := variant.Unmarshal(metaBytes, valBytes) - if err == nil && goVal != nil { - result[f.name] = goVal - } - } - } - - col = nextFieldCol - } - - if len(result) == 0 { - return nil - } - return result -} - -func hasNonNullInRange(columns [][]Value, start, end int) bool { - for i := start; i < end && i < len(columns); i++ { - if len(columns[i]) > 0 && !columns[i][0].IsNull() { - return true - } - } - return false -} - -func parquetValueToGo(v Value, e *shreddedExtractor) any { - switch e.kind() { - case Boolean: - return v.Boolean() - case Int32: - return v.Int32() - case Int64: - return v.Int64() - case Float: - return v.Float() - case Double: - return v.Double() - case ByteArray: - b := v.ByteArray() - if e.isString() { - return string(b) - } - dst := make([]byte, len(b)) - copy(dst, b) - return dst - case FixedLenByteArray: - b := v.ByteArray() - if e.isUUID() && len(b) == 16 { - return uuid.UUID(b) - } - if len(b) == 16 { - var u [16]byte - copy(u[:], b) - return u - } - dst := make([]byte, len(b)) - copy(dst, b) - return dst - default: - return nil - } -} - -// mergeVariantObjects merges two values, preferring typed (shredded) values -// over unshredded ones. Used for partially shredded objects. -func mergeVariantObjects(typed, unshredded any) any { - typedMap, tOk := typed.(map[string]any) - unshreddedMap, uOk := unshredded.(map[string]any) - if tOk && uOk { - result := make(map[string]any, len(typedMap)+len(unshreddedMap)) - maps.Copy(result, unshreddedMap) - maps.Copy(result, typedMap) - return result - } - if tOk { - return typed + if t.Kind() != reflect.Struct { + return false } - return unshredded + byteSliceType := reflect.TypeOf([]byte(nil)) + metaField, hasMetadata := t.FieldByName("Metadata") + valField, hasValue := t.FieldByName("Value") + return hasMetadata && hasValue && + metaField.Type == byteSliceType && valField.Type == byteSliceType } diff --git a/vendor/github.com/parquet-go/parquet-go/schema.go b/vendor/github.com/parquet-go/parquet-go/schema.go index c4d8a8addac..c233cdb8734 100644 --- a/vendor/github.com/parquet-go/parquet-go/schema.go +++ b/vendor/github.com/parquet-go/parquet-go/schema.go @@ -385,14 +385,7 @@ func (s *Schema) Reconstruct(value any, row Row) error { v = v.Elem() } - b := valuesSliceBufferPool.Get( - func() *valuesSliceBuffer { - return &valuesSliceBuffer{ - values: make([][]Value, 0, 64), - } - }, - func(v *valuesSliceBuffer) { v.values = v.values[:0] }, - ) + b := acquireValuesSliceBuffer() state := s.lazyLoadState() funcs := s.lazyLoadFuncs() @@ -432,6 +425,17 @@ func (v *valuesSliceBuffer) release() { var valuesSliceBufferPool memory.Pool[valuesSliceBuffer] +func acquireValuesSliceBuffer() *valuesSliceBuffer { + return valuesSliceBufferPool.Get( + func() *valuesSliceBuffer { + return &valuesSliceBuffer{ + values: make([][]Value, 0, 64), + } + }, + func(v *valuesSliceBuffer) { v.values = v.values[:0] }, + ) +} + // Lookup returns the leaf column at the given path. // // The path is the sequence of column names identifying a leaf column (not @@ -750,7 +754,7 @@ func nodeOf(path []string, t reflect.Type, tags parquetTags, tagReplacements []S } n = FieldID(n, id) default: - throwUnknownTag(t, "map", option) + throwUnknownTag(t, "map", joinOptionArgs(option, args)) } }) @@ -788,6 +792,17 @@ func splitOptionArgs(s string) (option, args string) { return } +// joinOptionArgs is the inverse of splitOptionArgs for the purpose of +// rendering a tag back to the user. splitOptionArgs returns args="()" as +// a sentinel meaning "no parens in the source"; we drop it here so plain +// options don't render as "foo()" in panic messages. +func joinOptionArgs(option, args string) string { + if args == "()" { + return option + } + return option + args +} + func parseDecimalArgs(args string) (scale, precision int, err error) { if !strings.HasPrefix(args, "(") || !strings.HasSuffix(args, ")") { return 0, 0, fmt.Errorf("malformed decimal args: %s", args) @@ -1069,7 +1084,15 @@ func makeNodeOf(path []string, t reflect.Type, name string, tags parquetTags, ta if t == reflect.TypeFor[json.RawMessage]() { throwInvalidTag(t, name, option) } - element := makeNodeOf(append(path, "list", "element"), t.Elem(), t.Name(), tags.getListElementNodeTags(), tagReplacements) + elementTags := tags.getListElementNodeTags() + if elem := t.Elem(); elem.Kind() == reflect.Slice && elem.Elem().Kind() != reflect.Uint8 && !strings.Contains(elementTags.parquet, "list") { + // A nested slice under a list is itself a list: recurse the + // list option implicitly so any nesting depth is expressible + // with a single `list` tag on the field. An explicit + // parquet-element tag still takes precedence. + elementTags.parquet += ",list" + } + element := makeNodeOf(append(path, "list", "element"), t.Elem(), t.Name(), elementTags, tagReplacements) setNode(element) setList() default: @@ -1327,6 +1350,8 @@ func makeNodeOf(path []string, t reflect.Type, name string, tags parquetTags, ta throwInvalidTag(t, name, option+args) } setNode(Geography(crs, alg)) + default: + throwUnknownTag(t, name, joinOptionArgs(option, args)) } }) } @@ -1390,6 +1415,7 @@ func forEachTagOption(tags []string, do func(option, args string)) { option, tag = split(tag) var args string option, args = splitOptionArgs(option) + option = strings.TrimSpace(option) do(option, args) } } diff --git a/vendor/github.com/parquet-go/parquet-go/sorting.go b/vendor/github.com/parquet-go/parquet-go/sorting.go index cdb5974cc99..c39b02f8e8f 100644 --- a/vendor/github.com/parquet-go/parquet-go/sorting.go +++ b/vendor/github.com/parquet-go/parquet-go/sorting.go @@ -110,15 +110,12 @@ func (w *SortingWriter[T]) Close() error { return err } - rows := m.Rows() - defer rows.Close() - - reader := RowReader(rows) - if w.sorting.DropDuplicatedRows { - reader = DedupeRowReader(rows, w.rowbuf.compare) - } - - if _, err := CopyRows(w.output, reader); err != nil { + // Writing the merged row group (rather than copying its rows) lets the + // writer use its chunk-level fast paths when the sorted chunks do not + // overlap: verbatim column chunk copies and column-oriented packing toward + // MaxRowsPerRowGroup. Overlapping chunks fall back to the row-oriented heap + // merge, and the merge itself applies DropDuplicatedRows when configured. + if _, err := w.output.WriteRowGroup(m); err != nil { return err } diff --git a/vendor/github.com/parquet-go/parquet-go/type.go b/vendor/github.com/parquet-go/parquet-go/type.go index c8e27ec64e5..15158022fd6 100644 --- a/vendor/github.com/parquet-go/parquet-go/type.go +++ b/vendor/github.com/parquet-go/parquet-go/type.go @@ -242,10 +242,36 @@ var ( NullType Type = &nullType{} ) +// logicalTypeOf returns the annotation carried by lt if it is of type T. A nil +// lt, or one carrying a different annotation, yields ok=false. +func logicalTypeOf[T format.LogicalTypeValue](lt *format.LogicalType) (T, bool) { + if lt == nil { + var zero T + return zero, false + } + v, ok := lt.Value.(T) + return v, ok +} + +// logicalTypeIs reports whether lt carries a T annotation. +func logicalTypeIs[T format.LogicalTypeValue](lt *format.LogicalType) bool { + _, ok := logicalTypeOf[T](lt) + return ok +} + +// logicalTypeValueOf returns the annotation carried by lt, or nil when lt is +// nil. It is the nil-safe way to reach lt.Value for a type switch. +func logicalTypeValueOf(lt *format.LogicalType) format.LogicalTypeValue { + if lt == nil { + return nil + } + return lt.Value +} + // In the current parquet version supported by this library, only type-defined // orders are supported. var typeDefinedColumnOrder = format.ColumnOrder{ - TypeOrder: new(format.TypeDefinedOrder), + Value: new(format.TypeDefinedOrder), } var physicalTypes = [...]format.Type{ diff --git a/vendor/github.com/parquet-go/parquet-go/type_bson.go b/vendor/github.com/parquet-go/parquet-go/type_bson.go index 687e5d1f7d0..5303f0af7c7 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_bson.go +++ b/vendor/github.com/parquet-go/parquet-go/type_bson.go @@ -14,7 +14,7 @@ import ( func BSON() Node { return Leaf(&bsonType{}) } var bsonLogicalType = format.LogicalType{ - Bson: new(format.BsonType), + Value: new(format.BsonType), } type bsonType format.BsonType diff --git a/vendor/github.com/parquet-go/parquet-go/type_date.go b/vendor/github.com/parquet-go/parquet-go/type_date.go index e408be207db..42b7862ede9 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_date.go +++ b/vendor/github.com/parquet-go/parquet-go/type_date.go @@ -15,7 +15,7 @@ import ( func Date() Node { return Leaf(&dateType{}) } var dateLogicalType = format.LogicalType{ - Date: new(format.DateType), + Value: new(format.DateType), } type dateType format.DateType diff --git a/vendor/github.com/parquet-go/parquet-go/type_decimal.go b/vendor/github.com/parquet-go/parquet-go/type_decimal.go index a3b71ac7bbc..b7882537a16 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_decimal.go +++ b/vendor/github.com/parquet-go/parquet-go/type_decimal.go @@ -49,7 +49,7 @@ type decimalType struct { func (t *decimalType) String() string { return t.decimal.String() } func (t *decimalType) LogicalType() *format.LogicalType { - return &format.LogicalType{Decimal: &t.decimal} + return &format.LogicalType{Value: &t.decimal} } func (t *decimalType) ConvertedType() *deprecated.ConvertedType { @@ -77,6 +77,14 @@ func (t *decimalType) AssignValue(dst reflect.Value, src Value) error { if t.Type.Kind() != ByteArray && t.Type.Kind() != FixedLenByteArray { return nil } + switch dst.Kind() { + case reflect.Slice, reflect.Array, reflect.String: + // Destinations like []byte, [N]byte, or string receive the raw + // big-endian two's-complement representation of the decimal + // value, as they did when decimalType inherited AssignValue + // from its underlying byte array type. + return t.Type.AssignValue(dst, src) + } data := src.ByteArray() val := new(big.Int) if len(data) > 0 && data[0]&0x80 != 0 { @@ -98,7 +106,13 @@ func (t *decimalType) AssignValue(dst reflect.Value, src Value) error { scaleFactor := new(big.Float).SetPrec(prec) scaleFactor.SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(t.decimal.Scale)), nil)) f.Quo(f, scaleFactor) - dst.Set(reflect.ValueOf(f)) + switch dst.Kind() { + case reflect.Float32, reflect.Float64: + v, _ := f.Float64() + dst.SetFloat(v) + default: + dst.Set(reflect.ValueOf(f)) + } } return nil } diff --git a/vendor/github.com/parquet-go/parquet-go/type_enum.go b/vendor/github.com/parquet-go/parquet-go/type_enum.go index d47c7bbb2fe..e2c4eedc7c7 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_enum.go +++ b/vendor/github.com/parquet-go/parquet-go/type_enum.go @@ -14,7 +14,7 @@ import ( func Enum() Node { return Leaf(&enumType{}) } var enumLogicalType = format.LogicalType{ - Enum: new(format.EnumType), + Value: new(format.EnumType), } type enumType format.EnumType diff --git a/vendor/github.com/parquet-go/parquet-go/type_geography.go b/vendor/github.com/parquet-go/parquet-go/type_geography.go index f39b0418e91..74f6a29ada3 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_geography.go +++ b/vendor/github.com/parquet-go/parquet-go/type_geography.go @@ -34,18 +34,18 @@ func (t *geographyType) ColumnOrder() *format.ColumnOrder { return byteArrayType func (t *geographyType) PhysicalType() *format.Type { return byteArrayType{}.PhysicalType() } func (t *geographyType) LogicalType() *format.LogicalType { - f := &format.LogicalType{Geography: &format.GeographyType{ + g := format.GeographyType{ CRS: t.CRS, Algorithm: t.Algorithm, - }} - if t.CRS == "" { - f.Geography.CRS = format.GeometryDefaultCRS + } + if g.CRS == "" { + g.CRS = format.GeometryDefaultCRS } if t.Algorithm != 0 { - f.Geography.Algorithm = t.Algorithm + g.Algorithm = t.Algorithm } - return f + return &format.LogicalType{Value: &g} } func (t *geographyType) ConvertedType() *deprecated.ConvertedType { @@ -120,15 +120,18 @@ func (t *geographyType) AssignValue(dst reflect.Value, src Value) error { func (t *geographyType) ConvertValue(val Value, typ Type) (Value, error) { switch src := typ.(type) { case *geographyType: - if src.LogicalType().Geography.CRS != t.CRS { + srcGeography, _ := logicalTypeOf[*format.GeographyType](src.LogicalType()) + dstGeography, _ := logicalTypeOf[*format.GeographyType](t.LogicalType()) + if srcGeography.CRS != t.CRS { return Value{}, errors.New("cannot convert between geography types with different CRS") } - if src.LogicalType().Geography.Algorithm != t.LogicalType().Geography.Algorithm { + if srcGeography.Algorithm != dstGeography.Algorithm { return Value{}, errors.New("cannot convert between geography types with different Algorithm") } return val, nil case *geometryType: - if src.LogicalType().Geometry.CRS != t.CRS { + srcGeometry, _ := logicalTypeOf[*format.GeometryType](src.LogicalType()) + if srcGeometry.CRS != t.CRS { return Value{}, errors.New("cannot convert between geography and geometry types with different CRS") } return val, nil diff --git a/vendor/github.com/parquet-go/parquet-go/type_geometry.go b/vendor/github.com/parquet-go/parquet-go/type_geometry.go index 54f53ef4fcb..57bf2528612 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_geometry.go +++ b/vendor/github.com/parquet-go/parquet-go/type_geometry.go @@ -37,9 +37,9 @@ func (t *geometryType) PhysicalType() *format.Type { return byteArrayType{}.Phys func (t *geometryType) LogicalType() *format.LogicalType { if t.CRS == "" { - return &format.LogicalType{Geometry: &geometryDefaultCRSLogicType} + return &format.LogicalType{Value: &geometryDefaultCRSLogicType} } - return &format.LogicalType{Geometry: (*format.GeometryType)(t)} + return &format.LogicalType{Value: (*format.GeometryType)(t)} } func (t *geometryType) ConvertedType() *deprecated.ConvertedType { @@ -114,12 +114,14 @@ func (t *geometryType) AssignValue(dst reflect.Value, src Value) error { func (t *geometryType) ConvertValue(val Value, typ Type) (Value, error) { switch src := typ.(type) { case *geometryType: - if src.LogicalType().Geometry.CRS != t.CRS { + srcGeometry, _ := logicalTypeOf[*format.GeometryType](src.LogicalType()) + if srcGeometry.CRS != t.CRS { return Value{}, errors.New("cannot convert between geometry types with different CRS") } return val, nil case *geographyType: - if src.LogicalType().Geography.CRS != t.CRS { + srcGeography, _ := logicalTypeOf[*format.GeographyType](src.LogicalType()) + if srcGeography.CRS != t.CRS { return Value{}, errors.New("cannot convert between geography and geometry types with different CRS") } return val, nil diff --git a/vendor/github.com/parquet-go/parquet-go/type_int32.go b/vendor/github.com/parquet-go/parquet-go/type_int32.go index bf9200b3622..c7a138127e3 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_int32.go +++ b/vendor/github.com/parquet-go/parquet-go/type_int32.go @@ -10,7 +10,7 @@ import ( type int32Type struct{} -var int32LogicalType = format.LogicalType{Integer: &format.IntType{ +var int32LogicalType = format.LogicalType{Value: &format.IntType{ BitWidth: 32, IsSigned: true, }} diff --git a/vendor/github.com/parquet-go/parquet-go/type_int64.go b/vendor/github.com/parquet-go/parquet-go/type_int64.go index db1287b6945..21c4fa7d3b3 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_int64.go +++ b/vendor/github.com/parquet-go/parquet-go/type_int64.go @@ -10,7 +10,7 @@ import ( type int64Type struct{} -var int64LogicalType = format.LogicalType{Integer: &format.IntType{ +var int64LogicalType = format.LogicalType{Value: &format.IntType{ BitWidth: 64, IsSigned: true, }} diff --git a/vendor/github.com/parquet-go/parquet-go/type_int_logical.go b/vendor/github.com/parquet-go/parquet-go/type_int_logical.go index 8a2f7ed7618..94627fb717b 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_int_logical.go +++ b/vendor/github.com/parquet-go/parquet-go/type_int_logical.go @@ -56,17 +56,41 @@ var unsignedIntTypes = [...]intType{ } var signedLogicalIntTypes = [...]format.LogicalType{ - {Integer: (*format.IntType)(&signedIntTypes[0])}, - {Integer: (*format.IntType)(&signedIntTypes[1])}, - {Integer: (*format.IntType)(&signedIntTypes[2])}, - {Integer: (*format.IntType)(&signedIntTypes[3])}, + {Value: (*format.IntType)(&signedIntTypes[0])}, + {Value: (*format.IntType)(&signedIntTypes[1])}, + {Value: (*format.IntType)(&signedIntTypes[2])}, + {Value: (*format.IntType)(&signedIntTypes[3])}, } var unsignedLogicalIntTypes = [...]format.LogicalType{ - {Integer: (*format.IntType)(&unsignedIntTypes[0])}, - {Integer: (*format.IntType)(&unsignedIntTypes[1])}, - {Integer: (*format.IntType)(&unsignedIntTypes[2])}, - {Integer: (*format.IntType)(&unsignedIntTypes[3])}, + {Value: (*format.IntType)(&unsignedIntTypes[0])}, + {Value: (*format.IntType)(&unsignedIntTypes[1])}, + {Value: (*format.IntType)(&unsignedIntTypes[2])}, + {Value: (*format.IntType)(&unsignedIntTypes[3])}, +} + +// canonicalIntType maps a decoded IntType onto the instance this package +// already declares for it. Returning the shared instance rather than a pointer +// into the file metadata lets LogicalType find it by identity, instead of +// allocating a new format.LogicalType on every call. +func canonicalIntType(t *format.IntType) *intType { + table := &unsignedIntTypes + if t.IsSigned { + table = &signedIntTypes + } + switch t.BitWidth { + case 8: + return &table[0] + case 16: + return &table[1] + case 32: + return &table[2] + case 64: + return &table[3] + default: + // Not a bit width the spec allows; keep the value the file carried. + return (*intType)(t) + } } type intType format.IntType @@ -143,7 +167,7 @@ func (t *intType) LogicalType() *format.LogicalType { case &unsignedIntTypes[3]: return &unsignedLogicalIntTypes[3] default: - return &format.LogicalType{Integer: (*format.IntType)(t)} + return &format.LogicalType{Value: (*format.IntType)(t)} } } diff --git a/vendor/github.com/parquet-go/parquet-go/type_json.go b/vendor/github.com/parquet-go/parquet-go/type_json.go index abf452f7fb9..d6d41630801 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_json.go +++ b/vendor/github.com/parquet-go/parquet-go/type_json.go @@ -15,7 +15,7 @@ import ( func JSON() Node { return Leaf(&jsonType{}) } var jsonLogicalType = format.LogicalType{ - Json: new(format.JsonType), + Value: new(format.JsonType), } type jsonType format.JsonType diff --git a/vendor/github.com/parquet-go/parquet-go/type_list.go b/vendor/github.com/parquet-go/parquet-go/type_list.go index 3f17fde4922..ccfd413df95 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_list.go +++ b/vendor/github.com/parquet-go/parquet-go/type_list.go @@ -21,7 +21,7 @@ func (listNode) Type() Type { return &listType{} } type listType format.ListType -var listLogicalType = format.LogicalType{List: new(format.ListType)} +var listLogicalType = format.LogicalType{Value: new(format.ListType)} func (t *listType) String() string { return (*format.ListType)(t).String() } diff --git a/vendor/github.com/parquet-go/parquet-go/type_map.go b/vendor/github.com/parquet-go/parquet-go/type_map.go index 66835cda12f..f1d96d3e09e 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_map.go +++ b/vendor/github.com/parquet-go/parquet-go/type_map.go @@ -26,7 +26,7 @@ func (mapNode) Type() Type { return &mapType{} } type mapType format.MapType -var mapLogicalType = format.LogicalType{Map: new(format.MapType)} +var mapLogicalType = format.LogicalType{Value: new(format.MapType)} func (t *mapType) String() string { return (*format.MapType)(t).String() } diff --git a/vendor/github.com/parquet-go/parquet-go/type_null.go b/vendor/github.com/parquet-go/parquet-go/type_null.go index 3a3318226bc..aa9b66950f5 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_null.go +++ b/vendor/github.com/parquet-go/parquet-go/type_null.go @@ -10,7 +10,7 @@ import ( type nullType format.NullType -var nullLogicalType = format.LogicalType{Unknown: new(format.NullType)} +var nullLogicalType = format.LogicalType{Value: new(format.NullType)} func (t *nullType) String() string { return (*format.NullType)(t).String() } diff --git a/vendor/github.com/parquet-go/parquet-go/type_string.go b/vendor/github.com/parquet-go/parquet-go/type_string.go index cdd9afb7873..89bc6ad82d5 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_string.go +++ b/vendor/github.com/parquet-go/parquet-go/type_string.go @@ -15,7 +15,7 @@ import ( func String() Node { return Leaf(&stringType{}) } var stringLogicalType = format.LogicalType{ - UTF8: new(format.StringType), + Value: new(format.StringType), } type stringType format.StringType @@ -92,7 +92,7 @@ func (t *stringType) ConvertValue(val Value, typ Type) (Value, error) { return convertDateToString(val) case *timeType: tz := t2.tz() - if t2.Unit.Micros != nil { + if isMicros(t2.Unit) { return convertTimeMicrosToString(val, tz) } else { return convertTimeMillisToString(val, tz) diff --git a/vendor/github.com/parquet-go/parquet-go/type_time.go b/vendor/github.com/parquet-go/parquet-go/type_time.go index 327ba8bf0ef..3eb5f8b13c1 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_time.go +++ b/vendor/github.com/parquet-go/parquet-go/type_time.go @@ -24,25 +24,31 @@ var ( Nanosecond TimeUnit = &nanosecond{} ) +// The TimeUnit union holds exactly one of these; testing which one is common +// enough in this package to be worth naming. +func isMillis(u format.TimeUnit) bool { _, ok := u.Value.(*format.MilliSeconds); return ok } +func isMicros(u format.TimeUnit) bool { _, ok := u.Value.(*format.MicroSeconds); return ok } +func isNanos(u format.TimeUnit) bool { _, ok := u.Value.(*format.NanoSeconds); return ok } + type millisecond format.MilliSeconds func (u *millisecond) Duration() time.Duration { return time.Millisecond } func (u *millisecond) TimeUnit() format.TimeUnit { - return format.TimeUnit{Millis: (*format.MilliSeconds)(u)} + return format.TimeUnit{Value: (*format.MilliSeconds)(u)} } type microsecond format.MicroSeconds func (u *microsecond) Duration() time.Duration { return time.Microsecond } func (u *microsecond) TimeUnit() format.TimeUnit { - return format.TimeUnit{Micros: (*format.MicroSeconds)(u)} + return format.TimeUnit{Value: (*format.MicroSeconds)(u)} } type nanosecond format.NanoSeconds func (u *nanosecond) Duration() time.Duration { return time.Nanosecond } func (u *nanosecond) TimeUnit() format.TimeUnit { - return format.TimeUnit{Nanos: (*format.NanoSeconds)(u)} + return format.TimeUnit{Value: (*format.NanoSeconds)(u)} } // Time constructs a leaf node of TIME logical type. @@ -61,21 +67,21 @@ func TimeAdjusted(unit TimeUnit, isAdjustedToUTC bool) Node { // Use pre-allocated instances for common cases timeUnit := unit.TimeUnit() if isAdjustedToUTC { - switch { - case timeUnit.Millis != nil: + switch timeUnit.Value.(type) { + case *format.MilliSeconds: return Leaf(&timeMilliAdjustedToUTC) - case timeUnit.Micros != nil: + case *format.MicroSeconds: return Leaf(&timeMicroAdjustedToUTC) - case timeUnit.Nanos != nil: + case *format.NanoSeconds: return Leaf(&timeNanoAdjustedToUTC) } } else { - switch { - case timeUnit.Millis != nil: + switch timeUnit.Value.(type) { + case *format.MilliSeconds: return Leaf(&timeMilliNotAdjustedToUTC) - case timeUnit.Micros != nil: + case *format.MicroSeconds: return Leaf(&timeMicroNotAdjustedToUTC) - case timeUnit.Nanos != nil: + case *format.NanoSeconds: return Leaf(&timeNanoNotAdjustedToUTC) } } @@ -85,56 +91,82 @@ func TimeAdjusted(unit TimeUnit, isAdjustedToUTC bool) Node { var timeMilliAdjustedToUTC = timeType{ IsAdjustedToUTC: true, - Unit: format.TimeUnit{Millis: new(format.MilliSeconds)}, + Unit: format.TimeUnit{Value: new(format.MilliSeconds)}, } var timeMicroAdjustedToUTC = timeType{ IsAdjustedToUTC: true, - Unit: format.TimeUnit{Micros: new(format.MicroSeconds)}, + Unit: format.TimeUnit{Value: new(format.MicroSeconds)}, } var timeNanoAdjustedToUTC = timeType{ IsAdjustedToUTC: true, - Unit: format.TimeUnit{Nanos: new(format.NanoSeconds)}, + Unit: format.TimeUnit{Value: new(format.NanoSeconds)}, } var timeMilliNotAdjustedToUTC = timeType{ IsAdjustedToUTC: false, - Unit: format.TimeUnit{Millis: new(format.MilliSeconds)}, + Unit: format.TimeUnit{Value: new(format.MilliSeconds)}, } var timeMicroNotAdjustedToUTC = timeType{ IsAdjustedToUTC: false, - Unit: format.TimeUnit{Micros: new(format.MicroSeconds)}, + Unit: format.TimeUnit{Value: new(format.MicroSeconds)}, } var timeNanoNotAdjustedToUTC = timeType{ IsAdjustedToUTC: false, - Unit: format.TimeUnit{Nanos: new(format.NanoSeconds)}, + Unit: format.TimeUnit{Value: new(format.NanoSeconds)}, } var timeMilliAdjustedToUTCLogicalType = format.LogicalType{ - Time: (*format.TimeType)(&timeMilliAdjustedToUTC), + Value: (*format.TimeType)(&timeMilliAdjustedToUTC), } var timeMicroAdjustedToUTCLogicalType = format.LogicalType{ - Time: (*format.TimeType)(&timeMicroAdjustedToUTC), + Value: (*format.TimeType)(&timeMicroAdjustedToUTC), } var timeNanoAdjustedToUTCLogicalType = format.LogicalType{ - Time: (*format.TimeType)(&timeNanoAdjustedToUTC), + Value: (*format.TimeType)(&timeNanoAdjustedToUTC), } var timeMilliNotAdjustedToUTCLogicalType = format.LogicalType{ - Time: (*format.TimeType)(&timeMilliNotAdjustedToUTC), + Value: (*format.TimeType)(&timeMilliNotAdjustedToUTC), } var timeMicroNotAdjustedToUTCLogicalType = format.LogicalType{ - Time: (*format.TimeType)(&timeMicroNotAdjustedToUTC), + Value: (*format.TimeType)(&timeMicroNotAdjustedToUTC), } var timeNanoNotAdjustedToUTCLogicalType = format.LogicalType{ - Time: (*format.TimeType)(&timeNanoNotAdjustedToUTC), + Value: (*format.TimeType)(&timeNanoNotAdjustedToUTC), +} + +// canonicalTimeType maps a decoded TimeType onto the instance this package +// already declares for it. See canonicalIntType. +func canonicalTimeType(t *format.TimeType) *timeType { + if t.IsAdjustedToUTC { + switch t.Unit.Value.(type) { + case *format.MilliSeconds: + return &timeMilliAdjustedToUTC + case *format.MicroSeconds: + return &timeMicroAdjustedToUTC + case *format.NanoSeconds: + return &timeNanoAdjustedToUTC + } + } else { + switch t.Unit.Value.(type) { + case *format.MilliSeconds: + return &timeMilliNotAdjustedToUTC + case *format.MicroSeconds: + return &timeMicroNotAdjustedToUTC + case *format.NanoSeconds: + return &timeNanoNotAdjustedToUTC + } + } + // No unit, or one we do not know; keep the value the file carried. + return (*timeType)(t) } type timeType format.TimeType @@ -155,9 +187,9 @@ func (t *timeType) baseType() Type { } } -func (t *timeType) useInt32() bool { return t.Unit.Millis != nil } +func (t *timeType) useInt32() bool { return isMillis(t.Unit) } -func (t *timeType) useInt64() bool { return t.Unit.Micros != nil } +func (t *timeType) useInt64() bool { return isMicros(t.Unit) } func (t *timeType) String() string { return (*format.TimeType)(t).String() } @@ -190,7 +222,7 @@ func (t *timeType) LogicalType() *format.LogicalType { case &timeNanoNotAdjustedToUTC: return &timeNanoNotAdjustedToUTCLogicalType default: - return &format.LogicalType{Time: (*format.TimeType)(t)} + return &format.LogicalType{Value: (*format.TimeType)(t)} } } @@ -241,17 +273,7 @@ func (t *timeType) AssignValue(dst reflect.Value, src Value) error { // Handle time.Duration specially to convert from the stored time unit to nanoseconds if dst.Type() == reflect.TypeFor[time.Duration]() { v := src.int64() - var nanos int64 - switch { - case t.Unit.Millis != nil: - nanos = v * int64(time.Millisecond) - case t.Unit.Micros != nil: - nanos = v * int64(time.Microsecond) - case t.Unit.Nanos != nil: - nanos = v - default: - nanos = v - } + nanos := v * int64(timeUnitDuration(t.Unit)) dst.SetInt(nanos) return nil } @@ -262,14 +284,14 @@ func (t *timeType) ConvertValue(val Value, typ Type) (Value, error) { switch src := typ.(type) { case *stringType: tz := t.tz() - if t.Unit.Micros != nil { + if isMicros(t.Unit) { return convertStringToTimeMicros(val, tz) } else { return convertStringToTimeMillis(val, tz) } case *timestampType: tz := t.tz() - if t.Unit.Micros != nil { + if isMicros(t.Unit) { return convertTimestampToTimeMicros(val, src.Unit, src.tz(), tz) } else { return convertTimestampToTimeMillis(val, src.Unit, src.tz(), tz) diff --git a/vendor/github.com/parquet-go/parquet-go/type_timestamp.go b/vendor/github.com/parquet-go/parquet-go/type_timestamp.go index 08d58633a1f..04fa6265285 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_timestamp.go +++ b/vendor/github.com/parquet-go/parquet-go/type_timestamp.go @@ -25,21 +25,21 @@ func TimestampAdjusted(unit TimeUnit, isAdjustedToUTC bool) Node { // Use pre-allocated instances for common cases timeUnit := unit.TimeUnit() if isAdjustedToUTC { - switch { - case timeUnit.Millis != nil: + switch timeUnit.Value.(type) { + case *format.MilliSeconds: return Leaf(×tampMilliAdjustedToUTC) - case timeUnit.Micros != nil: + case *format.MicroSeconds: return Leaf(×tampMicroAdjustedToUTC) - case timeUnit.Nanos != nil: + case *format.NanoSeconds: return Leaf(×tampNanoAdjustedToUTC) } } else { - switch { - case timeUnit.Millis != nil: + switch timeUnit.Value.(type) { + case *format.MilliSeconds: return Leaf(×tampMilliNotAdjustedToUTC) - case timeUnit.Micros != nil: + case *format.MicroSeconds: return Leaf(×tampMicroNotAdjustedToUTC) - case timeUnit.Nanos != nil: + case *format.NanoSeconds: return Leaf(×tampNanoNotAdjustedToUTC) } } @@ -49,56 +49,82 @@ func TimestampAdjusted(unit TimeUnit, isAdjustedToUTC bool) Node { var timestampMilliAdjustedToUTC = timestampType{ IsAdjustedToUTC: true, - Unit: format.TimeUnit{Millis: new(format.MilliSeconds)}, + Unit: format.TimeUnit{Value: new(format.MilliSeconds)}, } var timestampMicroAdjustedToUTC = timestampType{ IsAdjustedToUTC: true, - Unit: format.TimeUnit{Micros: new(format.MicroSeconds)}, + Unit: format.TimeUnit{Value: new(format.MicroSeconds)}, } var timestampNanoAdjustedToUTC = timestampType{ IsAdjustedToUTC: true, - Unit: format.TimeUnit{Nanos: new(format.NanoSeconds)}, + Unit: format.TimeUnit{Value: new(format.NanoSeconds)}, } var timestampMilliNotAdjustedToUTC = timestampType{ IsAdjustedToUTC: false, - Unit: format.TimeUnit{Millis: new(format.MilliSeconds)}, + Unit: format.TimeUnit{Value: new(format.MilliSeconds)}, } var timestampMicroNotAdjustedToUTC = timestampType{ IsAdjustedToUTC: false, - Unit: format.TimeUnit{Micros: new(format.MicroSeconds)}, + Unit: format.TimeUnit{Value: new(format.MicroSeconds)}, } var timestampNanoNotAdjustedToUTC = timestampType{ IsAdjustedToUTC: false, - Unit: format.TimeUnit{Nanos: new(format.NanoSeconds)}, + Unit: format.TimeUnit{Value: new(format.NanoSeconds)}, } var timestampMilliAdjustedToUTCLogicalType = format.LogicalType{ - Timestamp: (*format.TimestampType)(×tampMilliAdjustedToUTC), + Value: (*format.TimestampType)(×tampMilliAdjustedToUTC), } var timestampMicroAdjustedToUTCLogicalType = format.LogicalType{ - Timestamp: (*format.TimestampType)(×tampMicroAdjustedToUTC), + Value: (*format.TimestampType)(×tampMicroAdjustedToUTC), } var timestampNanoAdjustedToUTCLogicalType = format.LogicalType{ - Timestamp: (*format.TimestampType)(×tampNanoAdjustedToUTC), + Value: (*format.TimestampType)(×tampNanoAdjustedToUTC), } var timestampMilliNotAdjustedToUTCLogicalType = format.LogicalType{ - Timestamp: (*format.TimestampType)(×tampMilliNotAdjustedToUTC), + Value: (*format.TimestampType)(×tampMilliNotAdjustedToUTC), } var timestampMicroNotAdjustedToUTCLogicalType = format.LogicalType{ - Timestamp: (*format.TimestampType)(×tampMicroNotAdjustedToUTC), + Value: (*format.TimestampType)(×tampMicroNotAdjustedToUTC), } var timestampNanoNotAdjustedToUTCLogicalType = format.LogicalType{ - Timestamp: (*format.TimestampType)(×tampNanoNotAdjustedToUTC), + Value: (*format.TimestampType)(×tampNanoNotAdjustedToUTC), +} + +// canonicalTimestampType maps a decoded TimestampType onto the instance this +// package already declares for it. See canonicalIntType. +func canonicalTimestampType(t *format.TimestampType) *timestampType { + if t.IsAdjustedToUTC { + switch t.Unit.Value.(type) { + case *format.MilliSeconds: + return ×tampMilliAdjustedToUTC + case *format.MicroSeconds: + return ×tampMicroAdjustedToUTC + case *format.NanoSeconds: + return ×tampNanoAdjustedToUTC + } + } else { + switch t.Unit.Value.(type) { + case *format.MilliSeconds: + return ×tampMilliNotAdjustedToUTC + case *format.MicroSeconds: + return ×tampMicroNotAdjustedToUTC + case *format.NanoSeconds: + return ×tampNanoNotAdjustedToUTC + } + } + // No unit, or one we do not know; keep the value the file carried. + return (*timestampType)(t) } type timestampType format.TimestampType @@ -142,15 +168,15 @@ func (t *timestampType) LogicalType() *format.LogicalType { case ×tampNanoNotAdjustedToUTC: return ×tampNanoNotAdjustedToUTCLogicalType default: - return &format.LogicalType{Timestamp: (*format.TimestampType)(t)} + return &format.LogicalType{Value: (*format.TimestampType)(t)} } } func (t *timestampType) ConvertedType() *deprecated.ConvertedType { - switch { - case t.Unit.Millis != nil: + switch t.Unit.Value.(type) { + case *format.MilliSeconds: return &convertedTypes[deprecated.TimestampMillis] - case t.Unit.Micros != nil: + case *format.MicroSeconds: return &convertedTypes[deprecated.TimestampMicros] default: return nil @@ -200,17 +226,11 @@ func (t *timestampType) AssignValue(dst reflect.Value, src Value) error { unit := Nanosecond.TimeUnit() lt := t.LogicalType() - if lt != nil && lt.Timestamp != nil { - unit = lt.Timestamp.Unit + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok { + unit = ts.Unit } - nanos := src.int64() - switch { - case unit.Millis != nil: - nanos = nanos * 1e6 - case unit.Micros != nil: - nanos = nanos * 1e3 - } + nanos := src.int64() * int64(timeUnitDuration(unit)) val := time.Unix(0, nanos).UTC() dst.Set(reflect.ValueOf(val)) @@ -225,17 +245,11 @@ func (t *timestampType) AssignValue(dst reflect.Value, src Value) error { unit := Nanosecond.TimeUnit() lt := t.LogicalType() - if lt != nil && lt.Timestamp != nil { - unit = lt.Timestamp.Unit + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok { + unit = ts.Unit } - nanos := src.int64() - switch { - case unit.Millis != nil: - nanos = nanos * 1e6 - case unit.Micros != nil: - nanos = nanos * 1e3 - } + nanos := src.int64() * int64(timeUnitDuration(unit)) val := time.Unix(0, nanos).UTC() ptr := &val diff --git a/vendor/github.com/parquet-go/parquet-go/type_uuid.go b/vendor/github.com/parquet-go/parquet-go/type_uuid.go index 1cf2a4f94fc..c480e63bf7f 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_uuid.go +++ b/vendor/github.com/parquet-go/parquet-go/type_uuid.go @@ -14,7 +14,7 @@ import ( func UUID() Node { return Leaf(&uuidType{}) } var uuidLogicaType = format.LogicalType{ - UUID: new(format.UUIDType), + Value: new(format.UUIDType), } type uuidType format.UUIDType diff --git a/vendor/github.com/parquet-go/parquet-go/type_variant.go b/vendor/github.com/parquet-go/parquet-go/type_variant.go index 8d692e0e0c5..ecd93ad1df5 100644 --- a/vendor/github.com/parquet-go/parquet-go/type_variant.go +++ b/vendor/github.com/parquet-go/parquet-go/type_variant.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "reflect" + "slices" "strings" "github.com/parquet-go/parquet-go/deprecated" @@ -17,13 +18,51 @@ import ( // *Experimental*: Support for the VARIANT type is still being developed and subject to // change. // -// Initial support does not attempt to process the variant data. So reading and writing -// data of this type behaves as if it were just a group with two byte array fields, as -// if the logical type annotation were absent. This may change in the future. +// Go values written to a variant column with the "variant" struct tag are encoded +// with the variant binary encoding (see the variant subpackage); structs with +// Metadata and Value []byte fields pass the raw encoding through unchanged. When +// reading, files that store the column shredded are reconstructed automatically. // // [VARIANT logical type]: https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#variant func Variant() Node { - return variantNode{Group{"metadata": Required(Leaf(ByteArrayType)), "value": Required(Leaf(ByteArrayType))}} + return variantNode{variantOrderedGroup(Group{ + "metadata": Required(Leaf(ByteArrayType)), + "value": Required(Leaf(ByteArrayType)), + })} +} + +// variantOrderedGroup wraps a group so its fields are returned in the +// canonical variant order (metadata, value, typed_value; value before +// typed_value in nested groups) instead of alphabetically. Other engines +// (e.g. DuckDB) require the metadata and value columns to come first in +// the variant group. +func variantOrderedGroup(g Group) Node { + return orderedGroup{Group: g, order: []string{"metadata", "value", "typed_value"}} +} + +// orderedGroup is a Group whose fields are returned in an explicit order. +// Fields not listed in order come last, in alphabetical order. +type orderedGroup struct { + Group + order []string +} + +func (g orderedGroup) Fields() []Field { + fields := g.Group.Fields() + rank := func(name string) int { + for i, n := range g.order { + if n == name { + return i + } + } + return len(g.order) + } + sortedFields := make([]Field, len(fields)) + copy(sortedFields, fields) + slices.SortStableFunc(sortedFields, func(a, b Field) int { + return rank(a.Name()) - rank(b.Name()) + }) + return sortedFields } // ShreddedVariant constructs a node of shredded [VARIANT logical type]. It is a group @@ -48,9 +87,10 @@ func Variant() Node { // *Experimental*: Support for the VARIANT type is still being developed and subject to // change. // -// Initial support does not attempt to process the variant data. So reading and writing -// data of this type behaves as if it were just a group with the three described fields, -// as if the logical type annotation were absent. This may change in the future. +// Go values written to a shredded variant column with the "variant" struct tag are +// shredded per the [Parquet documentation]: values matching the shredded type are +// stored in the typed_value columns, and everything else is encoded into the +// appropriate value column. Reading reconstructs the variant from all columns. // // [VARIANT logical type]: https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#variant // [variant value types]: https://github.com/apache/parquet-format/blob/master/VariantShredding.md#shredded-value-types @@ -60,11 +100,11 @@ func ShreddedVariant(shreddedType Node) (Node, error) { if err != nil { return nil, err } - return variantNode{Group{ + return variantNode{variantOrderedGroup(Group{ "metadata": Required(Leaf(ByteArrayType)), "value": Optional(Leaf(ByteArrayType)), "typed_value": Optional(typedNode), - }}, nil + })}, nil } func variantTypedValueNode(node Node, fieldPath ...string) (typed Node, err error) { @@ -77,7 +117,7 @@ func variantTypedValueNode(node Node, fieldPath ...string) (typed Node, err erro return nil, errors.New("repeated types are not allowed unless they are part of a 3-level LIST logical type") } if lt := node.Type().LogicalType(); lt != nil { - switch lt := getLogicalType(lt).(type) { + switch lt := lt.Value.(type) { case *format.ListType: // We must first extract the inner list.element field of the 3-level LIST type. children := node.Fields() @@ -92,10 +132,10 @@ func variantTypedValueNode(node Node, fieldPath ...string) (typed Node, err erro if err != nil { return nil, err } - list := List(Required(Group{ + list := List(Required(variantOrderedGroup(Group{ "value": Optional(Leaf(ByteArrayType)), "typed_value": Optional(elementNode), - })) + }))) if node.ID() != 0 { return FieldID(list, node.ID()), nil } @@ -113,6 +153,8 @@ func variantTypedValueNode(node Node, fieldPath ...string) (typed Node, err erro case *format.TimestampType: case *format.StringType: case *format.UUIDType: + case nil: + // No logical type annotation. default: // No other logical types are allowed. return nil, fmt.Errorf("%s logical types are not allowed", lt) @@ -131,10 +173,10 @@ func variantTypedValueNode(node Node, fieldPath ...string) (typed Node, err erro if err != nil { return nil, err } - group[child.Name()] = Required(Group{ + group[child.Name()] = Required(variantOrderedGroup(Group{ "value": Optional(Leaf(ByteArrayType)), "typed_value": Optional(childNode), - }) + })) } if node.ID() != 0 { return FieldID(group, node.ID()), nil @@ -142,27 +184,13 @@ func variantTypedValueNode(node Node, fieldPath ...string) (typed Node, err erro return group, nil } -func getLogicalType(lt *format.LogicalType) any { - // We use reflection so we can always catch a logical type annotation. If a - // new one is added, we don't have to remember to update the switch above (unless - // a new one is added that is also supported as a variant value). - refVal := reflect.Indirect(reflect.ValueOf(lt)) - for i := range refVal.NumField() { - field := refVal.Field(i) - if field.CanInterface() && !field.IsZero() { - return field.Interface() - } - } - return nil -} - -type variantNode struct{ Group } +type variantNode struct{ Node } func (variantNode) Type() Type { return &variantType{} } type variantType format.VariantType -var variantLogicalType = format.LogicalType{Variant: new(format.VariantType)} +var variantLogicalType = format.LogicalType{Value: new(format.VariantType)} func (t *variantType) String() string { return (*format.VariantType)(t).String() } diff --git a/vendor/github.com/parquet-go/parquet-go/value.go b/vendor/github.com/parquet-go/parquet-go/value.go index b105dc45aa1..05d7f96b50e 100644 --- a/vendor/github.com/parquet-go/parquet-go/value.go +++ b/vendor/github.com/parquet-go/parquet-go/value.go @@ -269,16 +269,16 @@ func makeValue(k Kind, lt *format.LogicalType, v reflect.Value) Value { switch v.Type() { case reflect.TypeOf(time.Time{}): unit := Nanosecond.TimeUnit() - if lt != nil && lt.Timestamp != nil { - unit = lt.Timestamp.Unit + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok { + unit = ts.Unit } t := v.Interface().(time.Time) var val int64 - switch { - case unit.Millis != nil: + switch unit.Value.(type) { + case *format.MilliSeconds: val = t.UnixMilli() - case unit.Micros != nil: + case *format.MicroSeconds: val = t.UnixMicro() default: val = t.UnixNano() @@ -337,7 +337,7 @@ func makeValue(k Kind, lt *format.LogicalType, v reflect.Value) Value { case FixedLenByteArray: switch v.Kind() { case reflect.String: - if lt.UUID != nil { // uuid + if logicalTypeIs[*format.UUIDType](lt) { // uuid uuidStr := v.String() encoded, err := uuid.MustParse(uuidStr).MarshalBinary() if err != nil { @@ -788,7 +788,7 @@ func (v Value) String() string { case Float: return strconv.FormatFloat(float64(v.float()), 'g', -1, 32) case Double: - return strconv.FormatFloat(v.double(), 'g', -1, 32) + return strconv.FormatFloat(v.double(), 'g', -1, 64) case ByteArray, FixedLenByteArray: return string(v.byteArray()) default: @@ -802,14 +802,68 @@ func (v Value) GoString() string { return fmt.Sprintf("%#v", v) } // Level returns v with the repetition level, definition level, and column index // set to the values passed as arguments. // -// The method panics if either argument is negative. +// The method panics if any argument is negative or exceeds its maximum +// (MaxRepetitionLevel, MaxDefinitionLevel, MaxColumnIndex respectively). +// +// To mutate a single level field in place, see SetRepetitionLevel, +// SetDefinitionLevel, and SetColumnIndex, which the compiler can inline. func (v Value) Level(repetitionLevel, definitionLevel, columnIndex int) Value { - v.repetitionLevel = makeRepetitionLevel(repetitionLevel) - v.definitionLevel = makeDefinitionLevel(definitionLevel) - v.columnIndex = ^makeColumnIndex(columnIndex) + // MaxRepetitionLevel and MaxDefinitionLevel are both math.MaxUint8, so the + // two levels are bounds-checked with a single comparison: ORing them keeps + // the result in range only if both operands are; a negative value converts + // to a large uint and trips the check as well. + if uint(repetitionLevel)|uint(definitionLevel) > MaxRepetitionLevel || + uint(columnIndex) > MaxColumnIndex { + panicLevelOutOfRange(repetitionLevel, definitionLevel, columnIndex) + } + v.repetitionLevel = byte(repetitionLevel) + v.definitionLevel = byte(definitionLevel) + v.columnIndex = ^uint16(columnIndex) return v } +// SetRepetitionLevel sets the repetition level of v to the given value. +// +// Unlike Level, which sets all three level fields and returns a new Value, this +// method mutates a single field in place through a pointer receiver. Avoiding +// the value copy keeps it small enough for the compiler to inline, which lets +// the bounds check be eliminated entirely when the argument is provably in range +// (for example when forwarding an existing repetition level). Mutating a slice +// element in place (values[i].SetRepetitionLevel(...)) makes it a good fit for +// hot loops. +// +// The method panics if level is negative or greater than MaxRepetitionLevel. +func (v *Value) SetRepetitionLevel(level int) { + if uint(level) > MaxRepetitionLevel { + panicRepetitionLevelOutOfRange(level) + } + v.repetitionLevel = byte(level) +} + +// SetDefinitionLevel sets the definition level of v to the given value. +// +// See SetRepetitionLevel for the rationale behind the single-field setters. +// +// The method panics if level is negative or greater than MaxDefinitionLevel. +func (v *Value) SetDefinitionLevel(level int) { + if uint(level) > MaxDefinitionLevel { + panicDefinitionLevelOutOfRange(level) + } + v.definitionLevel = byte(level) +} + +// SetColumnIndex sets the column index of v to the given value. +// +// See SetRepetitionLevel for the rationale behind the single-field setters. +// +// The method panics if columnIndex is negative or greater than MaxColumnIndex. +func (v *Value) SetColumnIndex(columnIndex int) { + if uint(columnIndex) > MaxColumnIndex { + panicColumnIndexOutOfRange(columnIndex) + } + v.columnIndex = ^uint16(columnIndex) +} + // Clone returns a copy of v which does not share any pointers with it. func (v Value) Clone() Value { switch k := v.Kind(); k { @@ -1093,3 +1147,45 @@ type FixedLenByteArrayWriter interface { // is not a multiple of the expected item size. WriteFixedLenByteArrays(values []byte) (int, error) } + +// BE128Reader is an interface implemented by ValueReader instances which +// expose the content of a column of 128-bit big-endian byte array values. +type BE128Reader interface { + // Read 128-bit big-endian values into the buffer passed as argument, + // returning the number of values read. + // + // The method returns io.EOF when all values have been read. + ReadBE128s(values [][16]byte) (int, error) +} + +// BE128Writer is an interface implemented by ValueWriter instances which +// support writing columns of 128-bit big-endian byte array values. +type BE128Writer interface { + // Write 128-bit big-endian values. + // + // The method returns the number of values written, and any error that + // occurred while writing the values. + WriteBE128s(values [][16]byte) (int, error) +} + +// UUIDReader is an interface implemented by ValueReader instances which +// expose the content of a column of UUID values stored as 16-byte +// FIXED_LEN_BYTE_ARRAY with the UUID logical type. +type UUIDReader interface { + // Read UUID values into the buffer passed as argument, returning the + // number of values read. + // + // The method returns io.EOF when all values have been read. + ReadUUIDs(values []uuid.UUID) (int, error) +} + +// UUIDWriter is an interface implemented by ValueWriter instances which +// support writing columns of UUID values stored as 16-byte +// FIXED_LEN_BYTE_ARRAY with the UUID logical type. +type UUIDWriter interface { + // Write UUID values. + // + // The method returns the number of values written, and any error that + // occurred while writing the values. + WriteUUIDs(values []uuid.UUID) (int, error) +} diff --git a/vendor/github.com/parquet-go/parquet-go/variant/builder.go b/vendor/github.com/parquet-go/parquet-go/variant/builder.go new file mode 100644 index 00000000000..197f0259713 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/variant/builder.go @@ -0,0 +1,636 @@ +package variant + +import ( + "encoding/binary" + "errors" + "fmt" + "math" + "slices" + "strings" + + "github.com/google/uuid" +) + +// ValueBuilder is a streaming event sink for variant values. Callers describe +// a value as a sequence of events — scalars, or containers bracketed by +// Begin/End calls — and implementations consume the events without ever +// materializing the value as a tree. +// +// Exactly one value must be written: a single scalar event, or a single +// balanced container. Inside an object, every value must be preceded by a +// Field call naming it, and field names must be unique within their object +// (duplicates are an error). Errors (both misuse of the event sequence and +// implementation-specific failures) are sticky and reported by Err; events +// after an error are ignored. +// +// ValueBuilder is implemented by Builder, which encodes the events to variant +// binary, and by parquet.VariantColumnWriter, which shreds the events +// directly into parquet column buffers. +type ValueBuilder interface { + Null() + Bool(v bool) + Int8(v int8) + Int16(v int16) + Int32(v int32) + Int64(v int64) + Float(v float32) + Double(v float64) + String(v string) + Binary(v []byte) + Date(days int32) + Time(micros int64) + Timestamp(micros int64) + TimestampNTZ(micros int64) + TimestampNanos(nanos int64) + TimestampNTZNanos(nanos int64) + UUID(v uuid.UUID) + Decimal4(unscaled int32, scale byte) + Decimal8(unscaled int64, scale byte) + Decimal16(unscaled [16]byte, scale byte) + + // BeginObject starts an object value. Calls until the matching EndObject + // must alternate Field and value events. + BeginObject() + + // Field names the next value written as a field of the innermost open + // object. + Field(name string) + + // EndObject closes the innermost open object. + EndObject() + + // BeginArray starts an array value. Every value written until the + // matching EndArray is one element. + BeginArray() + + // EndArray closes the innermost open array. + EndArray() + + // Err returns the first error encountered, or nil. + Err() error +} + +// Write replays the value as a sequence of events on w. It is the bridge +// from the tree representation to any ValueBuilder. +func (v Value) Write(w ValueBuilder) { + switch v.basic { + case BasicObject: + w.BeginObject() + for _, f := range v.object.Fields { + w.Field(f.Name) + f.Value.Write(w) + } + w.EndObject() + case BasicArray: + w.BeginArray() + for _, e := range v.array.Elements { + e.Write(w) + } + w.EndArray() + case BasicShortString: + w.String(v.str) + default: + switch v.primitive { + case PrimitiveNull: + w.Null() + case PrimitiveTrue: + w.Bool(true) + case PrimitiveFalse: + w.Bool(false) + case PrimitiveInt8: + w.Int8(int8(v.i64)) + case PrimitiveInt16: + w.Int16(int16(v.i64)) + case PrimitiveInt32: + w.Int32(int32(v.i64)) + case PrimitiveInt64: + w.Int64(v.i64) + case PrimitiveFloat: + w.Float(float32(v.f64)) + case PrimitiveDouble: + w.Double(v.f64) + case PrimitiveString: + w.String(v.str) + case PrimitiveBinary: + w.Binary(v.bytes) + case PrimitiveDate: + w.Date(int32(v.i64)) + case PrimitiveTime: + w.Time(v.i64) + case PrimitiveTimestamp: + w.Timestamp(v.i64) + case PrimitiveTimestampNTZ: + w.TimestampNTZ(v.i64) + case PrimitiveTimestampNanos: + w.TimestampNanos(v.i64) + case PrimitiveTimestampNTZNanos: + w.TimestampNTZNanos(v.i64) + case PrimitiveUUID: + w.UUID(v.uuid) + case PrimitiveDecimal4: + w.Decimal4(int32(v.i64), v.scale) + case PrimitiveDecimal8: + w.Decimal8(v.i64, v.scale) + case PrimitiveDecimal16: + w.Decimal16(v.decimal16, v.scale) + default: + w.Null() + } + } +} + +// Builder is a streaming encoder for variant values: a ValueBuilder that +// encodes events directly to the variant binary format in a single growing +// buffer, without building a Value tree. +// +// Values are encoded as their events arrive. When a container closes, its +// header (field IDs, offsets) is spliced in front of the already-encoded +// children with one memmove, so encoding is a single pass with no per-value +// allocations beyond buffer growth. Object field values are kept in event +// order and only the header entries are sorted by field name, which the +// encoding permits (field IDs must be sorted, field offsets need not be +// monotonic). +// +// The zero value is ready to use and owns its metadata dictionary; Finish +// returns both the metadata and the value. NewBuilderWithMetadata creates a +// builder that interns field names into a shared, caller-owned dictionary, +// which is how multiple values (e.g. all residuals of one shredded row) +// share one dictionary. +// +// A Builder may be reused after Reset. Reset retains internal buffers, so a +// long-lived Builder encodes a stream of values with amortized zero +// allocation. A Builder must not be copied after first use. +type Builder struct { + meta *MetadataBuilder + ownMeta MetadataBuilder + + buf []byte + scratch []byte + + frames []builderFrame + fields []builderField // arena shared by all open object frames + elems []int // arena shared by all open array frames + + pendingField bool // inside an object, a Field awaits its value + complete bool // one complete top-level value has been written + err error +} + +type builderFrame struct { + isObject bool + start int // buf offset where the container's first child begins + fieldsBase int // objects: base of this frame's entries in the fields arena + elemsBase int // arrays: base of this frame's element starts in the elems arena +} + +type builderField struct { + id int + start int // buf offset where the field's value begins +} + +// NewBuilderWithMetadata returns a Builder that interns object field names +// into the given shared metadata dictionary instead of an internal one. +// Finish builds the shared dictionary; callers encoding multiple values +// against one dictionary typically use Bytes and build the metadata +// themselves once. +func NewBuilderWithMetadata(meta *MetadataBuilder) *Builder { + return &Builder{meta: meta} +} + +func (b *Builder) metadata() *MetadataBuilder { + if b.meta == nil { + b.meta = &b.ownMeta + } + return b.meta +} + +// Err returns the first error encountered, or nil. +func (b *Builder) Err() error { return b.err } + +func (b *Builder) fail(format string, args ...any) { + if b.err == nil { + b.err = fmt.Errorf("variant builder: "+format, args...) + } +} + +// Reset clears the builder for reuse, retaining internal buffers. If the +// builder owns its metadata dictionary the dictionary is cleared too; a +// shared dictionary (NewBuilderWithMetadata) is left untouched. +func (b *Builder) Reset() { + if b.meta == &b.ownMeta { + b.ownMeta.Reset() + } + b.buf = b.buf[:0] + b.frames = b.frames[:0] + b.fields = b.fields[:0] + b.elems = b.elems[:0] + b.pendingField = false + b.complete = false + b.err = nil +} + +// Finish returns the encoded metadata and value. It fails if no value or an +// incomplete value has been written. The value slice aliases the builder's +// internal buffer and is invalidated by Reset or further writes, the same +// as Bytes; the metadata slice is freshly allocated. +func (b *Builder) Finish() (metadata, value []byte, err error) { + value, err = b.Bytes() + if err != nil { + return nil, nil, err + } + meta := b.metadata() + // Dictionary offsets are at most 4 bytes wide; MetadataBuilder.AppendTo + // would silently truncate a larger dictionary. + if uint64(meta.Size()) > math.MaxUint32 { + return nil, nil, fmt.Errorf("variant builder: metadata dictionary of %d bytes exceeds the variant format's 4 GiB limit", meta.Size()) + } + metadata = meta.AppendTo(nil) + return metadata, value, nil +} + +// Bytes returns the encoded value bytes without building the metadata. The +// returned slice aliases the builder's internal buffer and is invalidated by +// Reset or further writes. +func (b *Builder) Bytes() ([]byte, error) { + switch { + case b.err != nil: + return nil, b.err + case len(b.frames) > 0: + return nil, errors.New("variant builder: unclosed object or array") + case !b.complete: + return nil, errors.New("variant builder: no value written") + } + return b.buf, nil +} + +// beginValue validates that a value event is legal in the current state and +// records array element boundaries. It reports whether to proceed. +func (b *Builder) beginValue() bool { + if b.err != nil { + return false + } + if n := len(b.frames); n == 0 { + if b.complete { + b.fail("more than one top-level value") + return false + } + } else if f := &b.frames[n-1]; f.isObject { + if !b.pendingField { + b.fail("value written inside an object without a Field call") + return false + } + b.pendingField = false + } else { + b.elems = append(b.elems, len(b.buf)) + } + return true +} + +func (b *Builder) endValue() { + if len(b.frames) == 0 { + b.complete = true + } +} + +func (b *Builder) appendScalar(data ...byte) { + if b.beginValue() { + b.buf = append(b.buf, data...) + b.endValue() + } +} + +func (b *Builder) Null() { b.appendScalar(makeHeader(BasicPrimitive, byte(PrimitiveNull))) } + +func (b *Builder) Bool(v bool) { + p := PrimitiveFalse + if v { + p = PrimitiveTrue + } + b.appendScalar(makeHeader(BasicPrimitive, byte(p))) +} + +func (b *Builder) Int8(v int8) { + b.appendScalar(makeHeader(BasicPrimitive, byte(PrimitiveInt8)), byte(v)) +} + +func (b *Builder) Int16(v int16) { b.scalar16(PrimitiveInt16, uint16(v)) } + +func (b *Builder) Int32(v int32) { b.scalar32(PrimitiveInt32, uint32(v)) } + +func (b *Builder) Int64(v int64) { b.scalar64(PrimitiveInt64, uint64(v)) } + +func (b *Builder) Float(v float32) { b.scalar32(PrimitiveFloat, math.Float32bits(v)) } + +func (b *Builder) Double(v float64) { b.scalar64(PrimitiveDouble, math.Float64bits(v)) } + +func (b *Builder) String(v string) { + if !b.beginValue() { + return + } + if uint64(len(v)) > math.MaxUint32 { + b.fail("string of %d bytes exceeds the variant format's 4 GiB limit", len(v)) + return + } + if len(v) <= 63 { + b.buf = append(b.buf, makeHeader(BasicShortString, byte(len(v)))) + } else { + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(PrimitiveString)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(b.buf[len(b.buf)-4:], uint32(len(v))) + } + b.buf = append(b.buf, v...) + b.endValue() +} + +func (b *Builder) Binary(v []byte) { + if !b.beginValue() { + return + } + if uint64(len(v)) > math.MaxUint32 { + b.fail("binary value of %d bytes exceeds the variant format's 4 GiB limit", len(v)) + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(PrimitiveBinary)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(b.buf[len(b.buf)-4:], uint32(len(v))) + b.buf = append(b.buf, v...) + b.endValue() +} + +func (b *Builder) Date(days int32) { b.scalar32(PrimitiveDate, uint32(days)) } + +func (b *Builder) Time(micros int64) { b.scalar64(PrimitiveTime, uint64(micros)) } + +func (b *Builder) Timestamp(micros int64) { b.scalar64(PrimitiveTimestamp, uint64(micros)) } + +func (b *Builder) TimestampNTZ(micros int64) { b.scalar64(PrimitiveTimestampNTZ, uint64(micros)) } + +func (b *Builder) TimestampNanos(nanos int64) { b.scalar64(PrimitiveTimestampNanos, uint64(nanos)) } + +func (b *Builder) TimestampNTZNanos(nanos int64) { + b.scalar64(PrimitiveTimestampNTZNanos, uint64(nanos)) +} + +func (b *Builder) UUID(v uuid.UUID) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(PrimitiveUUID))) + b.buf = append(b.buf, v[:]...) + b.endValue() +} + +func (b *Builder) Decimal4(unscaled int32, scale byte) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(PrimitiveDecimal4)), scale, 0, 0, 0, 0) + binary.LittleEndian.PutUint32(b.buf[len(b.buf)-4:], uint32(unscaled)) + b.endValue() +} + +func (b *Builder) Decimal8(unscaled int64, scale byte) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(PrimitiveDecimal8)), scale, 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(b.buf[len(b.buf)-8:], uint64(unscaled)) + b.endValue() +} + +func (b *Builder) Decimal16(unscaled [16]byte, scale byte) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(PrimitiveDecimal16)), scale) + b.buf = append(b.buf, unscaled[:]...) + b.endValue() +} + +func (b *Builder) scalar16(p PrimitiveType, v uint16) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(p)), 0, 0) + binary.LittleEndian.PutUint16(b.buf[len(b.buf)-2:], v) + b.endValue() +} + +func (b *Builder) scalar32(p PrimitiveType, v uint32) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(p)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(b.buf[len(b.buf)-4:], v) + b.endValue() +} + +func (b *Builder) scalar64(p PrimitiveType, v uint64) { + if !b.beginValue() { + return + } + b.buf = append(b.buf, makeHeader(BasicPrimitive, byte(p)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(b.buf[len(b.buf)-8:], v) + b.endValue() +} + +func (b *Builder) BeginObject() { + if !b.beginValue() { + return + } + b.frames = append(b.frames, builderFrame{ + isObject: true, + start: len(b.buf), + fieldsBase: len(b.fields), + }) +} + +func (b *Builder) Field(name string) { + if b.err != nil { + return + } + n := len(b.frames) + if n == 0 || !b.frames[n-1].isObject { + b.fail("Field %q outside of an object", name) + return + } + if b.pendingField { + b.fail("Field %q: previous field has no value", name) + return + } + id := b.metadata().Add(name) + b.fields = append(b.fields, builderField{ + id: id, + start: len(b.buf), + }) + b.pendingField = true +} + +func (b *Builder) EndObject() { + if b.err != nil { + return + } + n := len(b.frames) + if n == 0 || !b.frames[n-1].isObject { + b.fail("EndObject without matching BeginObject") + return + } + meta := b.metadata() + if b.pendingField { + b.fail("EndObject: field %q has no value", meta.stringAt(b.fields[len(b.fields)-1].id)) + return + } + f := b.frames[n-1] + entries := b.fields[f.fieldsBase:] + + // The encoding requires field IDs sorted lexicographically by name; + // field values stay where they were written, offsets need not be + // monotonic. Names are resolved from the metadata slab at close time + // so Field does not retain views that a later Add could invalidate. + slices.SortFunc(entries, func(a, c builderField) int { + return strings.Compare(meta.stringAt(a.id), meta.stringAt(c.id)) + }) + for i := 1; i < len(entries); i++ { + // Names are interned, so equal names always share one id. + if entries[i].id == entries[i-1].id { + b.fail("duplicate object field %q", meta.stringAt(entries[i].id)) + return + } + } + + numFields := len(entries) + contentSize := len(b.buf) - f.start + // Offsets are at most 4 bytes wide, so a container whose encoded + // children exceed math.MaxUint32 bytes is unrepresentable; failing + // beats the silent truncation of writeUint. Field offsets and counts + // are bounded by contentSize, so this one check covers them too. + if uint64(contentSize) > math.MaxUint32 { + b.fail("object content of %d bytes exceeds the variant format's 4 GiB limit", contentSize) + return + } + maxID := 0 + for i := range entries { + if entries[i].id > maxID { + maxID = entries[i].id + } + } + + fieldIDSzCode := offsetSizeCode(maxID) + fieldIDSz := offsetSize(fieldIDSzCode) + offsetSzCode := offsetSizeCode(contentSize) + offsetSz := offsetSize(offsetSzCode) + + isLarge := byte(0) + numElemSize := 1 + if numFields > 255 { + isLarge = 1 + numElemSize = 4 + } + + headerSize := 1 + numElemSize + numFields*fieldIDSz + (numFields+1)*offsetSz + h := b.header(headerSize) + h[0] = byte(BasicObject) | (offsetSzCode << 2) | (fieldIDSzCode << 4) | (isLarge << 6) + pos := 1 + if isLarge == 1 { + binary.LittleEndian.PutUint32(h[pos:], uint32(numFields)) + pos += 4 + } else { + h[pos] = byte(numFields) + pos++ + } + for i := range entries { + writeUint(h[pos:], entries[i].id, fieldIDSz) + pos += fieldIDSz + } + for i := range entries { + writeUint(h[pos:], entries[i].start-f.start, offsetSz) + pos += offsetSz + } + writeUint(h[pos:], contentSize, offsetSz) + + b.splice(f.start, h) + b.fields = b.fields[:f.fieldsBase] + b.frames = b.frames[:n-1] + b.endValue() +} + +func (b *Builder) BeginArray() { + if !b.beginValue() { + return + } + b.frames = append(b.frames, builderFrame{ + start: len(b.buf), + elemsBase: len(b.elems), + }) +} + +func (b *Builder) EndArray() { + if b.err != nil { + return + } + n := len(b.frames) + if n == 0 || b.frames[n-1].isObject { + b.fail("EndArray without matching BeginArray") + return + } + f := b.frames[n-1] + starts := b.elems[f.elemsBase:] + + numElems := len(starts) + contentSize := len(b.buf) - f.start + // See the matching check in EndObject. + if uint64(contentSize) > math.MaxUint32 { + b.fail("array content of %d bytes exceeds the variant format's 4 GiB limit", contentSize) + return + } + + offsetSzCode := offsetSizeCode(contentSize) + offsetSz := offsetSize(offsetSzCode) + + isLarge := byte(0) + numElemSize := 1 + if numElems > 255 { + isLarge = 1 + numElemSize = 4 + } + + headerSize := 1 + numElemSize + (numElems+1)*offsetSz + h := b.header(headerSize) + h[0] = byte(BasicArray) | (offsetSzCode << 2) | (isLarge << 4) + pos := 1 + if isLarge == 1 { + binary.LittleEndian.PutUint32(h[pos:], uint32(numElems)) + pos += 4 + } else { + h[pos] = byte(numElems) + pos++ + } + for _, start := range starts { + writeUint(h[pos:], start-f.start, offsetSz) + pos += offsetSz + } + writeUint(h[pos:], contentSize, offsetSz) + + b.splice(f.start, h) + b.elems = b.elems[:f.elemsBase] + b.frames = b.frames[:n-1] + b.endValue() +} + +// header returns a zeroed scratch slice of the given size for building a +// container header. +func (b *Builder) header(size int) []byte { + if cap(b.scratch) < size { + b.scratch = make([]byte, size) + } + h := b.scratch[:size] + clear(h) + return h +} + +// splice inserts header at position start, shifting the container's encoded +// children right by one memmove. +func (b *Builder) splice(start int, header []byte) { + n := len(header) + b.buf = append(b.buf, header...) + copy(b.buf[start+n:], b.buf[start:len(b.buf)-n]) + copy(b.buf[start:], header) +} diff --git a/vendor/github.com/parquet-go/parquet-go/variant/decoding.go b/vendor/github.com/parquet-go/parquet-go/variant/decoding.go index d426edbe2da..5023e339f25 100644 --- a/vendor/github.com/parquet-go/parquet-go/variant/decoding.go +++ b/vendor/github.com/parquet-go/parquet-go/variant/decoding.go @@ -5,10 +5,18 @@ import ( "errors" "fmt" "math" + "unicode/utf8" ) // Decode decodes a variant value from its binary representation using the // given metadata dictionary. +// +// Decode rejects input the spec declares invalid: strings that are not valid +// UTF-8, objects with duplicate field names, and structures whose declared +// sizes exceed the data. It accepts input that is non-canonical but +// unambiguous, as the spec directs for readers: reserved header bits are +// ignored, object fields need not be listed in lexicographic order, and +// bytes past the end of the value are ignored (values are self-delimiting). func Decode(m Metadata, data []byte) (Value, error) { if len(data) == 0 { return Null(), errors.New("variant value: empty data") @@ -35,8 +43,15 @@ func decodeValue(m Metadata, data []byte) (Value, int, error) { if len(data) < 1+length { return Null(), 0, fmt.Errorf("variant value: short string length %d exceeds data", length) } - v := Value{basic: BasicShortString, str: string(data[1 : 1+length])} - return v, 1 + length, nil + if !utf8.Valid(data[1 : 1+length]) { + return Null(), 0, errors.New("variant value: short string is not valid UTF-8") + } + // Normalize to the string primitive so the value re-encodes + // correctly. VariantEncoding.md: "The 'short string' basic type + // may be used as an optimization to fold string length into the + // type byte for strings less than 64 bytes. It is semantically + // identical to the 'string' primitive type." + return String(string(data[1 : 1+length])), 1 + length, nil case BasicObject: return decodeObject(m, header, data[1:]) case BasicArray: @@ -88,17 +103,31 @@ func decodePrimitive(pt PrimitiveType, data []byte) (Value, int, error) { if len(data) < 4 { return Null(), 0, errors.New("variant value: not enough data for string length") } + // On 32-bit platforms a 4-byte length above math.MaxInt32 + // overflows int and is negative, and 4+length can overflow the + // same way, so the bounds check avoids the addition. Neither + // overflow can happen on 64-bit platforms. length := int(binary.LittleEndian.Uint32(data[:4])) - if len(data) < 4+length { + if length < 0 || length > len(data)-4 { return Null(), 0, fmt.Errorf("variant value: string length %d exceeds data", length) } + // VariantEncoding.md: "All strings within the Variant binary + // format must be UTF-8 encoded. This includes the dictionary key + // string values, the 'short string' values, and the 'long string' + // values." (Short strings and dictionary entries are validated at + // their own decode sites.) + if !utf8.Valid(data[4 : 4+length]) { + return Null(), 0, errors.New("variant value: string is not valid UTF-8") + } return String(string(data[4 : 4+length])), 5 + length, nil case PrimitiveBinary: if len(data) < 4 { return Null(), 0, errors.New("variant value: not enough data for binary length") } length := int(binary.LittleEndian.Uint32(data[:4])) - if len(data) < 4+length { + // The check is phrased for 32-bit overflow safety; see the string + // case above. + if length < 0 || length > len(data)-4 { return Null(), 0, fmt.Errorf("variant value: binary length %d exceeds data", length) } b := make([]byte, length) @@ -124,6 +153,16 @@ func decodePrimitive(pt PrimitiveType, data []byte) (Value, int, error) { return Null(), 0, errors.New("variant value: not enough data for time") } return Time(int64(binary.LittleEndian.Uint64(data[:8]))), 9, nil + case PrimitiveTimestampNanos: + if len(data) < 8 { + return Null(), 0, errors.New("variant value: not enough data for timestamp nanos") + } + return TimestampNanos(int64(binary.LittleEndian.Uint64(data[:8]))), 9, nil + case PrimitiveTimestampNTZNanos: + if len(data) < 8 { + return Null(), 0, errors.New("variant value: not enough data for timestamp_ntz nanos") + } + return TimestampNTZNanos(int64(binary.LittleEndian.Uint64(data[:8]))), 9, nil case PrimitiveUUID: if len(data) < 16 { return Null(), 0, errors.New("variant value: not enough data for uuid") @@ -159,8 +198,11 @@ func decodePrimitive(pt PrimitiveType, data []byte) (Value, int, error) { } func decodeObject(m Metadata, header byte, data []byte) (Value, int, error) { - fieldIDSizeCode := (header >> 2) & 0x03 - offsetSzCode := (header >> 4) & 0x03 + // Object header byte layout (see encodeObject): bits 2-3 hold + // field_offset_size_minus_one, bits 4-5 hold field_id_size_minus_one, + // bit 6 holds is_large. + offsetSzCode := (header >> 2) & 0x03 + fieldIDSizeCode := (header >> 4) & 0x03 isLarge := (header >> 6) & 0x01 fieldIDSize := offsetSize(fieldIDSizeCode) @@ -184,6 +226,15 @@ func decodeObject(m Metadata, header byte, data []byte) (Value, int, error) { pos += 1 } + // Validate the declared element count against the available data + // before allocating, to reject corrupt inputs with absurd sizes. + // numElements < 0 happens only on 32-bit platforms, where a 4-byte + // count above math.MaxInt32 overflows int. + if remaining := len(data) - pos; numElements < 0 || + remaining/(fieldIDSize+offsetSz) < numElements { + return Null(), 0, fmt.Errorf("variant value: object element count %d exceeds data", numElements) + } + // Read field IDs fieldIDs := make([]int, numElements) for i := range numElements { @@ -206,23 +257,60 @@ func decodeObject(m Metadata, header byte, data []byte) (Value, int, error) { pos += n } - // Value data starts at pos + // Value data starts at pos. The last offset is the total size of the + // value data region. Fields must NOT be sliced as [offset[i], + // offset[i+1]) — per VariantEncoding.md, "the actual value entries do + // not need to be in any particular order. This implies that the + // field_offset values may not be monotonically increasing." (Spark + // writes such objects.) Each value is self-delimiting; the offset only + // determines where it starts. valueDataStart := pos + valueDataEnd := valueDataStart + offsets[numElements] + // valueDataEnd < valueDataStart rejects a last offset that overflowed + // int to a negative value on 32-bit platforms. + if valueDataEnd > len(data) || valueDataEnd < valueDataStart { + return Null(), 0, errors.New("variant value: object value data exceeds input") + } fields := make([]Field, numElements) + // VariantEncoding.md: "Field names are required to be unique for each + // object. It is an error for an object to contain two fields with the + // same name, whether or not they have distinct dictionary IDs." (The + // last clause is why the check compares names, not field IDs.) + // + // The spec also requires fields to be listed in lexicographic order of + // their names, so in well-formed input a duplicate is adjacent to its + // twin and one comparison against the previous name detects it. The + // map is only allocated for inputs that violate the sort order (which + // are otherwise accepted, for compatibility with lenient writers). + var seen map[string]struct{} for i := range numElements { name, err := m.Lookup(fieldIDs[i]) if err != nil { return Null(), 0, fmt.Errorf("variant value: object field %d: %w", i, err) } + if seen == nil && i > 0 && name <= fields[i-1].Name { + if name == fields[i-1].Name { + return Null(), 0, fmt.Errorf("variant value: duplicate object field %q", name) + } + seen = make(map[string]struct{}, numElements) + for _, f := range fields[:i] { + seen[f.Name] = struct{}{} + } + } + if seen != nil { + if _, dup := seen[name]; dup { + return Null(), 0, fmt.Errorf("variant value: duplicate object field %q", name) + } + seen[name] = struct{}{} + } valueStart := valueDataStart + offsets[i] - valueEnd := valueDataStart + offsets[i+1] - if valueStart > len(data) || valueEnd > len(data) || valueStart > valueEnd { + if valueStart < valueDataStart || valueStart > valueDataEnd { return Null(), 0, fmt.Errorf("variant value: object field %d: invalid value offset", i) } - v, _, err := decodeValue(m, data[valueStart:valueEnd]) + v, _, err := decodeValue(m, data[valueStart:valueDataEnd]) if err != nil { return Null(), 0, fmt.Errorf("variant value: object field %q: %w", name, err) } @@ -230,7 +318,7 @@ func decodeObject(m Metadata, header byte, data []byte) (Value, int, error) { fields[i] = Field{Name: name, Value: v} } - totalConsumed := 1 + valueDataStart + offsets[numElements] // +1 for header byte + totalConsumed := 1 + valueDataEnd // +1 for header byte return MakeObject(fields), totalConsumed, nil } @@ -258,6 +346,17 @@ func decodeArray(m Metadata, header byte, data []byte) (Value, int, error) { pos += 1 } + // Validate the declared element count against the available data + // before allocating, to reject corrupt inputs with absurd sizes. + // numElements < 0 happens only on 32-bit platforms, where a 4-byte + // count above math.MaxInt32 overflows int; the comparison is phrased + // as <= numElements rather than < numElements+1 (there are + // numElements+1 offsets) so the addition cannot overflow the same way. + if remaining := len(data) - pos; numElements < 0 || + remaining/offsetSz <= numElements { + return Null(), 0, fmt.Errorf("variant value: array element count %d exceeds data", numElements) + } + // Read offsets (numElements+1) offsets := make([]int, numElements+1) for i := range numElements + 1 { @@ -276,7 +375,11 @@ func decodeArray(m Metadata, header byte, data []byte) (Value, int, error) { for i := range numElements { elemStart := valueDataStart + offsets[i] elemEnd := valueDataStart + offsets[i+1] - if elemStart > len(data) || elemEnd > len(data) || elemStart > elemEnd { + // elemStart < 0 happens only on 32-bit platforms, where a 4-byte + // offset above math.MaxInt32 overflows int; without the check the + // slice below would panic. The remaining conditions imply + // elemStart <= elemEnd <= len(data). + if elemStart < 0 || elemEnd > len(data) || elemStart > elemEnd { return Null(), 0, fmt.Errorf("variant value: array element %d: invalid offset", i) } diff --git a/vendor/github.com/parquet-go/parquet-go/variant/encoding.go b/vendor/github.com/parquet-go/parquet-go/variant/encoding.go index 5767d13bcc9..d2b65a83dd2 100644 --- a/vendor/github.com/parquet-go/parquet-go/variant/encoding.go +++ b/vendor/github.com/parquet-go/parquet-go/variant/encoding.go @@ -2,8 +2,14 @@ package variant import ( "encoding/binary" + "fmt" "math" + "reflect" "sort" + "sync" + "time" + + "github.com/google/uuid" ) // Encode encodes a variant Value into its binary representation. @@ -12,9 +18,31 @@ import ( func Encode(b *MetadataBuilder, v Value) []byte { switch v.basic { case BasicObject: - return encodeObject(b, v.object) + enc := getEncoder(b) + + start, end, err := enc.encodeValueObject(v.object) + if err != nil { + releaseEncoder(enc) + return nil + } + res := make([]byte, end-start) + copy(res, enc.scratch[start:end]) + + releaseEncoder(enc) + return res case BasicArray: - return encodeArray(b, v.array) + enc := getEncoder(b) + + start, end, err := enc.encodeValueArray(v.array) + if err != nil { + releaseEncoder(enc) + return nil + } + res := make([]byte, end-start) + copy(res, enc.scratch[start:end]) + + releaseEncoder(enc) + return res default: return encodePrimitive(v) } @@ -58,13 +86,11 @@ func encodePrimitive(v Value) []byte { case PrimitiveString: s := v.str if len(s) <= 63 { - // Use short string encoding buf := make([]byte, 1+len(s)) buf[0] = makeHeader(BasicShortString, byte(len(s))) copy(buf[1:], s) return buf } - // Long string: primitive string type + 4-byte length + data buf := make([]byte, 5+len(s)) buf[0] = makeHeader(BasicPrimitive, byte(PrimitiveString)) binary.LittleEndian.PutUint32(buf[1:], uint32(len(s))) @@ -96,6 +122,16 @@ func encodePrimitive(v Value) []byte { buf[0] = makeHeader(BasicPrimitive, byte(PrimitiveTime)) binary.LittleEndian.PutUint64(buf[1:], uint64(v.i64)) return buf + case PrimitiveTimestampNanos: + buf := make([]byte, 9) + buf[0] = makeHeader(BasicPrimitive, byte(PrimitiveTimestampNanos)) + binary.LittleEndian.PutUint64(buf[1:], uint64(v.i64)) + return buf + case PrimitiveTimestampNTZNanos: + buf := make([]byte, 9) + buf[0] = makeHeader(BasicPrimitive, byte(PrimitiveTimestampNTZNanos)) + binary.LittleEndian.PutUint64(buf[1:], uint64(v.i64)) + return buf case PrimitiveUUID: buf := make([]byte, 17) buf[0] = makeHeader(BasicPrimitive, byte(PrimitiveUUID)) @@ -124,59 +160,408 @@ func encodePrimitive(v Value) []byte { } } -func encodeObject(b *MetadataBuilder, obj Object) []byte { +// makeHeader constructs a value_metadata byte. +func makeHeader(basic BasicType, valueHeader byte) byte { + return byte(basic) | (valueHeader << 2) +} + +type encoder struct { + b *MetadataBuilder + scratch []byte + temp []byte + positions []elementPos + fields []encodedField + offsets []int +} + +var encoderPool = sync.Pool{ + New: func() any { + return &encoder{ + scratch: make([]byte, 0, 1024), + temp: make([]byte, 0, 1024), + positions: make([]elementPos, 0, 32), + fields: make([]encodedField, 0, 32), + offsets: make([]int, 0, 32), + } + }, +} + +const ( + maxPooledEncoderBytes = 1 << 20 + maxPooledEncoderItems = 4096 +) + +func getEncoder(b *MetadataBuilder) *encoder { + enc := encoderPool.Get().(*encoder) + enc.b = b + enc.scratch = enc.scratch[:0] + enc.temp = enc.temp[:0] + enc.positions = enc.positions[:0] + enc.fields = enc.fields[:0] + enc.offsets = enc.offsets[:0] + return enc +} + +func releaseEncoder(enc *encoder) { + enc.b = nil + if cap(enc.scratch) > maxPooledEncoderBytes { + enc.scratch = nil + } else { + enc.scratch = enc.scratch[:0] + } + if cap(enc.temp) > maxPooledEncoderBytes { + enc.temp = nil + } else { + enc.temp = enc.temp[:0] + } + if cap(enc.positions) > maxPooledEncoderItems { + enc.positions = nil + } else { + enc.positions = enc.positions[:0] + } + if cap(enc.fields) > maxPooledEncoderItems { + enc.fields = nil + } else { + enc.fields = enc.fields[:0] + } + if cap(enc.offsets) > maxPooledEncoderItems { + enc.offsets = nil + } else { + enc.offsets = enc.offsets[:0] + } + encoderPool.Put(enc) +} + +type encodedField struct { + id int + name string + start int + end int +} + +type elementPos struct { + start int + end int +} + +var testHookVerifyArrayLayout func(e *encoder, positions []elementPos) +var testHookVerifyObjectLayout func(e *encoder, entries []encodedField) + +func (e *encoder) encodeValuePrimitive(v Value) (start, end int) { + start = len(e.scratch) + switch v.primitive { + case PrimitiveNull: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveNull))) + case PrimitiveTrue: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveTrue))) + case PrimitiveFalse: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveFalse))) + case PrimitiveInt8: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveInt8)), byte(v.i64)) + case PrimitiveInt16: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveInt16)), 0, 0) + binary.LittleEndian.PutUint16(e.scratch[start+1:], uint16(v.i64)) + case PrimitiveInt32: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveInt32)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(e.scratch[start+1:], uint32(v.i64)) + case PrimitiveInt64: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveInt64)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], uint64(v.i64)) + case PrimitiveFloat: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveFloat)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(e.scratch[start+1:], math.Float32bits(float32(v.f64))) + case PrimitiveDouble: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveDouble)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], math.Float64bits(v.f64)) + case PrimitiveString: + s := v.str + if len(s) <= 63 { + e.scratch = append(e.scratch, makeHeader(BasicShortString, byte(len(s)))) + e.scratch = append(e.scratch, s...) + } else { + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveString)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(e.scratch[start+1:], uint32(len(s))) + e.scratch = append(e.scratch, s...) + } + case PrimitiveBinary: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveBinary)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(e.scratch[start+1:], uint32(len(v.bytes))) + e.scratch = append(e.scratch, v.bytes...) + case PrimitiveDate: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveDate)), 0, 0, 0, 0) + binary.LittleEndian.PutUint32(e.scratch[start+1:], uint32(v.i64)) + case PrimitiveTimestamp: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveTimestamp)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], uint64(v.i64)) + case PrimitiveTimestampNTZ: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveTimestampNTZ)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], uint64(v.i64)) + case PrimitiveTime: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveTime)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], uint64(v.i64)) + case PrimitiveTimestampNanos: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveTimestampNanos)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], uint64(v.i64)) + case PrimitiveTimestampNTZNanos: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveTimestampNTZNanos)), 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+1:], uint64(v.i64)) + case PrimitiveUUID: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveUUID))) + e.scratch = append(e.scratch, v.uuid[:]...) + case PrimitiveDecimal4: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveDecimal4)), v.scale, 0, 0, 0, 0) + binary.LittleEndian.PutUint32(e.scratch[start+2:], uint32(v.i64)) + case PrimitiveDecimal8: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveDecimal8)), v.scale, 0, 0, 0, 0, 0, 0, 0, 0) + binary.LittleEndian.PutUint64(e.scratch[start+2:], uint64(v.i64)) + case PrimitiveDecimal16: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveDecimal16)), v.scale) + e.scratch = append(e.scratch, v.decimal16[:]...) + default: + e.scratch = append(e.scratch, makeHeader(BasicPrimitive, byte(PrimitiveNull))) + } + end = len(e.scratch) + return start, end +} + +func (e *encoder) encodeValue(v Value) (start, end int, err error) { + switch v.basic { + case BasicObject: + return e.encodeValueObject(v.object) + case BasicArray: + return e.encodeValueArray(v.array) + default: + start, end = e.encodeValuePrimitive(v) + return start, end, nil + } +} + +func (e *encoder) encodeValueArray(arr Array) (start, end int, err error) { + n := len(arr.Elements) + if n == 0 { + return e.buildArrayBytes(nil) + } + + savedStart := len(e.positions) + if cap(e.positions) < savedStart+n { + newCap := max(cap(e.positions)*2, savedStart+n) + newP := make([]elementPos, len(e.positions), newCap) + copy(newP, e.positions) + e.positions = newP + } + e.positions = e.positions[:savedStart+n] + positions := e.positions[savedStart : savedStart+n] + + for i := range n { + pStart, pEnd, err := e.encodeValue(arr.Elements[i]) + if err != nil { + e.positions = e.positions[:savedStart] + return 0, 0, err + } + positions[i] = elementPos{start: pStart, end: pEnd} + } + + resStart, resEnd, err := e.buildArrayBytes(positions) + e.positions = e.positions[:savedStart] + return resStart, resEnd, err +} + +func (e *encoder) encodeValueObject(obj Object) (start, end int, err error) { n := len(obj.Fields) + if n == 0 { + return e.buildObjectBytes(nil) + } - // Register all field names and get their IDs - type fieldEntry struct { - id int - name string - valueBytes []byte + savedStart := len(e.fields) + if cap(e.fields) < savedStart+n { + newCap := max(cap(e.fields)*2, savedStart+n) + newF := make([]encodedField, len(e.fields), newCap) + copy(newF, e.fields) + e.fields = newF } - entries := make([]fieldEntry, n) + e.fields = e.fields[:savedStart+n] + entries := e.fields[savedStart : savedStart+n] + for i, f := range obj.Fields { - entries[i] = fieldEntry{ - id: b.Add(f.Name), - name: f.Name, - valueBytes: Encode(b, f.Value), + id := e.b.Add(f.Name) + pStart, pEnd, err := e.encodeValue(f.Value) + if err != nil { + e.fields = e.fields[:savedStart] + return 0, 0, err + } + entries[i] = encodedField{ + id: id, + name: f.Name, + start: pStart, + end: pEnd, } } - // Sort by field name (as required by spec) sort.Slice(entries, func(i, j int) bool { return entries[i].name < entries[j].name }) - // Compute sizes - maxID := 0 - for _, e := range entries { - if e.id > maxID { - maxID = e.id + resStart, resEnd, err := e.buildObjectBytes(entries) + e.fields = e.fields[:savedStart] + return resStart, resEnd, err +} + +func (e *encoder) encodeReflect(rv reflect.Value) (start, end int, err error) { + if !rv.IsValid() { + start, end = e.encodeValuePrimitive(Null()) + return start, end, nil + } + + // Dereference pointers/interfaces + for rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface { + if rv.IsNil() { + start, end = e.encodeValuePrimitive(Null()) + return start, end, nil } + rv = rv.Elem() } - // Encode all values and compute offsets - totalValueSize := 0 - valueOffsets := make([]int, n+1) - for i, e := range entries { - valueOffsets[i] = totalValueSize - totalValueSize += len(e.valueBytes) + // Check concrete types first + if rv.Type() == reflect.TypeFor[uuid.UUID]() { + start, end = e.encodeValuePrimitive(UUID(rv.Interface().(uuid.UUID))) + return start, end, nil + } + if rv.Type() == reflect.TypeFor[time.Time]() { + start, end = e.encodeValuePrimitive(timeToVariant(rv.Interface().(time.Time))) + return start, end, nil } - valueOffsets[n] = totalValueSize - fieldIDSizeCode := offsetSizeCode(maxID) - fieldIDSize := offsetSize(fieldIDSizeCode) - offsetSzCode := offsetSizeCode(totalValueSize) + switch rv.Kind() { + case reflect.Bool: + start, end = e.encodeValuePrimitive(Bool(rv.Bool())) + return start, end, nil + case reflect.Int8: + start, end = e.encodeValuePrimitive(Int8(int8(rv.Int()))) + return start, end, nil + case reflect.Int16: + start, end = e.encodeValuePrimitive(Int16(int16(rv.Int()))) + return start, end, nil + case reflect.Int32: + start, end = e.encodeValuePrimitive(Int32(int32(rv.Int()))) + return start, end, nil + case reflect.Int64, reflect.Int: + start, end = e.encodeValuePrimitive(Int64(rv.Int())) + return start, end, nil + case reflect.Uint8: + start, end = e.encodeValuePrimitive(Int16(int16(rv.Uint()))) + return start, end, nil + case reflect.Uint16: + start, end = e.encodeValuePrimitive(Int32(int32(rv.Uint()))) + return start, end, nil + case reflect.Uint32: + start, end = e.encodeValuePrimitive(Int64(int64(rv.Uint()))) + return start, end, nil + case reflect.Uint64, reflect.Uint: + u := rv.Uint() + if u > math.MaxInt64 { + return 0, 0, fmt.Errorf("variant marshal: uint64 value %d overflows int64", u) + } + start, end = e.encodeValuePrimitive(Int64(int64(u))) + return start, end, nil + case reflect.Float32: + start, end = e.encodeValuePrimitive(Float(float32(rv.Float()))) + return start, end, nil + case reflect.Float64: + start, end = e.encodeValuePrimitive(Double(rv.Float())) + return start, end, nil + case reflect.String: + start, end = e.encodeValuePrimitive(String(rv.String())) + return start, end, nil + case reflect.Slice: + if rv.Type().Elem().Kind() == reflect.Uint8 { + start, end = e.encodeValuePrimitive(Binary(rv.Bytes())) + return start, end, nil + } + return e.encodeSliceArray(rv) + case reflect.Array: + // Byte arrays (including [16]byte) map to Binary. uuid.UUID is + // handled above via its concrete type; without a logical UUID + // annotation a fixed-length byte array is just bytes. + if rv.Type().Elem().Kind() == reflect.Uint8 { + b := make([]byte, rv.Len()) + for i := range b { + b[i] = byte(rv.Index(i).Uint()) + } + start, end = e.encodeValuePrimitive(Binary(b)) + return start, end, nil + } + return e.encodeSliceArray(rv) + case reflect.Map: + return e.encodeMapObject(rv) + case reflect.Struct: + return e.encodeStructObject(rv) + default: + return 0, 0, fmt.Errorf("variant marshal: unsupported type %s", rv.Type()) + } +} + +func (e *encoder) encodeSliceArray(rv reflect.Value) (start, end int, err error) { + n := rv.Len() + if n == 0 { + return e.buildArrayBytes(nil) + } + + savedStart := len(e.positions) + if cap(e.positions) < savedStart+n { + newCap := max(cap(e.positions)*2, savedStart+n) + newP := make([]elementPos, len(e.positions), newCap) + copy(newP, e.positions) + e.positions = newP + } + e.positions = e.positions[:savedStart+n] + positions := e.positions[savedStart : savedStart+n] + + for i := range n { + pStart, pEnd, err := e.encodeReflect(rv.Index(i)) + if err != nil { + e.positions = e.positions[:savedStart] + return 0, 0, err + } + positions[i] = elementPos{start: pStart, end: pEnd} + } + + resStart, resEnd, err := e.buildArrayBytes(positions) + e.positions = e.positions[:savedStart] + return resStart, resEnd, err +} + +func (e *encoder) buildArrayBytes(positions []elementPos) (start, end int, err error) { + n := len(positions) + + if testHookVerifyArrayLayout != nil { + testHookVerifyArrayLayout(e, positions) + } + + totalSize := 0 + for _, pos := range positions { + totalSize += pos.end - pos.start + } + + var offsetBuf [32]int + var offsets []int + if n+1 <= len(offsetBuf) { + offsets = offsetBuf[:n+1] + } else { + if cap(e.offsets) < n+1 { + e.offsets = make([]int, n+1) + } + offsets = e.offsets[:n+1] + } + off := 0 + for i, pos := range positions { + offsets[i] = off + off += pos.end - pos.start + } + offsets[n] = off + + offsetSzCode := offsetSizeCode(totalSize) offsetSz := offsetSize(offsetSzCode) - // Header: basic_type=2 (object), value_header encodes num_fields, field_id_size, offset_size - // Object header byte: bits 0-1 = BasicObject(2), bits 2-3 = field_id_size_minus_one, - // bits 4-5 = offset_size_minus_one, bits 6-7 = unused - // Then: num_elements (1 byte for small objects, but spec says offset_size bytes) - // - // Actually the spec says: - // value_metadata byte: bits 0-1 = basic_type (2=object), bits 2-3 = field_id_size-1, - // bits 4-5 = offset_size-1, bits 6-7 = is_large (0=1-byte num_elements, 1=4-byte) isLarge := byte(0) numElemSize := 1 if n > 255 { @@ -184,66 +569,215 @@ func encodeObject(b *MetadataBuilder, obj Object) []byte { numElemSize = 4 } - header := byte(BasicObject) | (fieldIDSizeCode << 2) | (offsetSzCode << 4) | (isLarge << 6) + header := byte(BasicArray) | (offsetSzCode << 2) | (isLarge << 4) - // Total size: header(1) + num_elements + field_ids(n*fieldIDSize) + offsets((n+1)*offsetSz) + values - totalSize := 1 + numElemSize + n*fieldIDSize + (n+1)*offsetSz + totalValueSize - buf := make([]byte, totalSize) - buf[0] = header + bufSize := 1 + numElemSize + (n+1)*offsetSz + totalSize + if cap(e.temp) < bufSize { + e.temp = make([]byte, bufSize) + } else { + e.temp = e.temp[:bufSize] + } + e.temp[0] = header - pos := 1 + posIdx := 1 if isLarge == 1 { - binary.LittleEndian.PutUint32(buf[pos:], uint32(n)) - pos += 4 + binary.LittleEndian.PutUint32(e.temp[posIdx:], uint32(n)) + posIdx += 4 } else { - buf[pos] = byte(n) - pos += 1 + e.temp[posIdx] = byte(n) + posIdx += 1 } - // Write field IDs - for _, e := range entries { - writeUint(buf[pos:], e.id, fieldIDSize) - pos += fieldIDSize + for _, o := range offsets { + writeUint(e.temp[posIdx:], o, offsetSz) + posIdx += offsetSz } - // Write offsets - for _, off := range valueOffsets { - writeUint(buf[pos:], off, offsetSz) - pos += offsetSz + for _, p := range positions { + copy(e.temp[posIdx:], e.scratch[p.start:p.end]) + posIdx += p.end - p.start } - // Write values - for _, e := range entries { - copy(buf[pos:], e.valueBytes) - pos += len(e.valueBytes) + firstStart := len(e.scratch) + if n > 0 { + firstStart = positions[0].start } + e.scratch = e.scratch[:firstStart] - return buf + start = len(e.scratch) + e.scratch = append(e.scratch, e.temp...) + end = len(e.scratch) + + return start, end, nil } -func encodeArray(b *MetadataBuilder, arr Array) []byte { - n := len(arr.Elements) +func (e *encoder) encodeMapObject(rv reflect.Value) (start, end int, err error) { + if rv.IsNil() { + start, end = e.encodeValuePrimitive(Null()) + return start, end, nil + } - // Encode all elements - encodedElems := make([][]byte, n) - totalSize := 0 - for i, e := range arr.Elements { - encodedElems[i] = Encode(b, e) - totalSize += len(encodedElems[i]) + n := rv.Len() + if n == 0 { + return e.buildObjectBytes(nil) } - // Compute offsets - offsets := make([]int, n+1) + savedStart := len(e.fields) + if cap(e.fields) < savedStart+n { + newCap := max(cap(e.fields)*2, savedStart+n) + newF := make([]encodedField, len(e.fields), newCap) + copy(newF, e.fields) + e.fields = newF + } + e.fields = e.fields[:savedStart+n] + entries := e.fields[savedStart : savedStart+n] + + iter := rv.MapRange() + idx := 0 + for iter.Next() { + key := iter.Key() + if key.Kind() != reflect.String { + e.fields = e.fields[:savedStart] + return 0, 0, fmt.Errorf("variant marshal: map key must be string, got %s", key.Type()) + } + name := key.String() + id := e.b.Add(name) + + pStart, pEnd, err := e.encodeReflect(iter.Value()) + if err != nil { + e.fields = e.fields[:savedStart] + return 0, 0, err + } + entries[idx] = encodedField{ + id: id, + name: name, + start: pStart, + end: pEnd, + } + idx++ + } + + sort.Slice(entries, func(i, j int) bool { + return entries[i].name < entries[j].name + }) + + resStart, resEnd, err := e.buildObjectBytes(entries) + e.fields = e.fields[:savedStart] + return resStart, resEnd, err +} + +func (e *encoder) encodeStructObject(rv reflect.Value) (start, end int, err error) { + rt := rv.Type() + numFields := rt.NumField() + + visibleCount := 0 + for i := range numFields { + sf := rt.Field(i) + if !sf.IsExported() { + continue + } + name := fieldName(sf) + if name == "-" { + continue + } + visibleCount++ + } + + if visibleCount == 0 { + return e.buildObjectBytes(nil) + } + + savedStart := len(e.fields) + if cap(e.fields) < savedStart+visibleCount { + newCap := max(cap(e.fields)*2, savedStart+visibleCount) + newF := make([]encodedField, len(e.fields), newCap) + copy(newF, e.fields) + e.fields = newF + } + e.fields = e.fields[:savedStart+visibleCount] + entries := e.fields[savedStart : savedStart+visibleCount] + + idx := 0 + for i := range numFields { + sf := rt.Field(i) + if !sf.IsExported() { + continue + } + name := fieldName(sf) + if name == "-" { + continue + } + + id := e.b.Add(name) + pStart, pEnd, err := e.encodeReflect(rv.Field(i)) + if err != nil { + e.fields = e.fields[:savedStart] + return 0, 0, err + } + entries[idx] = encodedField{ + id: id, + name: name, + start: pStart, + end: pEnd, + } + idx++ + } + + sort.Slice(entries, func(i, j int) bool { + return entries[i].name < entries[j].name + }) + + resStart, resEnd, err := e.buildObjectBytes(entries) + e.fields = e.fields[:savedStart] + return resStart, resEnd, err +} + +func (e *encoder) buildObjectBytes(entries []encodedField) (start, end int, err error) { + n := len(entries) + + if testHookVerifyObjectLayout != nil { + testHookVerifyObjectLayout(e, entries) + } + + maxID := 0 + totalValueSize := 0 + for _, entry := range entries { + if entry.id > maxID { + maxID = entry.id + } + totalValueSize += entry.end - entry.start + } + + var offsetBuf [32]int + var valueOffsets []int + if n+1 <= len(offsetBuf) { + valueOffsets = offsetBuf[:n+1] + } else { + if cap(e.offsets) < n+1 { + e.offsets = make([]int, n+1) + } + valueOffsets = e.offsets[:n+1] + } off := 0 - for i, enc := range encodedElems { - offsets[i] = off - off += len(enc) + for i, entry := range entries { + valueOffsets[i] = off + off += entry.end - entry.start } - offsets[n] = off + valueOffsets[n] = off - offsetSzCode := offsetSizeCode(totalSize) + fieldIDSizeCode := offsetSizeCode(maxID) + fieldIDSize := offsetSize(fieldIDSizeCode) + offsetSzCode := offsetSizeCode(totalValueSize) offsetSz := offsetSize(offsetSzCode) + // Header byte layout for objects, per the spec's value encoding grammar + // (object_header: is_large << 4 | field_id_size_minus_one << 2 | + // field_offset_size_minus_one, shifted left 2 past the basic type): + // + // bits 0-1: basic_type (2 = object) + // bits 2-3: field_offset_size_minus_one + // bits 4-5: field_id_size_minus_one + // bit 6: is_large (0 = 1-byte num_elements, 1 = 4-byte) isLarge := byte(0) numElemSize := 1 if n > 255 { @@ -251,40 +785,54 @@ func encodeArray(b *MetadataBuilder, arr Array) []byte { numElemSize = 4 } - header := byte(BasicArray) | (offsetSzCode << 2) | (isLarge << 4) + header := byte(BasicObject) | (offsetSzCode << 2) | (fieldIDSizeCode << 4) | (isLarge << 6) - // Total: header(1) + num_elements + offsets((n+1)*offsetSz) + values - bufSize := 1 + numElemSize + (n+1)*offsetSz + totalSize - buf := make([]byte, bufSize) - buf[0] = header + totalSize := 1 + numElemSize + n*fieldIDSize + (n+1)*offsetSz + totalValueSize + if cap(e.temp) < totalSize { + e.temp = make([]byte, totalSize) + } else { + e.temp = e.temp[:totalSize] + } + e.temp[0] = header pos := 1 if isLarge == 1 { - binary.LittleEndian.PutUint32(buf[pos:], uint32(n)) + binary.LittleEndian.PutUint32(e.temp[pos:], uint32(n)) pos += 4 } else { - buf[pos] = byte(n) + e.temp[pos] = byte(n) pos += 1 } - // Write offsets - for _, o := range offsets { - writeUint(buf[pos:], o, offsetSz) + for _, entry := range entries { + writeUint(e.temp[pos:], entry.id, fieldIDSize) + pos += fieldIDSize + } + + for _, offsetVal := range valueOffsets { + writeUint(e.temp[pos:], offsetVal, offsetSz) pos += offsetSz } - // Write values - for _, enc := range encodedElems { - copy(buf[pos:], enc) - pos += len(enc) + for _, entry := range entries { + copy(e.temp[pos:], e.scratch[entry.start:entry.end]) + pos += entry.end - entry.start } - return buf -} + firstStart := len(e.scratch) + if n > 0 { + firstStart = entries[0].start + for _, entry := range entries { + if entry.start < firstStart { + firstStart = entry.start + } + } + } + e.scratch = e.scratch[:firstStart] -// makeHeader constructs a value_metadata byte. -// For primitives: bits 0-1 = basic_type(0), bits 2-7 = primitive_type -// For short strings: bits 0-1 = basic_type(1), bits 2-7 = string length -func makeHeader(basic BasicType, valueHeader byte) byte { - return byte(basic) | (valueHeader << 2) + start = len(e.scratch) + e.scratch = append(e.scratch, e.temp...) + end = len(e.scratch) + + return start, end, nil } diff --git a/vendor/github.com/parquet-go/parquet-go/variant/loc.go b/vendor/github.com/parquet-go/parquet-go/variant/loc.go new file mode 100644 index 00000000000..43ab7c47700 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/variant/loc.go @@ -0,0 +1,50 @@ +package variant + +// Loc describes where the value of a variant path lives for one row +// (or one list element) of a columnar reader window. +type Loc uint8 + +const ( + // LocMissing means the path has no value: an enclosing level is null, + // the field is absent from its parent object, or the whole variant + // column is null for the row. + LocMissing Loc = iota + + // LocNull means the path holds the variant null value. + LocNull + + // LocTyped means the value is a scalar stored in a shredded typed_value + // column; it appears in the cursor's typed vector. + LocTyped + + // LocTypedObject means the value is an object stored (at least + // partially) in shredded form. Leftover fields of a partially shredded + // object are available through the residual. + LocTypedObject + + // LocTypedList means the value is a list stored in shredded form. + LocTypedList + + // LocResidual means the value exists only as variant binary at this + // position. + LocResidual +) + +func (l Loc) String() string { + switch l { + case LocMissing: + return "missing" + case LocNull: + return "null" + case LocTyped: + return "typed" + case LocTypedObject: + return "typed-object" + case LocTypedList: + return "typed-list" + case LocResidual: + return "residual" + default: + return "unknown" + } +} diff --git a/vendor/github.com/parquet-go/parquet-go/variant/marshal.go b/vendor/github.com/parquet-go/parquet-go/variant/marshal.go index 377c020ca98..d3fd25b9ed1 100644 --- a/vendor/github.com/parquet-go/parquet-go/variant/marshal.go +++ b/vendor/github.com/parquet-go/parquet-go/variant/marshal.go @@ -5,6 +5,7 @@ import ( "math" "reflect" "strings" + "time" "github.com/google/uuid" ) @@ -12,16 +13,30 @@ import ( // Marshal converts a Go value to variant binary encoding, returning the // metadata and value byte slices. func Marshal(v any) (metadata, value []byte, err error) { - varVal, err := goToVariant(v) + var b MetadataBuilder + enc := getEncoder(&b) + + start, end, err := enc.encodeReflect(reflect.ValueOf(v)) if err != nil { + releaseEncoder(enc) return nil, nil, err } - var b MetadataBuilder - valueBytes := Encode(&b, varVal) + valueBytes := make([]byte, end-start) + copy(valueBytes, enc.scratch[start:end]) + + releaseEncoder(enc) + _, metadataBytes := b.Build() return metadataBytes, valueBytes, nil } +// ValueOf converts a Go value to a variant Value without encoding it. It is +// useful for callers that need to inspect or partially encode the value, +// such as shredded variant writers. +func ValueOf(v any) (Value, error) { + return goToVariant(v) +} + // Unmarshal decodes variant binary data into a Go value. func Unmarshal(metadata, value []byte) (any, error) { m, err := DecodeMetadata(metadata) @@ -35,7 +50,10 @@ func Unmarshal(metadata, value []byte) (any, error) { return v.GoValue(), nil } -// goToVariant converts a Go value to a variant Value. +// goToVariant converts a Go value to a variant Value. Marshal encodes +// through the streaming encoder instead (see encodeReflect); this tree +// walk backs ValueOf, whose callers need the Value tree to make per-field +// decisions before encoding. The two must map Go types identically. func goToVariant(v any) (Value, error) { if v == nil { return Null(), nil @@ -48,7 +66,6 @@ func goToVariantReflect(rv reflect.Value) (Value, error) { return Null(), nil } - // Dereference pointers/interfaces for rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface { if rv.IsNil() { return Null(), nil @@ -56,11 +73,15 @@ func goToVariantReflect(rv reflect.Value) (Value, error) { rv = rv.Elem() } - // Check concrete types first + // uuid.UUID and time.Time must be recognized before the Kind switch: + // uuid.UUID is a [16]byte array and time.Time a struct with no exported + // fields, so the generic cases would mishandle them. iface := rv.Interface() switch val := iface.(type) { case uuid.UUID: return UUID(val), nil + case time.Time: + return timeToVariant(val), nil } switch rv.Kind() { @@ -94,15 +115,19 @@ func goToVariantReflect(rv reflect.Value) (Value, error) { return String(rv.String()), nil case reflect.Slice: if rv.Type().Elem().Kind() == reflect.Uint8 { - // []byte return Binary(rv.Bytes()), nil } return goSliceToArray(rv) case reflect.Array: - if rv.Type() == reflect.TypeFor[uuid.UUID]() { - var u uuid.UUID - reflect.ValueOf(&u).Elem().Set(rv) - return UUID(u), nil + // Byte arrays (including [16]byte) map to Binary. uuid.UUID is + // handled above via its concrete type; without a logical UUID + // annotation a fixed-length byte array is just bytes. + if rv.Type().Elem().Kind() == reflect.Uint8 { + b := make([]byte, rv.Len()) + for i := range b { + b[i] = byte(rv.Index(i).Uint()) + } + return Binary(b), nil } return goSliceToArray(rv) case reflect.Map: @@ -168,6 +193,18 @@ func goStructToObject(rv reflect.Value) (Value, error) { return MakeObject(fields), nil } +// timeToVariant converts a time.Time to a timestamp variant value. The +// timestamp is stored with time zone (isAdjustedToUTC), which is the natural +// mapping for time.Time since it represents an instant. Nanosecond precision +// is used when the value has sub-microsecond components and fits in the +// nanosecond timestamp range; microsecond precision otherwise. +func timeToVariant(t time.Time) Value { + if t.Nanosecond()%1000 != 0 && t.Year() >= 1678 && t.Year() <= 2261 { + return TimestampNanos(t.UnixNano()) + } + return Timestamp(t.UnixMicro()) +} + // fieldName returns the name to use for a struct field, checking variant and // json struct tags. func fieldName(sf reflect.StructField) string { diff --git a/vendor/github.com/parquet-go/parquet-go/variant/metadata.go b/vendor/github.com/parquet-go/parquet-go/variant/metadata.go index 030a23adf53..99549fe3f74 100644 --- a/vendor/github.com/parquet-go/parquet-go/variant/metadata.go +++ b/vendor/github.com/parquet-go/parquet-go/variant/metadata.go @@ -4,10 +4,13 @@ import ( "encoding/binary" "errors" "fmt" - "sort" + "unicode/utf8" + "unsafe" ) // Metadata holds the decoded metadata dictionary for a variant value. +// Sorted reports whether the dictionary strings were stored in +// lexicographic order (the sorted_strings header bit). type Metadata struct { Strings []string Sorted bool @@ -17,12 +20,17 @@ type Metadata struct { // // Format: header(1) | dictionary_size(uint) | offsets(dictionary_size+1) | string_data // -// Header bits: +// Header bits (per the spec's metadata encoding grammar, +// header = version | sorted_strings << 4 | offset_size_minus_one << 6): // // 0-3: version (must be 1) -// 4: sorted_strings -// 5-6: offset_size_minus_one -// 7: reserved (must be 0) +// 4: sorted_strings +// 6-7: offset_size_minus_one +// +// Like Decode, DecodeMetadata rejects what the spec declares invalid +// (non-UTF-8 dictionary strings, sizes exceeding the data) and does not +// validate the unused header bit, per VariantEncoding.md: "Bit 5 (marked R) +// is reserved; it must be ignored by readers." func DecodeMetadata(data []byte) (Metadata, error) { if len(data) == 0 { return Metadata{}, errors.New("variant metadata: empty data") @@ -33,12 +41,9 @@ func DecodeMetadata(data []byte) (Metadata, error) { if version != 1 { return Metadata{}, fmt.Errorf("variant metadata: unsupported version %d", version) } - if header&0x80 != 0 { - return Metadata{}, errors.New("variant metadata: reserved bit is set") - } sorted := (header>>4)&1 == 1 - offsetSz := offsetSize((header >> 5) & 0x03) + offsetSz := offsetSize((header >> 6) & 0x03) pos := 1 dictSize, n, err := readUint(data[pos:], offsetSz) @@ -47,7 +52,16 @@ func DecodeMetadata(data []byte) (Metadata, error) { } pos += n - // Read (dictSize+1) offsets + // The metadata must contain at least (dictSize+1) offsets; validate + // against the input size before allocating to reject corrupt data that + // declares an absurdly large dictionary. dictSize < 0 happens only on + // 32-bit platforms, where a 4-byte size above math.MaxInt32 overflows + // int; the comparison is phrased as <= dictSize rather than + // < dictSize+1 so the addition cannot overflow the same way. + if remaining := len(data) - pos; dictSize < 0 || remaining/offsetSz <= dictSize { + return Metadata{}, fmt.Errorf("variant metadata: dictionary size %d exceeds data", dictSize) + } + offsets := make([]int, dictSize+1) for i := range offsets { v, n, err := readUint(data[pos:], offsetSz) @@ -64,9 +78,15 @@ func DecodeMetadata(data []byte) (Metadata, error) { for i := range dictSize { start := offsets[i] end := offsets[i+1] - if start > end || end > len(stringData) { + // start < 0 happens only on 32-bit platforms, where a 4-byte + // offset above math.MaxInt32 overflows int; without the check the + // slice below would panic. + if start < 0 || start > end || end > len(stringData) { return Metadata{}, fmt.Errorf("variant metadata: invalid string offset [%d, %d) in data of length %d", start, end, len(stringData)) } + if !utf8.Valid(stringData[start:end]) { + return Metadata{}, fmt.Errorf("variant metadata: dictionary string %d is not valid UTF-8", i) + } strings[i] = string(stringData[start:end]) } @@ -81,14 +101,22 @@ func (m Metadata) Lookup(id int) (string, error) { return m.Strings[id], nil } -// MetadataBuilder builds a variant metadata dictionary. +// MetadataBuilder builds a variant metadata dictionary. Field names are +// interned into a single contiguous byte buffer so a high-cardinality key +// set pays for buffer growth rather than a heap string per key. type MetadataBuilder struct { - strings []string - index map[string]int + buf []byte // concatenated dictionary strings + offs []int // start offset of each string in buf; end is offs[i+1] or len(buf) + index map[string]int + // unsorted is set when some entry compares below its predecessor; it is + // tracked incrementally by Add so encoding a large dictionary need not + // re-compare every entry. + unsorted bool } -// Add adds a string to the dictionary and returns its index. -// If the string already exists, the existing index is returned. +// Add interns s into the dictionary and returns its stable index. The +// string is copied into the builder's buffer, so callers may reuse the +// argument's backing memory after Add returns. func (b *MetadataBuilder) Add(s string) int { if b.index == nil { b.index = make(map[string]int) @@ -96,73 +124,120 @@ func (b *MetadataBuilder) Add(s string) int { if idx, ok := b.index[s]; ok { return idx } - idx := len(b.strings) - b.strings = append(b.strings, s) - b.index[s] = idx + if n := len(b.offs); n > 0 && !b.unsorted && b.stringAt(n-1) > s { + b.unsorted = true + } + start := len(b.buf) + old := unsafe.SliceData(b.buf) + b.buf = append(b.buf, s...) + idx := len(b.offs) + // Record the new start before any reindex so stringAt can bound the + // previous last entry (and this one) correctly against the grown slab. + b.offs = append(b.offs, start) + if idx > 0 && unsafe.SliceData(b.buf) != old { + b.reindex() + } else { + b.index[b.stringAt(idx)] = idx + } return idx } +// stringAt returns a view of dictionary entry i into the slab. The view is +// only valid until the next Add that grows the buffer, or Reset. +func (b *MetadataBuilder) stringAt(i int) string { + start := b.offs[i] + end := len(b.buf) + if i+1 < len(b.offs) { + end = b.offs[i+1] + } + if end == start { + return "" + } + return unsafe.String(unsafe.SliceData(b.buf[start:end]), end-start) +} + +// reindex rebuilds the lookup map after the slab has been reallocated. +func (b *MetadataBuilder) reindex() { + clear(b.index) + for i := range b.offs { + b.index[b.stringAt(i)] = i + } +} + // Build returns the decoded Metadata and the encoded binary representation. // The dictionary indices in the output match those returned by Add, so -// encoded values referencing those indices remain valid. +// encoded values referencing those indices remain valid. The returned +// Metadata owns its strings and remains valid after Reset. func (b *MetadataBuilder) Build() (Metadata, []byte) { - n := len(b.strings) - - // Check if the strings happen to be sorted - sorted := sort.StringsAreSorted(b.strings) + strs := make([]string, len(b.offs)) + for i := range b.offs { + strs[i] = string(b.stringAt(i)) // detach from the slab so Reset cannot invalidate + } + return Metadata{Strings: strs, Sorted: !b.unsorted}, b.AppendTo(nil) +} - // Compute string data and offsets - offsets := make([]int, n+1) - totalLen := 0 - for i, s := range b.strings { - offsets[i] = totalLen - totalLen += len(s) +// AppendTo appends the encoded binary representation of the dictionary to +// dst and returns the extended slice. The dictionary indices in the output +// match those returned by Add, so encoded values referencing those indices +// remain valid. +// +// The variant format encodes dictionary offsets in at most 4 bytes, so the +// interned names must total at most math.MaxUint32 bytes; callers growing +// the dictionary without bound must check Size before encoding (as +// Builder.Finish and parquet.VariantColumnWriter do). +func (b *MetadataBuilder) AppendTo(dst []byte) []byte { + n := len(b.offs) + totalLen := len(b.buf) + sortedBit := byte(0) + if !b.unsorted { + sortedBit = 1 } - offsets[n] = totalLen - // Determine offset size maxOffset := max(totalLen, n) osc := offsetSizeCode(maxOffset) offsetSz := offsetSize(osc) - // Build the binary blob - // header(1) + dict_size(offsetSz) + offsets((n+1)*offsetSz) + string_data(totalLen) + // Layout: header(1) + dict_size(offsetSz) + offsets((n+1)*offsetSz) + + // string_data(totalLen). size := 1 + offsetSz + (n+1)*offsetSz + totalLen - buf := make([]byte, size) + base := len(dst) + dst = append(dst, make([]byte, size)...) + out := dst[base:] - // Header: version=1, sorted_strings flag, offset_size_minus_one - sortedBit := byte(0) - if sorted { - sortedBit = 1 - } - buf[0] = 1 | (sortedBit << 4) | (osc << 5) + // Header: version=1, sorted_strings flag at bit 4, offset_size_minus_one + // at bits 6-7 (per the spec's metadata encoding grammar). + out[0] = 1 | (sortedBit << 4) | (osc << 6) pos := 1 - writeUint(buf[pos:], n, offsetSz) + writeUint(out[pos:], n, offsetSz) pos += offsetSz - for _, off := range offsets { - writeUint(buf[pos:], off, offsetSz) + for _, off := range b.offs { + writeUint(out[pos:], off, offsetSz) pos += offsetSz } + writeUint(out[pos:], totalLen, offsetSz) + pos += offsetSz - for _, s := range b.strings { - copy(buf[pos:], s) - pos += len(s) - } - - return Metadata{Strings: b.strings, Sorted: sorted}, buf + copy(out[pos:], b.buf) + return dst } -// Reset clears the builder for reuse. +// Size returns the total number of bytes of interned dictionary strings. +func (b *MetadataBuilder) Size() int { return len(b.buf) } + +// Reset clears the builder for reuse, retaining the string buffer's capacity. func (b *MetadataBuilder) Reset() { - b.strings = b.strings[:0] - for k := range b.index { - delete(b.index, k) - } + b.buf = b.buf[:0] + b.offs = b.offs[:0] + b.unsorted = false + clear(b.index) } -// readUint reads an unsigned integer of the given byte width from data. +// readUint reads an unsigned integer of the given byte width from data. Note +// that on 32-bit platforms a 4-byte value above math.MaxInt32 overflows int +// and is returned negative; callers validating sizes and offsets against the +// input must guard against negative results before using them. func readUint(data []byte, size int) (int, int, error) { if len(data) < size { return 0, 0, errors.New("not enough data") diff --git a/vendor/github.com/parquet-go/parquet-go/variant/types.go b/vendor/github.com/parquet-go/parquet-go/variant/types.go index 7e1f76a68ca..70f2746076b 100644 --- a/vendor/github.com/parquet-go/parquet-go/variant/types.go +++ b/vendor/github.com/parquet-go/parquet-go/variant/types.go @@ -15,25 +15,27 @@ const ( type PrimitiveType byte const ( - PrimitiveNull PrimitiveType = 0 - PrimitiveTrue PrimitiveType = 1 - PrimitiveFalse PrimitiveType = 2 - PrimitiveInt8 PrimitiveType = 3 - PrimitiveInt16 PrimitiveType = 4 - PrimitiveInt32 PrimitiveType = 5 - PrimitiveInt64 PrimitiveType = 6 - PrimitiveDouble PrimitiveType = 7 - PrimitiveDecimal4 PrimitiveType = 8 - PrimitiveDecimal8 PrimitiveType = 9 - PrimitiveDecimal16 PrimitiveType = 10 - PrimitiveDate PrimitiveType = 11 - PrimitiveTimestamp PrimitiveType = 12 - PrimitiveTimestampNTZ PrimitiveType = 13 - PrimitiveFloat PrimitiveType = 14 - PrimitiveBinary PrimitiveType = 15 - PrimitiveString PrimitiveType = 16 - PrimitiveTime PrimitiveType = 17 - PrimitiveUUID PrimitiveType = 20 + PrimitiveNull PrimitiveType = 0 + PrimitiveTrue PrimitiveType = 1 + PrimitiveFalse PrimitiveType = 2 + PrimitiveInt8 PrimitiveType = 3 + PrimitiveInt16 PrimitiveType = 4 + PrimitiveInt32 PrimitiveType = 5 + PrimitiveInt64 PrimitiveType = 6 + PrimitiveDouble PrimitiveType = 7 + PrimitiveDecimal4 PrimitiveType = 8 + PrimitiveDecimal8 PrimitiveType = 9 + PrimitiveDecimal16 PrimitiveType = 10 + PrimitiveDate PrimitiveType = 11 + PrimitiveTimestamp PrimitiveType = 12 + PrimitiveTimestampNTZ PrimitiveType = 13 + PrimitiveFloat PrimitiveType = 14 + PrimitiveBinary PrimitiveType = 15 + PrimitiveString PrimitiveType = 16 + PrimitiveTime PrimitiveType = 17 + PrimitiveTimestampNanos PrimitiveType = 18 + PrimitiveTimestampNTZNanos PrimitiveType = 19 + PrimitiveUUID PrimitiveType = 20 ) // primitiveSize returns the byte size of a primitive value's data portion, @@ -48,7 +50,8 @@ func primitiveSize(p PrimitiveType) int { return 2 case PrimitiveInt32, PrimitiveFloat, PrimitiveDate: return 4 - case PrimitiveInt64, PrimitiveDouble, PrimitiveTimestamp, PrimitiveTimestampNTZ, PrimitiveTime: + case PrimitiveInt64, PrimitiveDouble, PrimitiveTimestamp, PrimitiveTimestampNTZ, PrimitiveTime, + PrimitiveTimestampNanos, PrimitiveTimestampNTZNanos: return 8 case PrimitiveDecimal4: return 5 // 1 scale + 4 value diff --git a/vendor/github.com/parquet-go/parquet-go/variant/value.go b/vendor/github.com/parquet-go/parquet-go/variant/value.go index 26611874848..e52aaf8f443 100644 --- a/vendor/github.com/parquet-go/parquet-go/variant/value.go +++ b/vendor/github.com/parquet-go/parquet-go/variant/value.go @@ -2,6 +2,7 @@ package variant import ( "math" + "time" "github.com/google/uuid" ) @@ -111,6 +112,17 @@ func Time(v int64) Value { return Value{basic: BasicPrimitive, primitive: PrimitiveTime, i64: v} } +// TimestampNanos returns a timestamp variant value (nanoseconds since epoch, UTC). +func TimestampNanos(v int64) Value { + return Value{basic: BasicPrimitive, primitive: PrimitiveTimestampNanos, i64: v} +} + +// TimestampNTZNanos returns a timestamp without timezone variant value +// (nanoseconds since epoch). +func TimestampNTZNanos(v int64) Value { + return Value{basic: BasicPrimitive, primitive: PrimitiveTimestampNTZNanos, i64: v} +} + // UUID returns a UUID variant value. func UUID(v uuid.UUID) Value { return Value{basic: BasicPrimitive, primitive: PrimitiveUUID, uuid: v} @@ -224,7 +236,10 @@ func (v Value) ArrayValue() Array { // Float → float32, Double → float64 // String → string, Binary → []byte // Date → int32 (days since epoch) -// Timestamp/TimestampNTZ → int64 (microseconds since epoch) +// Timestamp/TimestampNanos → time.Time (UTC) +// TimestampNTZ/TimestampNTZNanos → int64 (microseconds/nanoseconds since +// epoch; these have no time zone, so no time.Time instant exists for +// them) // Time → int64 (microseconds since midnight) // UUID → uuid.UUID // Decimal4 → int32 (unscaled), Decimal8 → int64 (unscaled), Decimal16 → [16]byte @@ -273,7 +288,11 @@ func (v Value) GoValue() any { return v.bytes case PrimitiveDate: return int32(v.i64) - case PrimitiveTimestamp, PrimitiveTimestampNTZ, PrimitiveTime: + case PrimitiveTimestamp: + return time.UnixMicro(v.i64).UTC() + case PrimitiveTimestampNanos: + return time.Unix(0, v.i64).UTC() + case PrimitiveTimestampNTZ, PrimitiveTimestampNTZNanos, PrimitiveTime: return v.i64 case PrimitiveUUID: return v.uuid @@ -288,8 +307,11 @@ func (v Value) GoValue() any { } } -// Equal reports whether two variant values are deeply equal. -// Short strings and primitive strings with the same content are considered equal. +// Equal reports whether two variant values are structurally equal: the same +// value with the same primitive type. Object fields are compared without +// regard to order, short strings and primitive strings with the same content +// are considered equal, and floating-point values are compared bitwise (NaN +// equals NaN, negative zero does not equal positive zero). func (v Value) Equal(other Value) bool { // Normalize: treat short strings and primitive strings as equivalent if v.isString() && other.isString() { @@ -300,12 +322,22 @@ func (v Value) Equal(other Value) bool { } switch v.basic { case BasicObject: + // Objects are unordered collections of named fields: two objects + // with the same fields in different order are equal. The encoded + // form sorts field IDs by name regardless of construction order — + // VariantEncoding.md: "The field values are not required to be in + // the same order as the field IDs, to enable flexibility when + // constructing Variant values." if len(v.object.Fields) != len(other.object.Fields) { return false } - for i, f := range v.object.Fields { - of := other.object.Fields[i] - if f.Name != of.Name || !f.Value.Equal(of.Value) { + otherByName := make(map[string]Value, len(other.object.Fields)) + for _, f := range other.object.Fields { + otherByName[f.Name] = f.Value + } + for _, f := range v.object.Fields { + ov, ok := otherByName[f.Name] + if !ok || !f.Value.Equal(ov) { return false } } diff --git a/vendor/github.com/parquet-go/parquet-go/variant_column_reader.go b/vendor/github.com/parquet-go/parquet-go/variant_column_reader.go new file mode 100644 index 00000000000..47b982015b0 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/variant_column_reader.go @@ -0,0 +1,1588 @@ +package parquet + +import ( + "fmt" + "io" + "slices" + "strings" + + "github.com/parquet-go/parquet-go/variant" +) + +// This file implements a columnar, cursor-based reader for VARIANT columns. +// +// Unlike the reconstruction path in variant_shredded_read.go — which rebuilds +// one variant.Value tree per row — VariantReader exposes the shredded layout +// of the file directly: every position in the shredding tree is a +// (typed_value, value) pair where at most one side is populated per row, and +// the API surfaces that duality as typed vectors plus a per-row location tag. +// A query engine evaluating a path expression such as $.a.b over a column +// shredded as INT64 runs a plain vector loop over Int64s()/Locs(), and only +// falls back to per-row work for rows where the value exists as residual +// variant binary. +// +// Navigation is total: a cursor exists for every path, whether or not the +// writer shredded it. Below a non-shredded position, cursors are backed by +// navigation of the nearest shredded ancestor's residual bytes, so location +// tags remain accurate through residuals: LocMissing means the path is +// missing even after looking inside ancestor residual values, and a type +// conflict anywhere along the path (a scalar where an object was shredded, a +// list where a scalar was expected) simply surfaces as variant.LocResidual +// with the residual value already navigated to the requested position. + +// VariantCursorKind is the static (schema-derived) kind of a cursor +// position. It tells the engine which access pattern the position supports; +// the per-row runtime disposition is in Locs. +type VariantCursorKind uint8 + +const ( + // VariantCursorUnshredded is a position with no typed_value column: + // either the schema stores only variant binary here, or the cursor + // navigates below the shredded schema entirely. All present values are + // variant.LocNull or variant.LocResidual. + VariantCursorUnshredded VariantCursorKind = iota + + // VariantCursorLeaf is a position shredded as a primitive type; typed + // values are read from the typed vector accessors. + VariantCursorLeaf + + // VariantCursorObject is a position shredded as an object; descend into + // shredded fields with Field. + VariantCursorObject + + // VariantCursorList is a position shredded as a list; descend with + // Elements and use ListOffsets. + VariantCursorList +) + +func (k VariantCursorKind) String() string { + switch k { + case VariantCursorUnshredded: + return "unshredded" + case VariantCursorLeaf: + return "leaf" + case VariantCursorObject: + return "object" + case VariantCursorList: + return "list" + default: + return "unknown" + } +} + +// VariantReader reads one VARIANT column of a row group in columnar form. +// +// All cursors created from a reader share one row window, advanced with +// Next. Vectors and residual views returned by cursors are valid until the +// next call to Next or SeekToRow. +// +// Only the columns reachable from cursors that have been created are read: +// creating cursors is how an engine declares projection. Cursors may be +// created at any time; cursors created after a call to Next take effect on +// the following call. +type VariantReader struct { + rowGroup RowGroup + group *shreddedVariantGroup + groupDef int // definition level at which the variant group is present + baseColumn int // first leaf column of the variant group + numRows int64 + rowOffset int64 + leafInfo []variantLeafInfo + leaves []*variantLeafReader // lazily created, indexed by relative column + metaLeaf *variantLeafReader + root *VariantCursor + metaCache map[string]variant.Metadata + leafSet map[*variantLeafReader]struct{} // reused by Next + err error + + // rootValueRequired is set for plain unshredded variant groups, whose + // value field is required rather than optional. + rootValueRequired bool +} + +// unshreddedVariantGroupOf recognizes the plain unshredded variant group +// shape (required binary metadata and required binary value, nothing else) +// and returns its reconstruction tree. Groups with an optional value field +// are handled by buildShreddedVariantGroup instead. +func unshreddedVariantGroupOf(node Node) (*shreddedVariantGroup, bool) { + g := &shreddedVariantGroup{metadataCol: -1, valueCol: -1} + col := 0 + for _, f := range node.Fields() { + if !f.Leaf() || f.Type().Kind() != ByteArray || f.Repeated() { + return nil, false + } + switch f.Name() { + case "metadata": + if f.Optional() { + return nil, false + } + g.metadataCol = col + case "value": + if f.Optional() { + // An optional value with no typed_value is handled by + // buildShreddedVariantGroup; this recognizer exists for + // the required-value shape it rejects. + return nil, false + } + g.valueCol = col + default: + return nil, false + } + col++ + } + if g.metadataCol < 0 || g.valueCol < 0 { + return nil, false + } + g.numCols = col + return g, true +} + +type variantLeafInfo struct { + typ Type + maxDef byte + maxRep byte +} + +// variantColumnInfo is the result of resolving a variant column path in a +// schema, shared by NewVariantReader and NewVariantColumnWriter. +type variantColumnInfo struct { + node Node + group *shreddedVariantGroup + valueRequired bool // plain unshredded shape (required binary value) + col int // first leaf column of the variant group + def int // definition level at which the group is present + optional bool // whether the group node itself is optional +} + +// variantGroupOf builds the shredding tree of a variant group node, +// accepting both the shredded shapes (optional value) and the plain +// unshredded shape (required value) that VariantEncoding.md declares. The +// boolean result reports the latter. +func variantGroupOf(node Node) (*shreddedVariantGroup, bool, error) { + g, err := buildShreddedVariantGroup(node, 0, 0, 0) + if err != nil { + if u, ok := unshreddedVariantGroupOf(node); ok { + return u, true, nil + } + return nil, false, err + } + if g.metadataCol < 0 { + return nil, false, fmt.Errorf("variant: variant group has no metadata field") + } + return g, false, nil +} + +// resolveVariantColumn walks the schema to the variant group node named by +// path and builds its shredding tree. +func resolveVariantColumn(schema Node, path []string) (info variantColumnInfo, err error) { + if len(path) == 0 { + return info, fmt.Errorf("variant: a column path is required") + } + node := schema + for _, name := range path { + if node.Leaf() { + return info, fmt.Errorf("variant: column %q not found: %q is a leaf", joinPath(path), name) + } + var next Node + for _, f := range node.Fields() { + if f.Name() == name { + next = f + break + } + info.col += int(numLeafColumnsOf(f)) + } + if next == nil { + return info, fmt.Errorf("variant: column %q not found: no field %q", joinPath(path), name) + } + if next.Repeated() { + return info, fmt.Errorf("variant: column %q is beneath a repeated field, which the columnar variant APIs do not support", joinPath(path)) + } + info.optional = next.Optional() + if info.optional { + info.def++ + } + node = next + } + if node.Leaf() { + return info, fmt.Errorf("variant: column %q is not a variant group", joinPath(path)) + } + info.node = node + info.group, info.valueRequired, err = variantGroupOf(node) + if err != nil { + return info, fmt.Errorf("variant: column %q: %w", joinPath(path), err) + } + return info, nil +} + +// NewVariantReader creates a reader for the variant column at the given path +// in the row group. The path names the variant group node in the schema +// (e.g. "event" for a top-level column, "attrs", "v" for a nested one). The +// column may be unshredded (metadata, value) or shredded (metadata, value, +// typed_value) in any shape permitted by the Variant Shredding +// specification. +func NewVariantReader(rowGroup RowGroup, path ...string) (*VariantReader, error) { + info, err := resolveVariantColumn(rowGroup.Schema(), path) + if err != nil { + return nil, err + } + group, node := info.group, info.node + + r := &VariantReader{ + rowGroup: rowGroup, + group: group, + groupDef: info.def, + baseColumn: info.col, + numRows: rowGroup.NumRows(), + leafInfo: make([]variantLeafInfo, group.numCols), + leaves: make([]*variantLeafReader, group.numCols), + metaCache: make(map[string]variant.Metadata), + + rootValueRequired: info.valueRequired, + } + + // Types in leaf order; the traversal order matches the column numbering + // of buildShreddedVariantGroup (both walk Fields() depth-first). + i := 0 + forEachLeafColumnOf(node, func(leaf leafColumn) { + if i < len(r.leafInfo) { + r.leafInfo[i].typ = leaf.node.Type() + } + i++ + }) + if i != group.numCols { + return nil, fmt.Errorf("variant: column %q has %d leaves but the shredded group spans %d", joinPath(path), i, group.numCols) + } + r.fillLeafLevels(group) + + for _, li := range r.leafInfo { + switch li.typ.Kind() { + case Boolean, Int32, Int64, Float, Double, ByteArray, FixedLenByteArray: + default: + return nil, fmt.Errorf("variant: unsupported leaf type %s in shredded variant group", li.typ) + } + } + + r.metaLeaf = r.leafFor(group.metadataCol) + r.root = r.newNodeCursor(nil, group, "", false) + return r, nil +} + +func joinPath(path []string) string { + return strings.Join(path, ".") +} + +// fillLeafLevels computes the absolute max definition and repetition level +// of every leaf column of the variant subtree from the shredding tree. +func (r *VariantReader) fillLeafLevels(g *shreddedVariantGroup) { + if g.metadataCol >= 0 { + r.leafInfo[g.metadataCol].maxDef = byte(r.groupDef + g.defLevel) + r.leafInfo[g.metadataCol].maxRep = byte(g.repDepth) + } + if g.valueCol >= 0 { + valueDef := r.groupDef + g.defLevel + 1 + if g == r.group && r.rootValueRequired { + valueDef = r.groupDef + } + r.leafInfo[g.valueCol].maxDef = byte(valueDef) + r.leafInfo[g.valueCol].maxRep = byte(g.repDepth) + } + if t := g.typed; t != nil { + switch t.kind { + case shreddedTypedPrimitive: + r.leafInfo[t.startCol].maxDef = byte(r.groupDef + t.defLevel) + r.leafInfo[t.startCol].maxRep = byte(g.repDepth) + case shreddedTypedList: + r.fillLeafLevels(t.element) + case shreddedTypedObject: + for _, f := range t.fields { + r.fillLeafLevels(f.group) + } + } + } +} + +func (r *VariantReader) leafFor(relCol int) *variantLeafReader { + if l := r.leaves[relCol]; l != nil { + return l + } + info := r.leafInfo[relCol] + l := &variantLeafReader{ + reader: r, + relCol: relCol, + typ: info.typ, + kind: info.typ.Kind(), + maxDef: info.maxDef, + maxRep: info.maxRep, + pendingSeek: -1, + } + r.leaves[relCol] = l + return l +} + +// Root returns the cursor for the variant value itself. +func (r *VariantReader) Root() *VariantCursor { return r.root } + +// Path returns the cursor for the object field path below the root, +// equivalent to chaining Field calls. +func (r *VariantReader) Path(path ...string) *VariantCursor { + c := r.root + for _, name := range path { + c = c.Field(name) + } + return c +} + +// NumRows returns the number of rows of the row group. +func (r *VariantReader) NumRows() int64 { return r.numRows } + +// Next advances the shared row window by up to n rows and recomputes the +// window state of every cursor. It returns the number of rows in the new +// window, or (0, io.EOF) when the row group is exhausted. +func (r *VariantReader) Next(n int) (int, error) { + if r.err != nil { + return 0, r.err + } + if n <= 0 { + return 0, nil + } + remaining := r.numRows - r.rowOffset + if remaining <= 0 { + return 0, io.EOF + } + if int64(n) > remaining { + n = int(remaining) + } + if r.leafSet == nil { + r.leafSet = make(map[*variantLeafReader]struct{}) + } + clear(r.leafSet) + r.collectLeaves(r.root, r.leafSet) + for l := range r.leafSet { + if err := l.readWindow(n); err != nil { + r.err = err + return 0, err + } + } + if err := r.root.process(n); err != nil { + r.err = err + return 0, err + } + r.rowOffset += int64(n) + return n, nil +} + +func (r *VariantReader) collectLeaves(c *VariantCursor, seen map[*variantLeafReader]struct{}) { + if c == r.root { + seen[r.metaLeaf] = struct{}{} + } + for _, l := range [...]*variantLeafReader{c.valueLeaf, c.typedLeaf, c.presenceLeaf} { + if l != nil { + seen[l] = struct{}{} + } + } + for _, ch := range c.childList { + r.collectLeaves(ch, seen) + } +} + +// SeekToRow positions the reader such that the next call to Next starts at +// the given row of the row group. +func (r *VariantReader) SeekToRow(rowIndex int64) error { + if r.err != nil { + return r.err + } + if rowIndex < 0 || rowIndex > r.numRows { + return fmt.Errorf("variant: seek to row %d out of range [0, %d]", rowIndex, r.numRows) + } + r.rowOffset = rowIndex + for _, l := range r.leaves { + if l != nil && l.opened { + l.pendingSeek = rowIndex + } + } + return nil +} + +// Close releases the page readers of all columns opened by the reader. +func (r *VariantReader) Close() error { + var firstErr error + for _, l := range r.leaves { + if l == nil || !l.opened { + continue + } + if l.page != nil { + Release(l.page) + l.page = nil + } + if err := l.pages.Close(); err != nil && firstErr == nil { + firstErr = err + } + l.opened = false + } + return firstErr +} + +func (r *VariantReader) metadataFor(row int32) (variant.Metadata, error) { + w := &r.metaLeaf.win + d := w.denseIdx[row] + if d < 0 { + return variant.Metadata{}, fmt.Errorf("variant: missing metadata for window row %d", row) + } + b := w.slab[w.offsets[d]:w.offsets[d+1]] + if m, ok := r.metaCache[string(b)]; ok { + return m, nil + } + m, err := variant.DecodeMetadata(b) + if err != nil { + return variant.Metadata{}, fmt.Errorf("variant metadata: %w", err) + } + // The cache key copies the bytes (they alias the window slab); cap the + // cache so files with per-row unique metadata do not grow it unboundedly. + if len(r.metaCache) < 4096 { + r.metaCache[string(b)] = m + } + return m, nil +} + +// VariantCursor is a position in the variant navigation tree: the root +// value, an object field, or a list element. See VariantReader. +type VariantCursor struct { + reader *VariantReader + parent *VariantCursor + node *shreddedVariantGroup // nil for cursors below the shredded schema + kind VariantCursorKind + + fieldName string // step from parent, for field cursors + isElements bool // step from parent, for element cursors + + depth int // repetition depth within the variant subtree + + valueLeaf *variantLeafReader + typedLeaf *variantLeafReader // primitive typed_value + presenceLeaf *variantLeafReader // first leaf under an object/list typed_value + valueMaxDef byte + typedMaxDef byte + typedDefAbs byte // definition level at which typed_value is present + elemsDefAbs byte // definition level at which a typed list has elements + + children map[string]*VariantCursor + childList []*VariantCursor + elemsCursor *VariantCursor + hasVirtualChild bool + + // Window state. All slices are indexed by entry: one entry per row for + // row-level cursors, one per list element for element cursors. + // + // Residual state is stored sparsely: entries holding residual bytes or + // values are rare in shredded-heavy data, and per-entry storage of a + // variant.Value (144 bytes) plus a byte-slice header dominated the + // reader's memory footprint and window-reset cost. + identityRows bool // entry i is row i; rows stays nil + identitySlots bool // entry i is slot group i; slotGroup stays nil + locs []variant.Loc + slotGroup []int32 // slot group in this node's own columns, -1 if none + rows []int32 // window row of each entry, nil means identity + res []variantResidual // residual state of tagged entries, ascending by entry + typedRows []int32 + listOffsets []int32 + residualCount int +} + +// variantResidual is the residual state of one entry: the raw bytes from the +// value column (nil for navigated entries, which are born decoded) and the +// lazily decoded value. +type variantResidual struct { + bytes []byte + val variant.Value + entry int32 + decoded bool +} + +func (r *VariantReader) newNodeCursor(parent *VariantCursor, node *shreddedVariantGroup, name string, elements bool) *VariantCursor { + c := &VariantCursor{ + reader: r, + parent: parent, + node: node, + fieldName: name, + isElements: elements, + depth: node.repDepth, + children: make(map[string]*VariantCursor), + } + c.identityRows = parent == nil || (!elements && parent.identityRows) + c.identitySlots = parent == nil || (!elements && parent.identitySlots) + if node.valueCol >= 0 { + c.valueLeaf = r.leafFor(node.valueCol) + c.valueMaxDef = r.leafInfo[node.valueCol].maxDef + } + if t := node.typed; t != nil { + c.typedDefAbs = byte(r.groupDef + t.defLevel) + switch t.kind { + case shreddedTypedPrimitive: + c.kind = VariantCursorLeaf + c.typedLeaf = r.leafFor(t.startCol) + c.typedMaxDef = byte(r.groupDef + t.defLevel) + case shreddedTypedObject: + c.kind = VariantCursorObject + c.presenceLeaf = r.leafFor(t.startCol) + case shreddedTypedList: + c.kind = VariantCursorList + c.presenceLeaf = r.leafFor(t.startCol) + c.elemsDefAbs = byte(r.groupDef + t.defLevel + 1) + } + } else { + c.kind = VariantCursorUnshredded + } + return c +} + +func (r *VariantReader) newVirtualCursor(parent *VariantCursor, name string, elements bool) *VariantCursor { + return &VariantCursor{ + reader: r, + parent: parent, + kind: VariantCursorUnshredded, + fieldName: name, + isElements: elements, + depth: parent.depth, + children: make(map[string]*VariantCursor), + identityRows: !elements && parent.identityRows, + // Virtual cursors have no columns of their own, so their slot + // groups are never read; leaving identitySlots set skips the + // per-entry slotGroup appends. + identitySlots: true, + } +} + +// Kind returns the static kind of the cursor position, derived from the +// shredded schema. +func (c *VariantCursor) Kind() VariantCursorKind { return c.kind } + +// LeafType returns the parquet type of the typed_value column for cursors of +// kind VariantCursorLeaf, and nil otherwise. The type's logical type +// identifies the variant type per the shredded types table (e.g. a +// STRING-annotated BYTE_ARRAY holds variant strings). +func (c *VariantCursor) LeafType() Type { + if c.typedLeaf != nil { + return c.typedLeaf.typ + } + return nil +} + +// Fields returns the names of the shredded fields at a cursor of kind +// VariantCursorObject, in schema order, and nil for other kinds. Residual +// fields of partially shredded objects are not listed; they are reached +// through Residual (or by name through Field). +func (c *VariantCursor) Fields() []string { + if c.node == nil || c.node.typed == nil || c.node.typed.kind != shreddedTypedObject { + return nil + } + names := make([]string, len(c.node.typed.fields)) + for i, f := range c.node.typed.fields { + names[i] = f.name + } + return names +} + +// Field returns the cursor for the object field with the given name below +// this cursor. Navigation is total: if the field is not part of the shredded +// schema at this position, the returned cursor is backed by per-row +// navigation of residual values. +func (c *VariantCursor) Field(name string) *VariantCursor { + if ch := c.children[name]; ch != nil { + return ch + } + var ch *VariantCursor + if c.node != nil && c.node.typed != nil && c.node.typed.kind == shreddedTypedObject { + if g := c.node.typed.fieldByName(name); g != nil { + ch = c.reader.newNodeCursor(c, g, name, false) + } + } + if ch == nil { + ch = c.reader.newVirtualCursor(c, name, false) + c.hasVirtualChild = true + } + c.children[name] = ch + c.childList = append(c.childList, ch) + return ch +} + +// Elements returns the cursor for the elements of lists at this position. +// The element entry space concatenates, in row order, the elements of typed +// (shredded) lists and the elements of residual values that turn out to be +// arrays, so an engine can process mixed shredded/residual lists in one +// loop. ListOffsets on this cursor maps entries to element ranges. +func (c *VariantCursor) Elements() *VariantCursor { + if c.elemsCursor != nil { + return c.elemsCursor + } + var ch *VariantCursor + if c.node != nil && c.node.typed != nil && c.node.typed.kind == shreddedTypedList { + ch = c.reader.newNodeCursor(c, c.node.typed.element, "", true) + } else { + ch = c.reader.newVirtualCursor(c, "", true) + c.hasVirtualChild = true + } + c.elemsCursor = ch + c.childList = append(c.childList, ch) + return ch +} + +// Locs returns the location tag of every entry of the current window: one +// per row for row-level cursors, one per element for element cursors. +func (c *VariantCursor) Locs() []variant.Loc { return c.locs } + +// Rows maps each entry of the current window to its row index within the +// window. For row-level cursors the mapping is the identity and Rows returns +// nil; for element cursors (and cursors below them) it returns one row index +// per entry, and several entries may map to one row. +func (c *VariantCursor) Rows() []int32 { return c.rows } + +// ResidualCount returns the number of entries tagged variant.LocResidual in +// the current window. A zero count lets an engine skip per-entry residual +// decoding, though Residual may still return values for entries tagged +// variant.LocNull or variant.LocTypedObject (partial-object leftovers). +func (c *VariantCursor) ResidualCount() int { return c.residualCount } + +// TypedRows maps each value of the typed vectors to its entry index in the +// current window: TypedRows()[i] is the entry holding the i-th typed value. +func (c *VariantCursor) TypedRows() []int32 { return c.typedRows } + +// Booleans returns the dense typed values of a BOOLEAN leaf cursor. +func (c *VariantCursor) Booleans() []bool { + if c.typedLeaf == nil { + return nil + } + return c.typedLeaf.win.bools +} + +// Int32s returns the dense typed values of an INT32-backed leaf cursor +// (int8, int16, int32, date, and decimal4 variant types). +func (c *VariantCursor) Int32s() []int32 { + if c.typedLeaf == nil { + return nil + } + return c.typedLeaf.win.i32 +} + +// Int64s returns the dense typed values of an INT64-backed leaf cursor +// (int64, timestamps, time, and decimal8 variant types). +func (c *VariantCursor) Int64s() []int64 { + if c.typedLeaf == nil { + return nil + } + return c.typedLeaf.win.i64 +} + +// Floats returns the dense typed values of a FLOAT leaf cursor. +func (c *VariantCursor) Floats() []float32 { + if c.typedLeaf == nil { + return nil + } + return c.typedLeaf.win.f32 +} + +// Doubles returns the dense typed values of a DOUBLE leaf cursor. +func (c *VariantCursor) Doubles() []float64 { + if c.typedLeaf == nil { + return nil + } + return c.typedLeaf.win.f64 +} + +// ByteArrays returns the dense typed values of a BYTE_ARRAY-backed leaf +// cursor (string, binary, and byte-array decimal variant types) as a shared +// slab plus len+1 offsets: value i is slab[offsets[i]:offsets[i+1]]. +func (c *VariantCursor) ByteArrays() (slab []byte, offsets []uint32) { + if c.typedLeaf == nil { + return nil, nil + } + return c.typedLeaf.win.slab, c.typedLeaf.win.offsets +} + +// FixedLenByteArrays returns the dense typed values of a +// FIXED_LEN_BYTE_ARRAY-backed leaf cursor (uuid and fixed decimal variant +// types) as a shared slab of size-byte values. +func (c *VariantCursor) FixedLenByteArrays() (slab []byte, size int) { + if c.typedLeaf == nil { + return nil, 0 + } + return c.typedLeaf.win.flba, c.typedLeaf.win.flbaSize +} + +// ListOffsets returns len(entries)+1 offsets into the entry space of the +// Elements cursor: the elements of entry e span +// Elements() entries [offsets[e], offsets[e+1]). It is computed only when +// Elements was called before the window was read. +func (c *VariantCursor) ListOffsets() []int32 { return c.listOffsets } + +// Residual returns the residual variant value of entry i. It is valid for +// entries tagged variant.LocResidual (the value itself), variant.LocNull (the +// variant null value), and variant.LocTypedObject when the row is a partially +// shredded object (the leftover fields not covered by the shredded schema, +// as a variant object). The boolean result reports whether a residual value +// exists at the entry. +func (c *VariantCursor) Residual(i int) (variant.Value, bool, error) { + if i < 0 || i >= len(c.locs) { + return variant.Null(), false, fmt.Errorf("variant: residual index %d out of range", i) + } + switch c.locs[i] { + case variant.LocNull: + return variant.Null(), true, nil + case variant.LocResidual, variant.LocTypedObject: + r := c.residualAt(i) + if r == nil { + return variant.Null(), false, nil + } + if r.decoded { + return r.val, true, nil + } + v, err := c.decodeResidual(r) + if err != nil { + return variant.Null(), false, err + } + return v, true, nil + default: + return variant.Null(), false, nil + } +} + +// residualAt returns the residual state of entry e, or nil if the entry has +// none. res is sorted by entry (windows are built in entry order). +func (c *VariantCursor) residualAt(e int) *variantResidual { + i, ok := slices.BinarySearchFunc(c.res, int32(e), func(r variantResidual, e int32) int { + return int(r.entry) - int(e) + }) + if !ok { + return nil + } + return &c.res[i] +} + +// addResidual appends residual state for entry e, which must be greater than +// the entry of any state added to this window before it. The pointer is +// valid only until the next call to addResidual. +func (c *VariantCursor) addResidual(e int) *variantResidual { + c.res = append(c.res, variantResidual{entry: int32(e)}) + return &c.res[len(c.res)-1] +} + +func (c *VariantCursor) decodeResidual(r *variantResidual) (variant.Value, error) { + m, err := c.reader.metadataFor(c.rowOf(int(r.entry))) + if err != nil { + return variant.Null(), err + } + v, err := variant.Decode(m, r.bytes) + if err != nil { + return variant.Null(), fmt.Errorf("variant: decoding residual value: %w", err) + } + r.val = v + r.decoded = true + return v, nil +} + +func (c *VariantCursor) rowOf(i int) int32 { + if c.rows == nil { + return int32(i) + } + return c.rows[i] +} + +// resetWindow clears the per-window state, retaining slice capacity. The +// residual entries are cleared so that references to window slabs and +// decoded values do not outlive the window. +func (c *VariantCursor) resetWindow() { + c.locs = c.locs[:0] + c.slotGroup = c.slotGroup[:0] + c.rows = c.rows[:0] + clear(c.res) + c.res = c.res[:0] + c.typedRows = c.typedRows[:0] + c.listOffsets = c.listOffsets[:0] + c.residualCount = 0 +} + +// growEntries bulk-extends the window to n entries, all tagged +// variant.LocMissing, for the flat window paths that fill locs in place. +func (c *VariantCursor) growEntries(n int) { + c.locs = slices.Grow(c.locs, n)[:n] + clear(c.locs) +} + +func (c *VariantCursor) appendEntry(group, row int32) int { + c.locs = append(c.locs, variant.LocMissing) + if !c.identitySlots { + c.slotGroup = append(c.slotGroup, group) + } + if !c.identityRows { + c.rows = append(c.rows, row) + } + return len(c.locs) - 1 +} + +// groupOf returns the slot group of entry e in this node's own columns. +func (c *VariantCursor) groupOf(e int) int32 { + if c.identitySlots { + return int32(e) + } + return c.slotGroup[e] +} + +func (c *VariantCursor) setNavigated(e int, v variant.Value) { + if v.IsNull() { + c.locs[e] = variant.LocNull + } else { + c.locs[e] = variant.LocResidual + c.residualCount++ + } + r := c.addResidual(e) + r.val = v + r.decoded = true +} + +// process recomputes the cursor's window state from its leaf windows (or its +// parent's residuals), then recurses into child cursors. +func (c *VariantCursor) process(n int) error { + c.resetWindow() + var err error + switch { + case c.parent == nil: + err = c.processRoot(n) + case c.isElements: + err = c.processElements() + case c.node != nil: + err = c.processShreddedField() + default: + err = c.processVirtualField() + } + if err != nil { + return err + } + if len(c.childList) > 0 { + if err := c.decodeResiduals(); err != nil { + return err + } + } + for _, ch := range c.childList { + if err := ch.process(n); err != nil { + return err + } + } + return nil +} + +// decodeResiduals eagerly decodes the residual values that child cursors +// navigate through: all variant.LocResidual entries, plus partial-object +// leftovers when a non-shredded field cursor exists below this one. +func (c *VariantCursor) decodeResiduals() error { + for i := range c.res { + r := &c.res[i] + if r.decoded || r.bytes == nil { + continue + } + if c.locs[r.entry] == variant.LocTypedObject && !c.hasVirtualChild { + continue + } + if _, err := c.decodeResidual(r); err != nil { + return err + } + } + return nil +} + +// flatWindow reports whether the cursor can use the bulk window path: no +// slot or row indirection, and one slot per entry in every leaf window it +// reads. The value and primitive typed_value leaves of a depth-0 cursor are +// never repeated, but the presence leaf can be: it is the first leaf under +// an object or list typed_value, which may sit below a repeated level (a +// list typed_value always does). +func (c *VariantCursor) flatWindow() bool { + return c.depth == 0 && c.identitySlots && c.identityRows && + (c.presenceLeaf == nil || c.presenceLeaf.maxRep == 0) +} + +func (c *VariantCursor) processRoot(n int) error { + mw := &c.reader.metaLeaf.win + if c.flatWindow() { + c.growEntries(n) + c.computeOwnFlat(n, mw.defs, byte(c.reader.groupDef), variant.LocNull) + return nil + } + for row := range n { + e := c.appendEntry(int32(row), int32(row)) + if mw.defs[row] < byte(c.reader.groupDef) { + c.locs[e] = variant.LocMissing + } else { + c.computeOwn(e, int32(row), variant.LocNull) + } + } + return nil +} + +func (c *VariantCursor) processShreddedField() error { + p := c.parent + n := len(p.locs) + if c.flatWindow() && p.residualCount == 0 { + // No parent entry needs residual navigation, so every entry is + // resolved from this node's own columns: entries below an absent + // parent read as missing there too (their definition levels are + // below the maxima). + c.growEntries(n) + c.computeOwnFlat(n, nil, 0, variant.LocMissing) + return nil + } + for e := range n { + g := p.groupOf(e) + e2 := c.appendEntry(g, p.rowOf(e)) + switch p.locs[e] { + case variant.LocTypedObject: + // A typed object always has its own column slots (navigated + // residual entries can only be tagged null or residual). + c.computeOwn(e2, g, variant.LocMissing) + case variant.LocResidual: + if r := p.residualAt(e); r != nil && r.decoded { + c.navigateField(e2, r.val) + } + } + } + return nil +} + +func (c *VariantCursor) processVirtualField() error { + p := c.parent + n := len(p.locs) + if c.identityRows && len(p.res) == 0 { + // Virtual fields exist only inside residual values; with none in + // the parent window every entry is missing. + c.growEntries(n) + return nil + } + for e := range n { + e2 := c.appendEntry(-1, p.rowOf(e)) + switch p.locs[e] { + case variant.LocResidual, variant.LocTypedObject: + if r := p.residualAt(e); r != nil && r.decoded { + c.navigateField(e2, r.val) + } + } + } + return nil +} + +func (c *VariantCursor) navigateField(e int, pv variant.Value) { + if pv.Basic() != variant.BasicObject { + return // stays missing + } + for _, f := range pv.ObjectValue().Fields { + if f.Name == c.fieldName { + c.setNavigated(e, f.Value) + return + } + } +} + +func (c *VariantCursor) processElements() error { + p := c.parent + var startsP, startsE []int32 + var plw *variantLeafWindow + h := 0 + if c.node != nil { + plw = &p.presenceLeaf.win + startsP = plw.starts(p.depth) + startsE = plw.starts(c.depth) + } + p.listOffsets = append(p.listOffsets[:0], 0) + for e := range p.locs { + switch p.locs[e] { + case variant.LocTypedList: + g := p.groupOf(e) + // g beyond the presence column's group count means the file + // is corrupt (sibling columns must agree); skip the entry. + if g < 0 || c.node == nil || int(g) >= len(startsP)-1 { + break + } + gs, ge := startsP[g], startsP[g+1] + for h < len(startsE)-1 && startsE[h] < gs { + h++ + } + if plw.defs[gs] >= p.elemsDefAbs { + for h < len(startsE)-1 && startsE[h] < ge { + e2 := c.appendEntry(int32(h), p.rowOf(e)) + c.computeOwn(e2, int32(h), variant.LocNull) + h++ + } + } + case variant.LocResidual: + if r := p.residualAt(e); r != nil && r.decoded && r.val.Basic() == variant.BasicArray { + for _, elem := range r.val.ArrayValue().Elements { + e2 := c.appendEntry(-1, p.rowOf(e)) + c.setNavigated(e2, elem) + } + } + } + p.listOffsets = append(p.listOffsets, int32(len(c.locs))) + } + return nil +} + +// computeOwn resolves the location of entry e from the node's own value and +// typed_value columns at slot group g. missingLoc is the tag used when both +// sides are null: variant.LocMissing for object fields, variant.LocNull for +// the root and list elements (where both-null is invalid per the spec and +// read as variant null, matching the row-based reader). +func (c *VariantCursor) computeOwn(e int, g int32, missingLoc variant.Loc) { + var vbytes []byte + valuePresent := false + if c.valueLeaf != nil { + w := &c.valueLeaf.win + if s, ok := w.slotOf(c.depth, g); ok && w.defs[s] == c.valueMaxDef { + d := w.denseIdx[s] + vbytes = w.slab[w.offsets[d]:w.offsets[d+1]] + valuePresent = true + } + } + if t := c.node.typed; t != nil { + switch t.kind { + case shreddedTypedPrimitive: + w := &c.typedLeaf.win + if s, ok := w.slotOf(c.depth, g); ok && w.defs[s] == c.typedMaxDef { + // The spec requires value to be null when a primitive + // typed_value is present; if a non-compliant writer set + // both, the typed side wins (readers may assume data is + // written correctly). + c.locs[e] = variant.LocTyped + c.typedRows = append(c.typedRows, int32(e)) + return + } + case shreddedTypedObject: + w := &c.presenceLeaf.win + if s, ok := w.slotOf(c.depth, g); ok && w.defs[s] >= c.typedDefAbs { + c.locs[e] = variant.LocTypedObject + if valuePresent { + c.addResidual(e).bytes = vbytes // partially shredded object + } + return + } + case shreddedTypedList: + w := &c.presenceLeaf.win + if s, ok := w.slotOf(c.depth, g); ok && w.defs[s] >= c.typedDefAbs { + c.locs[e] = variant.LocTypedList + return + } + } + } + if valuePresent { + if len(vbytes) == 0 || vbytes[0] == 0x00 { + // Variant null is a one-byte value with a zero header. Empty + // bytes are how the plain unshredded write path stores a zero + // variant value; the row-based reader reads them as null too. + c.locs[e] = variant.LocNull + } else { + c.locs[e] = variant.LocResidual + c.addResidual(e).bytes = vbytes + c.residualCount++ + } + return + } + c.locs[e] = missingLoc +} + +// computeOwnFlat is the bulk equivalent of computeOwn for flat cursors (see +// flatWindow): entry e reads slot e of every leaf window directly. Entries +// whose gate level (the metadata column for the root) is below gateDef stay +// variant.LocMissing; growEntries pre-tagged every entry that way, so the +// loops only write the other locations. +func (c *VariantCursor) computeOwnFlat(n int, gate []byte, gateDef byte, missingLoc variant.Loc) { + locs := c.locs + switch { + case c.typedLeaf != nil: // primitive typed_value + tdefs := c.typedLeaf.win.defs + for e := range n { + if gate != nil && gate[e] < gateDef { + continue + } + if tdefs[e] == c.typedMaxDef { + locs[e] = variant.LocTyped + c.typedRows = append(c.typedRows, int32(e)) + continue + } + c.resolveValueFlat(e, missingLoc, false) + } + case c.presenceLeaf != nil: // object or list typed_value + typedLoc := variant.LocTypedObject + isObject := c.node.typed.kind == shreddedTypedObject + if !isObject { + typedLoc = variant.LocTypedList + } + pdefs := c.presenceLeaf.win.defs + for e := range n { + if gate != nil && gate[e] < gateDef { + continue + } + if pdefs[e] >= c.typedDefAbs { + locs[e] = typedLoc + if isObject { + // A present value column holds the leftover fields of + // a partially shredded object. + c.resolveValueFlat(e, typedLoc, true) + } + continue + } + c.resolveValueFlat(e, missingLoc, false) + } + default: // no typed_value column + for e := range n { + if gate != nil && gate[e] < gateDef { + continue + } + c.resolveValueFlat(e, missingLoc, false) + } + } +} + +// resolveValueFlat resolves entry e of a flat cursor from the value column +// alone: fallbackLoc when the column is null there, variant.LocNull or +// variant.LocResidual otherwise. With partialObject set (entry already +// tagged variant.LocTypedObject) a present value only records its leftover +// bytes. +func (c *VariantCursor) resolveValueFlat(e int, fallbackLoc variant.Loc, partialObject bool) { + if c.valueLeaf != nil { + w := &c.valueLeaf.win + if w.defs[e] == c.valueMaxDef { + d := w.denseIdx[e] + vbytes := w.slab[w.offsets[d]:w.offsets[d+1]] + switch { + case partialObject: + c.addResidual(e).bytes = vbytes + case len(vbytes) == 0 || vbytes[0] == 0x00: + // See computeOwn: zero or empty bytes read as variant null. + c.locs[e] = variant.LocNull + default: + c.locs[e] = variant.LocResidual + c.addResidual(e).bytes = vbytes + c.residualCount++ + } + return + } + } + c.locs[e] = fallbackLoc +} + +// variantLeafWindow holds the current window of one leaf column in columnar +// form: one definition level (and repetition level for repeated leaves) per +// slot, and the non-null values densely in typed buffers. All buffers are +// reused across windows. +type variantLeafWindow struct { + defs []byte + reps []byte // nil when the leaf is not repeated + denseIdx []int32 // slot -> index in the typed buffers, -1 for null slots + dense int + + // starts[d] lists the first slot of every repetition-depth-d group in + // the window (plus a final sentinel of numSlots). Depth 0 groups are + // rows. Computed lazily per depth per window. + startsByDepth [][]int32 + startsValid []bool + + bools []bool + i32 []int32 + i64 []int64 + f32 []float32 + f64 []float64 + slab []byte + offsets []uint32 // ByteArray: len == dense+1 + flba []byte + flbaSize int +} + +func (w *variantLeafWindow) reset() { + w.defs = w.defs[:0] + w.reps = w.reps[:0] + w.denseIdx = w.denseIdx[:0] + w.dense = 0 + for i := range w.startsValid { + w.startsValid[i] = false + } + w.bools = w.bools[:0] + w.i32 = w.i32[:0] + w.i64 = w.i64[:0] + w.f32 = w.f32[:0] + w.f64 = w.f64[:0] + w.slab = w.slab[:0] + w.offsets = append(w.offsets[:0], 0) + w.flba = w.flba[:0] +} + +// slotOf returns the first slot of depth-d group g and whether the group +// exists in the window. Sibling columns of a valid file agree on group +// counts; a missing group means the file is corrupt, and the caller treats +// the position as missing rather than panicking. +func (w *variantLeafWindow) slotOf(depth int, g int32) (int32, bool) { + if len(w.reps) == 0 { + // Non-repeated window: every slot is its own group at every depth, + // so the starts mapping is the identity. + if int(g) >= len(w.defs) { + return 0, false + } + return g, true + } + starts := w.starts(depth) + if int(g) >= len(starts)-1 { + return 0, false + } + return starts[g], true +} + +func (w *variantLeafWindow) starts(depth int) []int32 { + for len(w.startsByDepth) <= depth { + w.startsByDepth = append(w.startsByDepth, nil) + w.startsValid = append(w.startsValid, false) + } + if w.startsValid[depth] { + return w.startsByDepth[depth] + } + s := w.startsByDepth[depth][:0] + if len(w.reps) == 0 { + for i := range w.defs { + s = append(s, int32(i)) + } + } else { + for i, rp := range w.reps { + if int(rp) <= depth { + s = append(s, int32(i)) + } + } + } + s = append(s, int32(len(w.defs))) + w.startsByDepth[depth] = s + w.startsValid[depth] = true + return s +} + +// variantLeafReader reads windows of one leaf column of the variant subtree +// from its pages, extracting levels and typed data without boxing values. +type variantLeafReader struct { + reader *VariantReader + relCol int + typ Type + kind Kind + maxDef byte + maxRep byte + + opened bool + pages Pages + pendingSeek int64 + + // Current page state. + page Page + pdefs []byte + preps []byte + pcount int // slots in the page + ppos int // slots consumed + pdense int // non-null values consumed + + // Typed data of the current page (one of these per kind), or dictionary + // indexes when the page is dictionary-encoded. + pi32 []int32 + pi64 []int64 + pf32 []float32 + pf64 []float64 + pba []byte + pbaOff []uint32 + pflba []byte + pflbaN int + pbools []bool + pidx []int32 + dictSet bool + di32 []int32 + di64 []int64 + df32 []float32 + df64 []float64 + dba []byte + dbaOff []uint32 + dflba []byte + dflbaN int + + win variantLeafWindow +} + +func (l *variantLeafReader) open() error { + chunks := l.reader.rowGroup.ColumnChunks() + col := l.reader.baseColumn + l.relCol + if col >= len(chunks) { + return fmt.Errorf("variant: column %d out of range", col) + } + l.pages = chunks[col].Pages() + l.opened = true + if l.reader.rowOffset > 0 && l.pendingSeek < 0 { + l.pendingSeek = l.reader.rowOffset + } + return nil +} + +func (l *variantLeafReader) readWindow(nRows int) error { + if !l.opened { + if err := l.open(); err != nil { + return err + } + } + if l.pendingSeek >= 0 { + if l.page != nil { + Release(l.page) + l.page = nil + } + if err := l.pages.SeekToRow(l.pendingSeek); err != nil { + return err + } + l.pendingSeek = -1 + } + w := &l.win + w.reset() + rowsDone := 0 + started := false + for { + if err := l.ensurePage(); err != nil { + if err == io.EOF { + if started { + rowsDone++ + } + if rowsDone == nRows { + return nil + } + return fmt.Errorf("variant: column %d ended after %d of %d rows", l.reader.baseColumn+l.relCol, rowsDone, nRows) + } + return err + } + rep := byte(0) + if l.preps != nil { + rep = l.preps[l.ppos] + } + if rep == 0 { + if started { + rowsDone++ + if rowsDone == nRows { + return nil + } + } + started = true + } + l.consumeSlot(w, rep) + } +} + +func (l *variantLeafReader) ensurePage() error { + for l.page == nil || l.ppos == l.pcount { + if l.page != nil { + Release(l.page) + l.page = nil + } + p, err := l.pages.ReadPage() + if err != nil { + return err + } + if err := l.setPage(p); err != nil { + // setPage stored the page in l.page; clear it so Close does + // not release it a second time. + l.page = nil + Release(p) + return err + } + } + return nil +} + +func (l *variantLeafReader) setPage(p Page) error { + l.page = p + l.pdefs = p.DefinitionLevels() + l.preps = p.RepetitionLevels() + if l.pdefs != nil { + l.pcount = len(l.pdefs) + } else { + l.pcount = int(p.NumValues()) + } + l.ppos, l.pdense = 0, 0 + l.pidx = nil + + if l.kind == Boolean { + // Boolean page data is bit-packed with an internal bit offset that + // Data() does not expose for sliced pages, so booleans go through + // the page's value reader instead. + if err := l.extractBooleans(p); err != nil { + return err + } + return l.checkPageValues() + } + + data := p.Data() + if d := p.Dictionary(); d != nil { + l.pidx = data.Int32() + if !l.dictSet { + dd := d.Page().Data() + switch l.kind { + case Int32: + l.di32 = dd.Int32() + case Int64: + l.di64 = dd.Int64() + case Float: + l.df32 = dd.Float() + case Double: + l.df64 = dd.Double() + case ByteArray: + l.dba, l.dbaOff = dd.ByteArray() + case FixedLenByteArray: + l.dflba, l.dflbaN = dd.FixedLenByteArray() + } + l.dictSet = true + } + return l.checkPageValues() + } + switch l.kind { + case Int32: + l.pi32 = data.Int32() + case Int64: + l.pi64 = data.Int64() + case Float: + l.pf32 = data.Float() + case Double: + l.pf64 = data.Double() + case ByteArray: + l.pba, l.pbaOff = data.ByteArray() + case FixedLenByteArray: + l.pflba, l.pflbaN = data.FixedLenByteArray() + default: + return fmt.Errorf("variant: unsupported page kind %s", l.kind) + } + return l.checkPageValues() +} + +// checkPageValues verifies that the page decoded at least as many non-null +// values as its definition levels declare, so that appendValue never indexes +// past the decoded data. The page decode layer does not enforce this for +// BYTE_ARRAY, dictionary-encoded, or data page v2 pages, where a corrupt +// value section can decode short without error. +func (l *variantLeafReader) checkPageValues() error { + needed := l.pcount + if l.pdefs != nil { + needed = countLevelsEqual(l.pdefs, l.maxDef) + } + var have int + switch { + case l.pidx != nil: + have = len(l.pidx) + case l.kind == Boolean: + have = len(l.pbools) + case l.kind == Int32: + have = len(l.pi32) + case l.kind == Int64: + have = len(l.pi64) + case l.kind == Float: + have = len(l.pf32) + case l.kind == Double: + have = len(l.pf64) + case l.kind == ByteArray: + if n := len(l.pbaOff); n > 0 { + have = n - 1 + } + case l.kind == FixedLenByteArray: + if l.pflbaN > 0 { + have = len(l.pflba) / l.pflbaN + } + } + if have < needed { + return fmt.Errorf("variant: column %d page declares %d non-null values but decoded %d: %w", + l.reader.baseColumn+l.relCol, needed, have, ErrCorrupted) + } + return nil +} + +func (l *variantLeafReader) extractBooleans(p Page) error { + l.pbools = l.pbools[:0] + vr := p.Values() + var buf [128]Value + for { + n, err := vr.ReadValues(buf[:]) + for _, v := range buf[:n] { + if !v.IsNull() { + l.pbools = append(l.pbools, v.Boolean()) + } + } + if err == io.EOF { + return nil + } + if err != nil { + return err + } + if n == 0 { + return fmt.Errorf("variant: boolean page reader made no progress") + } + } +} + +func (l *variantLeafReader) consumeSlot(w *variantLeafWindow, rep byte) { + def := l.maxDef + if l.pdefs != nil { + def = l.pdefs[l.ppos] + } + w.defs = append(w.defs, def) + if l.maxRep > 0 { + w.reps = append(w.reps, rep) + } + if def == l.maxDef { + w.denseIdx = append(w.denseIdx, int32(w.dense)) + w.dense++ + l.appendValue(w) + } else { + w.denseIdx = append(w.denseIdx, -1) + } + l.ppos++ +} + +func (l *variantLeafReader) appendValue(w *variantLeafWindow) { + i := l.pdense + l.pdense++ + switch l.kind { + case Boolean: + w.bools = append(w.bools, l.pbools[i]) + case Int32: + if l.pidx != nil { + w.i32 = append(w.i32, l.di32[l.pidx[i]]) + } else { + w.i32 = append(w.i32, l.pi32[i]) + } + case Int64: + if l.pidx != nil { + w.i64 = append(w.i64, l.di64[l.pidx[i]]) + } else { + w.i64 = append(w.i64, l.pi64[i]) + } + case Float: + if l.pidx != nil { + w.f32 = append(w.f32, l.df32[l.pidx[i]]) + } else { + w.f32 = append(w.f32, l.pf32[i]) + } + case Double: + if l.pidx != nil { + w.f64 = append(w.f64, l.df64[l.pidx[i]]) + } else { + w.f64 = append(w.f64, l.pf64[i]) + } + case ByteArray: + var b []byte + if l.pidx != nil { + j := l.pidx[i] + b = l.dba[l.dbaOff[j]:l.dbaOff[j+1]] + } else { + b = l.pba[l.pbaOff[i]:l.pbaOff[i+1]] + } + w.slab = append(w.slab, b...) + w.offsets = append(w.offsets, uint32(len(w.slab))) + case FixedLenByteArray: + if l.pidx != nil { + j := int(l.pidx[i]) + w.flba = append(w.flba, l.dflba[j*l.dflbaN:(j+1)*l.dflbaN]...) + w.flbaSize = l.dflbaN + } else { + w.flba = append(w.flba, l.pflba[i*l.pflbaN:(i+1)*l.pflbaN]...) + w.flbaSize = l.pflbaN + } + } +} diff --git a/vendor/github.com/parquet-go/parquet-go/variant_column_writer.go b/vendor/github.com/parquet-go/parquet-go/variant_column_writer.go new file mode 100644 index 00000000000..7260236424c --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/variant_column_writer.go @@ -0,0 +1,844 @@ +package parquet + +import ( + "fmt" + "math" + "strings" + + "github.com/google/uuid" + "github.com/parquet-go/parquet-go/variant" +) + +// This file implements a columnar, streaming writer for VARIANT columns. +// +// Unlike the row-based write path (column_buffer_variant.go) — which decodes +// each row into a variant.Value tree and shreds the tree — VariantColumnWriter +// consumes variant.ValueBuilder events and shreds them as they arrive: values +// matching the shredded type are appended directly to the typed_value column +// buffers, and everything else is encoded to variant binary residuals with a +// streaming variant.Builder. All rows share one metadata dictionary (reset +// only when it outgrows a bound), so a stable field set interns each name +// once and every row writes byte-identical metadata. No +// intermediate tree, map, or []parquet.Value is ever built, so transcoding +// e.g. JSON into a shredded variant column runs allocation-free per row once +// the writer's buffers are warm. +// +// The shredding semantics are identical to the row path: both follow the +// case tables of the Variant Shredding specification (summarized at the top +// of variant_shredded_write.go) and share variantToParquetValue and the +// shreddedVariantGroup tree. + +// VariantColumnWriter writes one VARIANT column of a parquet file in +// streaming, columnar form. It implements variant.ValueBuilder: each row is +// bracketed by BeginRow and EndRow, and the row's value is described by the +// event methods in between, following the event-sequence rules documented +// on variant.ValueBuilder. WriteValue and WriteNullRow are row-level +// conveniences. String and []byte event arguments, and Field names, are +// copied; callers may reuse their backing memory after the call returns. +// +// The writer appends to the column buffers of the ColumnWriters backing the +// variant column's leaf columns and flushes full pages at row boundaries, +// like ColumnWriter.WriteRowValues. To keep row boundaries cheap the +// page-size check is polled every few rows while the buffers are under half +// the configured page size (and every row past that), so pages may +// moderately overshoot the configured size. Other columns of the file must be +// written separately (e.g. through Writer.ColumnWriters) with the same +// number of rows, and the parent writer must be closed (or its row group +// committed) as usual to flush buffered sub-page data to the file. +// +// Errors are sticky: the first misuse or write failure is retained, +// subsequent events are ignored, and the error is reported by Err, EndRow, +// and row-level methods. After an error the underlying columns may hold a +// partial row, so the parent writer's current row group is inconsistent and +// must be abandoned as a whole, including the other columns' writers: for a +// ConcurrentRowGroupWriter target, do not Commit; for a Writer or +// GenericWriter target, discard the output. +// +// A VariantColumnWriter is not safe for concurrent use, and the parent +// writer must not be flushed, reset, or closed between BeginRow and EndRow +// (rows cannot span pages or row groups). +type VariantColumnWriter struct { + group *shreddedVariantGroup + groupDef int // definition level at which the variant group is present + optional bool // whether the variant group node itself is optional + columns []*ColumnWriter + + // rootValueRequired is set for plain unshredded variant groups, whose + // value field is required rather than optional. + rootValueRequired bool + + meta variant.MetadataBuilder + metaGen uint64 // bumped when meta resets; invalidates VariantFieldRef interns + metaBuf []byte + builders map[*shreddedVariantGroup]*variant.Builder + + // flushCountdown spaces out the page-size scan of flush, which is + // O(columns) and dominates wide schemas when run every row. + flushCountdown int + + // Row state. cur is the shredded node awaiting a value event, nil when + // no value is expected (inside an object before a Field call, or after + // the row's value completed). frames tracks open shredded containers; + // residual tracks an active residual stream. + inRow bool + cur *shreddedVariantGroup + curLevels shredLevels + frames []variantWriterFrame + residual variantResidualState + err error +} + +// variantWriterFrame is one open shredded container (an object or list +// being shredded field-wise or element-wise). +type variantWriterFrame struct { + node *shreddedVariantGroup + isList bool + levels shredLevels // level context of this container occurrence + seen []bool // objects: shredded fields that received a value + partial *variant.Builder + elems int // lists: elements written so far +} + +// variantResidualState tracks an active residual stream: events are +// forwarded to b until the container depth returns to base. +type variantResidualState struct { + b *variant.Builder + node *shreddedVariantGroup + levels shredLevels + depth int + base int +} + +// WriterTarget is the writer surface VariantColumnWriter binds to; +// it is satisfied by *Writer, *GenericWriter[T], and +// *ConcurrentRowGroupWriter. +type WriterTarget interface { + Schema() *Schema + ColumnWriters() []*ColumnWriter +} + +var ( + _ WriterTarget = (*Writer)(nil) + _ WriterTarget = (*GenericWriter[any])(nil) + _ WriterTarget = (*ConcurrentRowGroupWriter)(nil) +) + +// NewVariantColumnWriter returns a streaming columnar writer for the VARIANT +// column at the given path in w's schema (e.g. "event" for a top-level +// column, "attrs", "v" for one nested in a group). The column may be +// unshredded (metadata, value) or shredded (metadata, value, typed_value) +// in any shape permitted by the Variant Shredding specification. +func NewVariantColumnWriter(w WriterTarget, path ...string) (*VariantColumnWriter, error) { + schema := w.Schema() + if schema == nil { + return nil, fmt.Errorf("variant: the writer has no schema configured") + } + info, err := resolveVariantColumn(schema, path) + if err != nil { + return nil, err + } + group := info.group + + columnWriters := w.ColumnWriters() + if info.col+group.numCols > len(columnWriters) { + return nil, fmt.Errorf("variant: column %q spans columns [%d, %d) but the writer has %d", joinPath(path), info.col, info.col+group.numCols, len(columnWriters)) + } + + return &VariantColumnWriter{ + group: group, + groupDef: info.def, + optional: info.optional, + columns: columnWriters[info.col : info.col+group.numCols], + rootValueRequired: info.valueRequired, + builders: make(map[*shreddedVariantGroup]*variant.Builder), + }, nil +} + +// Err returns the first error encountered, or nil. +func (w *VariantColumnWriter) Err() error { return w.err } + +func (w *VariantColumnWriter) fail(format string, args ...any) { + if w.err == nil { + w.err = fmt.Errorf("variant writer: "+format, args...) + } +} + +// variantMetadataResetSize bounds the interned name bytes of the writer's +// metadata dictionary. The dictionary persists across rows so that a stable +// field set interns each name once and every row writes byte-identical +// metadata (which encodes and compresses well); the bound keeps workloads +// with unbounded field-name churn from bloating every row's metadata with +// names of earlier rows. +const variantMetadataResetSize = 4096 + +// variantFlushCheckRows is how many rows may pass between page-size checks +// of the variant group's columns while every column is under half its +// buffer size; past half, flush checks every row. +const variantFlushCheckRows = 16 + +// BeginRow starts a new row. Exactly one value — a single scalar event, or +// a single balanced object or array — must be written before the matching +// EndRow. +func (w *VariantColumnWriter) BeginRow() error { + if w.err != nil { + return w.err + } + if w.inRow { + w.fail("BeginRow inside a row") + return w.err + } + w.inRow = true + w.cur = w.group + w.curLevels = shredLevels{baseDef: w.groupDef} + if w.meta.Size() > variantMetadataResetSize { + w.meta.Reset() + w.metaGen++ + } + return nil +} + +// EndRow completes the current row: it writes the row's metadata dictionary +// and periodically flushes columns whose buffered page reached the writer's +// page size. +func (w *VariantColumnWriter) EndRow() error { + if w.err == nil && !w.inRow { + w.fail("EndRow outside of a row") + } + if w.err == nil && (w.residual.b != nil || len(w.frames) > 0) { + w.fail("EndRow with an unclosed object or array") + } + // With no open frames or residual, cur still set means the row's value + // never arrived (valueDone clears it when the value completes). + if w.err == nil && w.cur != nil { + w.fail("EndRow without a value; use WriteNullRow for SQL null rows") + } + if w.err != nil { + return w.err + } + // Dictionary offsets are at most 4 bytes wide; AppendTo would silently + // truncate a larger dictionary. Only reachable when a single row + // interns over 4 GiB of unique field names, since BeginRow resets the + // dictionary at variantMetadataResetSize. + if uint64(w.meta.Size()) > math.MaxUint32 { + w.fail("metadata dictionary of %d bytes exceeds the variant format's 4 GiB limit", w.meta.Size()) + return w.err + } + w.metaBuf = w.meta.AppendTo(w.metaBuf[:0]) + w.leaf(w.group.metadataCol).writeByteArray(w.levels(byte(w.groupDef), 0), w.metaBuf) + w.inRow = false + w.cur = nil + return w.flush() +} + +// WriteNullRow writes a row where the variant column itself is null (a SQL +// null, distinct from the variant null value). The variant group must be +// optional. Any optional ancestors of the variant group are written as +// present; the writer cannot express a row where an ancestor group is null. +func (w *VariantColumnWriter) WriteNullRow() error { + if w.err != nil { + return w.err + } + if w.inRow { + w.fail("WriteNullRow inside a row") + return w.err + } + if !w.optional { + w.fail("WriteNullRow on a required variant column") + return w.err + } + lv := w.levels(byte(w.groupDef-1), 0) + for col := range w.columns { + w.leaf(col).writeNull(lv) + } + return w.flush() +} + +// WriteValue writes one row holding the given variant value: it brackets +// v.Write(w) with BeginRow and EndRow and reports any error either raised. +func (w *VariantColumnWriter) WriteValue(v variant.Value) error { + if err := w.BeginRow(); err != nil { + return err + } + v.Write(w) + return w.EndRow() +} + +// leaf returns the column buffer of the relative leaf column, creating it on +// first use like ColumnWriter.WriteRowValues does. +func (w *VariantColumnWriter) leaf(col int) ColumnBuffer { + c := w.columns[col] + if c.columnBuffer == nil { + c.columnBuffer = c.newColumnBuffer() + if c.originalColumnBuffer == nil { + c.originalColumnBuffer = c.columnBuffer + } + } + return c.columnBuffer +} + +func (w *VariantColumnWriter) levels(def, rep byte) columnLevels { + return columnLevels{definitionLevel: def, repetitionLevel: rep} +} + +// flush flushes any column whose buffer reached the configured page size. +// It only runs at row boundaries, since a row cannot span two pages. While +// every column is under half its buffer size the poll is spaced out to +// every variantFlushCheckRows rows; once any column crosses half, it runs +// every row so a page cannot silently overshoot by many large rows. +func (w *VariantColumnWriter) flush() error { + if w.flushCountdown > 0 { + w.flushCountdown-- + return nil + } + w.flushCountdown = variantFlushCheckRows - 1 + for _, c := range w.columns { + if c.columnBuffer == nil { + continue + } + if size := c.columnBuffer.Size(); size >= int64(c.bufferSize) { + if err := c.Flush(); err != nil { + w.err = err + return err + } + } else if size >= int64(c.bufferSize)/2 { + w.flushCountdown = 0 + } + } + return nil +} + +// builder returns the residual builder of a shredded node, sharing the +// row's metadata dictionary. +func (w *VariantColumnWriter) builder(node *shreddedVariantGroup) *variant.Builder { + b := w.builders[node] + if b == nil { + b = variant.NewBuilderWithMetadata(&w.meta) + w.builders[node] = b + } + b.Reset() + return b +} + +// writeNulls writes one null to every leaf column in [startCol, endCol). +func (w *VariantColumnWriter) writeNulls(startCol, endCol int, def, rep byte) { + lv := w.levels(def, rep) + for col := startCol; col < endCol; col++ { + w.leaf(col).writeNull(lv) + } +} + +// writeMissing writes a missing occurrence of a shredded node (both value +// and typed_value null), which is how absent object fields are represented. +func (w *VariantColumnWriter) writeMissing(g *shreddedVariantGroup, l shredLevels) { + if g.valueCol >= 0 { + w.leaf(g.valueCol).writeNull(w.levels(l.def(g.defLevel), l.rep)) + } + if g.typed != nil { + w.writeNulls(g.typed.startCol, g.typed.startCol+g.typed.numCols, l.def(g.defLevel), l.rep) + } +} + +// writeResidualBytes writes encoded variant bytes to the node's value +// column. +func (w *VariantColumnWriter) writeResidualBytes(g *shreddedVariantGroup, l shredLevels, data []byte) { + if g.valueCol < 0 { + w.fail("value does not match the shredded type and the schema has no value column to fall back to") + return + } + def := l.def(g.defLevel) + 1 + if g == w.group && w.rootValueRequired { + def = byte(w.groupDef) + } + w.leaf(g.valueCol).writeByteArray(w.levels(def, l.rep), data) +} + +// writeTyped writes a matched scalar to the node's typed_value column. +func (w *VariantColumnWriter) writeTyped(col int, pv Value, def, rep byte) { + buf := w.leaf(col) + lv := w.levels(def, rep) + switch pv.Kind() { + case Boolean: + buf.writeBoolean(lv, pv.Boolean()) + case Int32: + buf.writeInt32(lv, pv.Int32()) + case Int64: + buf.writeInt64(lv, pv.Int64()) + case Float: + buf.writeFloat(lv, pv.Float()) + case Double: + buf.writeDouble(lv, pv.Double()) + default: + buf.writeByteArray(lv, pv.ByteArray()) + } +} + +// valueDone advances the row state after one value completed at node level: +// back to the row, to the enclosing object (awaiting the next Field), or to +// the next element of the enclosing list. +func (w *VariantColumnWriter) valueDone() { + w.cur = nil + if n := len(w.frames); n > 0 { + f := &w.frames[n-1] + if f.isList { + f.elems++ + w.cur = f.node.typed.element + w.curLevels = f.levels + w.curLevels.rep = byte(f.levels.baseRep + f.node.typed.element.repDepth) + } + } +} + +// forward reports whether events must stream into an active residual. +func (w *VariantColumnWriter) forward() bool { + return w.err == nil && w.residual.b != nil +} + +// checkResidual surfaces an error the residual builder recorded from a +// forwarded event (misuse of the event sequence, an oversized value) as the +// writer's error, so it is reported at the offending event rather than when +// the residual is committed. It reports whether the residual is healthy. +func (w *VariantColumnWriter) checkResidual() bool { + if err := w.residual.b.Err(); err != nil { + if w.err == nil { + w.err = err + } + return false + } + return true +} + +// residualDone finalizes a completed residual stream. +func (w *VariantColumnWriter) residualDone() { + r := w.residual + w.residual = variantResidualState{} + if r.base > 0 { + // A residual field of a partial object completed; the partial + // object builder stays open in its frame. + return + } + data, err := r.b.Bytes() + if err != nil { + w.err = err + return + } + w.writeResidualBytes(r.node, r.levels, data) + if w.err != nil { + return + } + w.valueDone() +} + +func (w *VariantColumnWriter) afterResidualScalar() { + if !w.checkResidual() { + return + } + if w.residual.depth == w.residual.base { + w.residualDone() + } +} + +// scalar shreds one scalar value at the current position: into typed_value +// on an exact type match, into the value column as variant binary otherwise. +func (w *VariantColumnWriter) scalar(v variant.Value) { + if w.err != nil { + return + } + node := w.cur + if node == nil { + w.fail("unexpected value event") + return + } + l := w.curLevels + if t := node.typed; t != nil && t.kind == shreddedTypedPrimitive { + if pv, ok := variantToParquetValue(v, t.typ); ok { + w.writeTyped(t.startCol, pv, l.def(t.defLevel), l.rep) + if node.valueCol >= 0 { + w.leaf(node.valueCol).writeNull(w.levels(l.def(node.defLevel), l.rep)) + } + w.valueDone() + return + } + } + b := w.builder(node) + v.Write(b) + data, err := b.Bytes() + if err != nil { + w.err = err + return + } + w.writeResidualBytes(node, l, data) + if w.err != nil { + return + } + if node.typed != nil { + w.writeNulls(node.typed.startCol, node.typed.startCol+node.typed.numCols, l.def(node.defLevel), l.rep) + } + w.valueDone() +} + +// startResidual begins streaming a container that does not match the +// shredded type into the node's residual builder, nulling the typed columns. +func (w *VariantColumnWriter) startResidual(node *shreddedVariantGroup, l shredLevels) *variant.Builder { + if node.typed != nil { + w.writeNulls(node.typed.startCol, node.typed.startCol+node.typed.numCols, l.def(node.defLevel), l.rep) + } + b := w.builder(node) + w.residual = variantResidualState{b: b, node: node, levels: l} + return b +} + +// BeginObject starts an object value at the current position. If the +// position is shredded as an object, its fields shred individually; any +// other shredded type is a conflict and the whole object streams into the +// position's value column. +func (w *VariantColumnWriter) BeginObject() { + if w.forward() { + w.residual.b.BeginObject() + w.residual.depth++ + w.checkResidual() + return + } + if w.err != nil { + return + } + node := w.cur + if node == nil { + w.fail("unexpected BeginObject event") + return + } + l := w.curLevels + if t := node.typed; t != nil && t.kind == shreddedTypedObject { + w.pushFrame(node, false, l) + w.cur = nil + return + } + b := w.startResidual(node, l) + b.BeginObject() + w.residual.depth = 1 + w.cur = nil +} + +// Field names the next value written as a field of the innermost open +// object. Values of shredded fields go to the field's columns; others +// stream into the object's partial residual. +func (w *VariantColumnWriter) Field(name string) { + if w.forward() { + w.residual.b.Field(name) + w.checkResidual() + return + } + f := w.fieldFrame(name) + if f == nil { + return + } + // VariantShredding.md requires all field names, shredded or not, to be + // present in the metadata dictionary. + w.meta.Add(name) + idx, ok := f.node.typed.index[name] + if !ok { + idx = -1 + } + w.beginField(f, name, idx) +} + +// VariantFieldRef is a pre-resolved object field name for FieldByRef: a ref +// caches its resolution (shredded position and metadata intern) against the +// last writer and object it was used with, so hot ingest loops writing the +// same fields on every row skip the per-event name hashing of Field. The +// cache re-resolves whenever the writer or object position changes, but +// FieldByRef mutates it, so a ref must not be used by multiple goroutines +// concurrently — for concurrency and peak performance use one ref per +// writer per field. +type VariantFieldRef struct { + name string + node *shreddedVariantGroup // object node the ref last resolved against + idx int // field index in node, -1 when not shredded + metaFor *VariantColumnWriter // writer whose dictionary holds the cached intern + metaGen uint64 // dictionary generation of the cached intern +} + +// NewVariantFieldRef pre-resolves an object field name for use with +// VariantColumnWriter.FieldByRef. The name is copied; the caller may reuse +// its backing memory. The ref is not bound to any writer: resolution is +// cached lazily by FieldByRef. +func NewVariantFieldRef(name string) *VariantFieldRef { + return &VariantFieldRef{name: strings.Clone(name)} +} + +// FieldByRef is Field with a pre-resolved name; see NewVariantFieldRef. +func (w *VariantColumnWriter) FieldByRef(ref *VariantFieldRef) { + if w.forward() { + w.residual.b.Field(ref.name) + w.checkResidual() + return + } + f := w.fieldFrame(ref.name) + if f == nil { + return + } + if ref.metaFor != w || ref.metaGen != w.metaGen { + w.meta.Add(ref.name) + ref.metaFor = w + ref.metaGen = w.metaGen + } + if ref.node != f.node { + ref.node = f.node + if i, ok := f.node.typed.index[ref.name]; ok { + ref.idx = i + } else { + ref.idx = -1 + } + } + w.beginField(f, ref.name, ref.idx) +} + +// fieldFrame validates that a field event is legal here and returns the +// innermost open object frame, or nil after recording the error. +func (w *VariantColumnWriter) fieldFrame(name string) *variantWriterFrame { + if w.err != nil { + return nil + } + n := len(w.frames) + if n == 0 || w.frames[n-1].isList { + w.fail("Field %q outside of an object", name) + return nil + } + if w.cur != nil { + w.fail("Field %q: previous field has no value", name) + return nil + } + return &w.frames[n-1] +} + +// beginField positions the writer at shredded field idx of the open object +// frame, or at the partial-object residual when idx is -1. +func (w *VariantColumnWriter) beginField(f *variantWriterFrame, name string, idx int) { + if idx >= 0 { + if f.seen[idx] { + w.fail("duplicate object field %q", name) + return + } + f.seen[idx] = true + w.cur = f.node.typed.fields[idx].group + w.curLevels = f.levels + return + } + // Not a shredded field: it goes into the partial-object residual. + if f.node.valueCol < 0 { + w.fail("object field %q is not in the shredded schema and the object has no value column to hold it", name) + return + } + if f.partial == nil { + f.partial = w.builder(f.node) + f.partial.BeginObject() + } + f.partial.Field(name) + w.residual = variantResidualState{b: f.partial, node: f.node, levels: f.levels, depth: 1, base: 1} +} + +// EndObject closes the innermost open object, recording shredded fields +// that received no value as missing and committing the partial residual, if +// any, to the object's value column. +func (w *VariantColumnWriter) EndObject() { + if w.forward() { + if w.residual.depth == w.residual.base { + // Only reachable in a partial-object residual, right after a + // Field: the event tries to close the enclosing shredded + // object while the field's value is still pending. Fail here + // rather than corrupting the residual's depth tracking. + w.fail("EndObject: last field has no value") + return + } + w.residual.b.EndObject() + w.residual.depth-- + if w.checkResidual() && w.residual.depth == w.residual.base { + w.residualDone() + } + return + } + if w.err != nil { + return + } + n := len(w.frames) + if n == 0 || w.frames[n-1].isList { + w.fail("EndObject without matching BeginObject") + return + } + f := &w.frames[n-1] + if w.cur != nil { + w.fail("EndObject: last field has no value") + return + } + node, l := f.node, f.levels + for i := range node.typed.fields { + if !f.seen[i] { + w.writeMissing(node.typed.fields[i].group, l) + } + } + if f.partial != nil { + f.partial.EndObject() + data, err := f.partial.Bytes() + if err != nil { + w.err = err + return + } + w.writeResidualBytes(node, l, data) + } else if node.valueCol >= 0 { + w.leaf(node.valueCol).writeNull(w.levels(l.def(node.defLevel), l.rep)) + } + w.frames = w.frames[:n-1] + w.valueDone() +} + +// BeginArray starts an array value at the current position. If the position +// is shredded as a list, every value until the matching EndArray shreds as +// one element; any other shredded type is a conflict and the whole array +// streams into the position's value column. +func (w *VariantColumnWriter) BeginArray() { + if w.forward() { + w.residual.b.BeginArray() + w.residual.depth++ + w.checkResidual() + return + } + if w.err != nil { + return + } + node := w.cur + if node == nil { + w.fail("unexpected BeginArray event") + return + } + l := w.curLevels + if t := node.typed; t != nil && t.kind == shreddedTypedList { + w.pushFrame(node, true, l) + // The first element carries the enclosing occurrence's repetition + // level; valueDone switches to the element repetition level for + // subsequent elements. + w.cur = t.element + w.curLevels = l + return + } + b := w.startResidual(node, l) + b.BeginArray() + w.residual.depth = 1 + w.cur = nil +} + +// EndArray closes the innermost open array. +func (w *VariantColumnWriter) EndArray() { + if w.forward() { + if w.residual.depth == w.residual.base { + // See the matching guard in EndObject; here the enclosing + // container is an object, so the array being closed was never + // opened. + w.fail("EndArray without matching BeginArray") + return + } + w.residual.b.EndArray() + w.residual.depth-- + if w.checkResidual() && w.residual.depth == w.residual.base { + w.residualDone() + } + return + } + if w.err != nil { + return + } + n := len(w.frames) + if n == 0 || !w.frames[n-1].isList { + w.fail("EndArray without matching BeginArray") + return + } + f := &w.frames[n-1] + node, l := f.node, f.levels + if f.elems == 0 { + // typed_value present but the list is empty: every leaf records + // the list's definition level. + t := node.typed + w.writeNulls(t.startCol, t.startCol+t.numCols, l.def(t.defLevel), l.rep) + } + if node.valueCol >= 0 { + w.leaf(node.valueCol).writeNull(w.levels(l.def(node.defLevel), l.rep)) + } + w.frames = w.frames[:n-1] + w.valueDone() +} + +func (w *VariantColumnWriter) pushFrame(node *shreddedVariantGroup, isList bool, l shredLevels) { + if len(w.frames) < cap(w.frames) { + w.frames = w.frames[:len(w.frames)+1] + } else { + w.frames = append(w.frames, variantWriterFrame{}) + } + f := &w.frames[len(w.frames)-1] + f.node = node + f.isList = isList + f.levels = l + f.partial = nil + f.elems = 0 + if !isList { + numFields := len(node.typed.fields) + if cap(f.seen) < numFields { + f.seen = make([]bool, numFields) + } else { + f.seen = f.seen[:numFields] + clear(f.seen) + } + } +} + +// scalarEvent handles one scalar event: forwarded into an active residual +// stream, or shredded at the current position. +func (w *VariantColumnWriter) scalarEvent(v variant.Value) { + if w.forward() { + v.Write(w.residual.b) + w.afterResidualScalar() + return + } + w.scalar(v) +} + +// The scalar event methods below write one scalar value at the current +// position: the row's value, the current object field, or the next array +// element. A scalar matching the position's shredded type goes to its +// typed_value column; any other scalar encodes into the value column. + +// Null writes the variant null value (distinct from a missing field and +// from a SQL null row; see WriteNullRow). Variant null never matches a +// shredded type: it encodes into the position's value column, or fails the +// row when the position is shredded without one. +func (w *VariantColumnWriter) Null() { w.scalarEvent(variant.Null()) } +func (w *VariantColumnWriter) Bool(v bool) { w.scalarEvent(variant.Bool(v)) } +func (w *VariantColumnWriter) Int8(v int8) { w.scalarEvent(variant.Int8(v)) } +func (w *VariantColumnWriter) Int16(v int16) { w.scalarEvent(variant.Int16(v)) } +func (w *VariantColumnWriter) Int32(v int32) { w.scalarEvent(variant.Int32(v)) } +func (w *VariantColumnWriter) Int64(v int64) { w.scalarEvent(variant.Int64(v)) } +func (w *VariantColumnWriter) Float(v float32) { w.scalarEvent(variant.Float(v)) } +func (w *VariantColumnWriter) Double(v float64) { w.scalarEvent(variant.Double(v)) } +func (w *VariantColumnWriter) String(v string) { w.scalarEvent(variant.String(v)) } +func (w *VariantColumnWriter) Binary(v []byte) { w.scalarEvent(variant.Binary(v)) } +func (w *VariantColumnWriter) Date(days int32) { w.scalarEvent(variant.Date(days)) } +func (w *VariantColumnWriter) Time(micros int64) { w.scalarEvent(variant.Time(micros)) } +func (w *VariantColumnWriter) UUID(v uuid.UUID) { w.scalarEvent(variant.UUID(v)) } +func (w *VariantColumnWriter) Timestamp(us int64) { w.scalarEvent(variant.Timestamp(us)) } +func (w *VariantColumnWriter) TimestampNTZ(us int64) { + w.scalarEvent(variant.TimestampNTZ(us)) +} +func (w *VariantColumnWriter) TimestampNanos(ns int64) { + w.scalarEvent(variant.TimestampNanos(ns)) +} +func (w *VariantColumnWriter) TimestampNTZNanos(ns int64) { + w.scalarEvent(variant.TimestampNTZNanos(ns)) +} +func (w *VariantColumnWriter) Decimal4(unscaled int32, scale byte) { + w.scalarEvent(variant.Decimal4(unscaled, scale)) +} +func (w *VariantColumnWriter) Decimal8(unscaled int64, scale byte) { + w.scalarEvent(variant.Decimal8(unscaled, scale)) +} +func (w *VariantColumnWriter) Decimal16(unscaled [16]byte, scale byte) { + w.scalarEvent(variant.Decimal16(unscaled, scale)) +} + +var _ variant.ValueBuilder = (*VariantColumnWriter)(nil) diff --git a/vendor/github.com/parquet-go/parquet-go/variant_shredded_read.go b/vendor/github.com/parquet-go/parquet-go/variant_shredded_read.go new file mode 100644 index 00000000000..98e32672c1c --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/variant_shredded_read.go @@ -0,0 +1,562 @@ +package parquet + +import ( + "fmt" + "slices" + + "github.com/google/uuid" + "github.com/parquet-go/parquet-go/format" + "github.com/parquet-go/parquet-go/variant" +) + +// This file implements the construct_variant reconstruction algorithm from +// the Variant Shredding specification: +// https://github.com/apache/parquet-format/blob/master/VariantShredding.md +// +// Reconstruction is not optional — VariantShredding.md: "When typed_value is +// present, readers must reconstruct shredded values according to this +// specification." +// +// A shredded variant group has the shape: +// +// optional group v (VARIANT) { +// required binary metadata; +// optional binary value; +// optional typed_value; // primitive, LIST, or object group +// } +// +// where object typed_value groups contain one required group per shredded +// field, each with its own optional value/typed_value pair, and LIST +// typed_value groups contain a repeated list of elements with the same +// value/typed_value pair. Reconstruction walks the leaf columns of the +// variant subtree and rebuilds the variant value for each row. + +// shreddedVariantGroup describes one (value, typed_value) pair in a shredded +// variant schema: the top-level variant group, an object field group, or a +// list element group. Column indices are relative to the variant group's +// first leaf column; definition levels are relative to the definition level +// at which the variant group itself is present. +type shreddedVariantGroup struct { + metadataCol int // metadata leaf column, or -1 (top-level group only) + valueCol int // value leaf column, or -1 + typed *shreddedTypedValue + startCol int + numCols int + defLevel int // relative definition level at which this group exists + repDepth int // repetition depth added within the variant subtree +} + +type shreddedTypedKind int + +const ( + shreddedTypedPrimitive shreddedTypedKind = iota + shreddedTypedList + shreddedTypedObject +) + +// shreddedTypedValue describes the typed_value part of a shredded variant +// group. +type shreddedTypedValue struct { + kind shreddedTypedKind + startCol int + numCols int + defLevel int // relative definition level at which typed_value is present + + typ Type // primitive + element *shreddedVariantGroup // list + fields []shreddedVariantField // object + index map[string]int // object: field name to position in fields +} + +type shreddedVariantField struct { + name string + group *shreddedVariantGroup +} + +// fieldByName returns the shredded field with the given name, or nil. +func (t *shreddedTypedValue) fieldByName(name string) *shreddedVariantGroup { + if i, ok := t.index[name]; ok { + return t.fields[i].group + } + return nil +} + +// buildShreddedVariantGroup builds the reconstruction tree for a variant +// group node. defLevel is the relative definition level at which the group +// exists (0 for the top-level variant group), repDepth the repetition depth +// added within the variant subtree. +func buildShreddedVariantGroup(node Node, startCol, defLevel, repDepth int) (*shreddedVariantGroup, error) { + g := &shreddedVariantGroup{ + metadataCol: -1, + valueCol: -1, + startCol: startCol, + defLevel: defLevel, + repDepth: repDepth, + } + col := startCol + for _, f := range node.Fields() { + switch f.Name() { + case "metadata": + // Every schema in VariantShredding.md declares + // "required binary metadata;" — a row cannot lack a dictionary. + if !f.Leaf() || f.Type().Kind() != ByteArray || f.Optional() || f.Repeated() { + return nil, fmt.Errorf("variant: metadata field must be a required binary leaf") + } + g.metadataCol = col + col++ + case "value": + if !f.Leaf() || f.Type().Kind() != ByteArray { + return nil, fmt.Errorf("variant: value field must be a binary leaf") + } + // VariantShredding.md: "Both value and typed_value are optional + // fields". The reconstruction's level arithmetic relies on the + // value column contributing one definition level. + if !f.Optional() { + return nil, fmt.Errorf("variant: value field of a shredded variant group must be optional") + } + g.valueCol = col + col++ + case "typed_value": + typed, err := buildShreddedTypedValue(f, col, defLevel+1, repDepth) + if err != nil { + return nil, err + } + g.typed = typed + col += typed.numCols + default: + return nil, fmt.Errorf("variant: unexpected field %q in shredded variant group", f.Name()) + } + } + g.numCols = col - startCol + if g.valueCol < 0 && g.typed == nil { + return nil, fmt.Errorf("variant: shredded variant group has neither value nor typed_value") + } + return g, nil +} + +// buildShreddedTypedValue builds the reconstruction tree for a typed_value +// field. defLevel is the relative definition level at which typed_value is +// present (its parent group's level + 1, since typed_value is optional). +func buildShreddedTypedValue(node Node, startCol, defLevel, repDepth int) (*shreddedTypedValue, error) { + if !node.Optional() { + return nil, fmt.Errorf("variant: typed_value must be optional") + } + t := &shreddedTypedValue{ + startCol: startCol, + defLevel: defLevel, + } + switch { + case node.Leaf(): + t.kind = shreddedTypedPrimitive + t.typ = node.Type() + t.numCols = 1 + if err := validateShreddedPrimitiveType(t.typ); err != nil { + return nil, err + } + + case isList(node): + t.kind = shreddedTypedList + elem := listElementOf(node) + elemDef := defLevel + 1 // the repeated list group adds one level + if elem.Optional() { + // The spec requires list elements to be required groups, but + // tolerate optional elements by accounting for the extra level. + elemDef++ + } + element, err := buildShreddedVariantGroup(elem, startCol, elemDef, repDepth+1) + if err != nil { + return nil, fmt.Errorf("variant: list element: %w", err) + } + if element.metadataCol >= 0 { + return nil, fmt.Errorf("variant: list element must not contain metadata") + } + t.element = element + t.numCols = element.numCols + + default: + t.kind = shreddedTypedObject + col := startCol + for _, f := range node.Fields() { + if f.Leaf() { + return nil, fmt.Errorf("variant: object field %q must be a group", f.Name()) + } + if f.Repeated() { + return nil, fmt.Errorf("variant: object field %q must not be repeated", f.Name()) + } + // The spec requires field groups to be required, but tolerate + // optional groups (a null group reads as a missing field). + fieldDef := defLevel + if f.Optional() { + fieldDef++ + } + group, err := buildShreddedVariantGroup(f, col, fieldDef, repDepth) + if err != nil { + return nil, fmt.Errorf("variant: object field %q: %w", f.Name(), err) + } + if group.metadataCol >= 0 { + return nil, fmt.Errorf("variant: object field %q must not contain metadata", f.Name()) + } + t.fields = append(t.fields, shreddedVariantField{name: f.Name(), group: group}) + col += group.numCols + } + if len(t.fields) == 0 { + // An empty object group has no columns to carry its own + // presence, so it cannot be reconstructed. + return nil, fmt.Errorf("variant: object typed_value group must have at least one field") + } + // Object field events resolve names against this map; a linear + // scan makes wide shredded objects quadratic per row (measurably + // dominant from a few dozen fields up). + t.index = make(map[string]int, len(t.fields)) + for i := range t.fields { + t.index[t.fields[i].name] = i + } + t.numCols = col - startCol + } + return t, nil +} + +// variantColumnReader reads values from the leaf columns of a variant +// subtree, tracking a cursor per column. The column slices contain the +// values belonging to a single occurrence of the variant group. +type variantColumnReader struct { + columns [][]Value + pos []int +} + +func (r *variantColumnReader) peek(col int) (Value, bool) { + if col >= len(r.columns) || r.pos[col] >= len(r.columns[col]) { + return Value{}, false + } + return r.columns[col][r.pos[col]], true +} + +func (r *variantColumnReader) next(col int) (Value, bool) { + v, ok := r.peek(col) + if ok { + r.pos[col]++ + } + return v, ok +} + +// read reconstructs the variant value for one occurrence of the group. It +// consumes exactly one value from every leaf column of the group's subtree +// (more beneath repeated lists). baseDef and baseRep are the definition +// level and repetition depth of the variant group in the enclosing schema. +// +// The boolean result reports whether the value is present; a false result +// means both value and typed_value were null, which the spec defines as a +// missing object field (and is invalid elsewhere; callers decide). +func (g *shreddedVariantGroup) read(r *variantColumnReader, m variant.Metadata, baseDef, baseRep int) (variant.Value, bool, error) { + var valueBytes []byte + valuePresent := false + if g.valueCol >= 0 { + v, ok := r.next(g.valueCol) + if ok && !v.IsNull() && int(v.definitionLevel) >= baseDef+g.defLevel+1 { + valuePresent = true + valueBytes = v.ByteArray() + } + } + + if g.typed == nil { + if !valuePresent { + return variant.Null(), false, nil + } + val, err := variant.Decode(m, valueBytes) + if err != nil { + return variant.Null(), false, fmt.Errorf("variant: decoding value: %w", err) + } + return val, true, nil + } + + // For primitives and arrays, value and typed_value are mutually + // exclusive. VariantShredding.md: "Unless the value is shredded as an + // object (see Objects), typed_value or value (but not both) must be + // non-null." + switch g.typed.kind { + case shreddedTypedPrimitive: + v, ok := r.next(g.typed.startCol) + typedPresent := ok && !v.IsNull() && int(v.definitionLevel) >= baseDef+g.typed.defLevel + if typedPresent { + if valuePresent { + return variant.Null(), false, fmt.Errorf("variant: value and primitive typed_value are both non-null") + } + val, err := parquetToVariantValue(v, g.typed.typ) + if err != nil { + return variant.Null(), false, err + } + return val, true, nil + } + + case shreddedTypedList: + arr, listPresent, err := g.typed.readList(r, m, baseDef, baseRep) + if err != nil { + return variant.Null(), false, err + } + if listPresent { + if valuePresent { + return variant.Null(), false, fmt.Errorf("variant: value and array typed_value are both non-null") + } + return arr, true, nil + } + + case shreddedTypedObject: + obj, objPresent, err := g.typed.readObject(r, m, baseDef, baseRep) + if err != nil { + return variant.Null(), false, err + } + if objPresent { + if !valuePresent { + return obj, true, nil + } + // Partially shredded object: the residual value must be an + // object. VariantShredding.md: "The value column of a + // partially shredded object must never contain fields + // represented by the Parquet columns in typed_value (shredded + // fields). Readers may always assume that data is written + // correctly" — so if a writer repeats a shredded name anyway, + // readers use the shredded field and ignore the residual copy + // (matching parquet-java). + residual, err := variant.Decode(m, valueBytes) + if err != nil { + return variant.Null(), false, fmt.Errorf("variant: decoding partial object value: %w", err) + } + if residual.Basic() != variant.BasicObject { + return variant.Null(), false, fmt.Errorf("variant: object typed_value with non-object value") + } + fields := slices.Clone(obj.ObjectValue().Fields) + for _, f := range residual.ObjectValue().Fields { + if g.typed.fieldByName(f.Name) != nil { + continue + } + fields = append(fields, f) + } + return variant.MakeObject(fields), true, nil + } + } + + // typed_value is null: fall back to the value column. + if !valuePresent { + return variant.Null(), false, nil + } + val, err := variant.Decode(m, valueBytes) + if err != nil { + return variant.Null(), false, fmt.Errorf("variant: decoding value: %w", err) + } + return val, true, nil +} + +// readList reconstructs a shredded array. The boolean result reports whether +// the typed_value list was present (a present empty list yields an empty +// array). +func (t *shreddedTypedValue) readList(r *variantColumnReader, m variant.Metadata, baseDef, baseRep int) (variant.Value, bool, error) { + first, ok := r.peek(t.startCol) + listPresent := ok && int(first.definitionLevel) >= baseDef+t.defLevel + // The repeated list group adds one definition level when the list has at + // least one element (independent of the element group's own levels). + hasElements := ok && int(first.definitionLevel) >= baseDef+t.defLevel+1 + + if !hasElements { + // Null or empty list: one (null) value per leaf column to consume. + for col := t.startCol; col < t.startCol+t.numCols; col++ { + r.next(col) + } + if listPresent { + return variant.MakeArray(nil), true, nil + } + return variant.Null(), false, nil + } + + elemRep := baseRep + t.element.repDepth + var elements []variant.Value + for { + elem, present, err := t.element.read(r, m, baseDef, baseRep) + if err != nil { + return variant.Null(), false, err + } + if !present { + // Elements with both value and typed_value null are invalid + // per the spec; read them as variant null (matching + // parquet-java's behavior). + elem = variant.Null() + } + elements = append(elements, elem) + + next, ok := r.peek(t.startCol) + if !ok || int(next.repetitionLevel) != elemRep { + break + } + } + return variant.MakeArray(elements), true, nil +} + +// readObject reconstructs the shredded fields of an object typed_value. The +// boolean result reports whether the typed_value group was present. Field +// groups are always consumed, even when the object is absent, because their +// leaf columns carry one (null) value per occurrence either way. +func (t *shreddedTypedValue) readObject(r *variantColumnReader, m variant.Metadata, baseDef, baseRep int) (variant.Value, bool, error) { + objPresent := false + if first, ok := r.peek(t.startCol); ok { + objPresent = int(first.definitionLevel) >= baseDef+t.defLevel + } + + fields := make([]variant.Field, 0, len(t.fields)) + for _, f := range t.fields { + val, present, err := f.group.read(r, m, baseDef, baseRep) + if err != nil { + return variant.Null(), false, fmt.Errorf("variant: object field %q: %w", f.name, err) + } + // A missing field (value and typed_value both null) is simply + // omitted from the reconstructed object. + if objPresent && present { + fields = append(fields, variant.Field{Name: f.name, Value: val}) + } + } + if !objPresent { + return variant.Null(), false, nil + } + return variant.MakeObject(fields), true, nil +} + +// validateShreddedPrimitiveType checks that a typed_value leaf type is one +// of the shredded types permitted by the Variant Shredding specification +// (e.g. unsigned integers and non-UUID fixed-length byte arrays are not). +func validateShreddedPrimitiveType(typ Type) error { + lt := typ.LogicalType() + switch value := logicalTypeValueOf(lt).(type) { + case nil: + switch typ.Kind() { + case Boolean, Int32, Int64, Float, Double, ByteArray: + return nil + } + case *format.StringType: + return nil + case *format.IntType: + if !value.IsSigned { + return fmt.Errorf("variant: unsupported shredded type %s (unsigned integer)", typ) + } + switch value.BitWidth { + case 8, 16, 32, 64: + return nil + } + case *format.DateType: + return nil + case *format.TimeType: + if _, ok := value.Unit.Value.(*format.MicroSeconds); ok { + return nil + } + case *format.TimestampType: + switch value.Unit.Value.(type) { + case *format.MicroSeconds, *format.NanoSeconds: + return nil + } + case *format.DecimalType: + switch typ.Kind() { + case Int32, Int64, FixedLenByteArray, ByteArray: + return nil + } + case *format.UUIDType: + return nil + } + return fmt.Errorf("variant: unsupported shredded type %s", typ) +} + +// parquetToVariantValue converts a parquet leaf value of a shredded +// typed_value column to the corresponding variant value, per the shredded +// types table of the Variant Shredding specification. +func parquetToVariantValue(v Value, typ Type) (variant.Value, error) { + lt := typ.LogicalType() + switch value := logicalTypeValueOf(lt).(type) { + case nil: + switch typ.Kind() { + case Boolean: + return variant.Bool(v.Boolean()), nil + case Int32: + return variant.Int32(v.Int32()), nil + case Int64: + return variant.Int64(v.Int64()), nil + case Float: + return variant.Float(v.Float()), nil + case Double: + return variant.Double(v.Double()), nil + case ByteArray: + return variant.Binary(copyBytes(v.ByteArray())), nil + } + + case *format.StringType: + return variant.String(string(v.ByteArray())), nil + + case *format.IntType: + switch value.BitWidth { + case 8: + return variant.Int8(int8(v.Int32())), nil + case 16: + return variant.Int16(int16(v.Int32())), nil + case 32: + return variant.Int32(v.Int32()), nil + case 64: + return variant.Int64(v.Int64()), nil + } + + case *format.DateType: + return variant.Date(v.Int32()), nil + + case *format.TimeType: + if _, ok := value.Unit.Value.(*format.MicroSeconds); ok { + return variant.Time(v.Int64()), nil + } + + case *format.TimestampType: + switch value.Unit.Value.(type) { + case *format.MicroSeconds: + if value.IsAdjustedToUTC { + return variant.Timestamp(v.Int64()), nil + } + return variant.TimestampNTZ(v.Int64()), nil + case *format.NanoSeconds: + if value.IsAdjustedToUTC { + return variant.TimestampNanos(v.Int64()), nil + } + return variant.TimestampNTZNanos(v.Int64()), nil + } + + case *format.DecimalType: + scale := uint8(value.Scale) + switch typ.Kind() { + case Int32: + return variant.Decimal4(v.Int32(), scale), nil + case Int64: + return variant.Decimal8(v.Int64(), scale), nil + case FixedLenByteArray, ByteArray: + b := v.ByteArray() + if len(b) > 16 { + return variant.Null(), fmt.Errorf("variant: decimal value wider than 16 bytes") + } + return variant.Decimal16(bigEndianToLittleEndian16(b), scale), nil + } + + case *format.UUIDType: + b := v.ByteArray() + if len(b) != 16 { + return variant.Null(), fmt.Errorf("variant: UUID value must be 16 bytes, got %d", len(b)) + } + return variant.UUID(uuid.UUID(b)), nil + } + return variant.Null(), fmt.Errorf("variant: unsupported shredded type %s", typ) +} + +// bigEndianToLittleEndian16 converts a big-endian two's complement integer +// of up to 16 bytes (parquet decimal representation) to the little-endian +// 16-byte representation used by variant decimal16. +func bigEndianToLittleEndian16(b []byte) [16]byte { + var out [16]byte + for i := range b { + out[i] = b[len(b)-1-i] + } + if len(b) > 0 && b[0]&0x80 != 0 { + for i := len(b); i < 16; i++ { + out[i] = 0xFF + } + } + return out +} diff --git a/vendor/github.com/parquet-go/parquet-go/variant_shredded_write.go b/vendor/github.com/parquet-go/parquet-go/variant_shredded_write.go new file mode 100644 index 00000000000..8909d8c1927 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/variant_shredded_write.go @@ -0,0 +1,367 @@ +package parquet + +import ( + "math/bits" + + "github.com/parquet-go/parquet-go/format" + "github.com/parquet-go/parquet-go/variant" +) + +// This file implements the spec-compliant shredded variant write path. It +// reuses the shreddedVariantGroup tree from variant_shredded_read.go for +// column layout and level bookkeeping, and writes values per the case tables +// of the Variant Shredding specification: +// +// - Values that exactly match the shredded type go into typed_value with a +// null value column. +// - Values that do not match are encoded as plain variant values into the +// value column (sharing the row's top-level metadata dictionary), with +// all typed_value columns null. +// - Objects shred field-wise: shredded fields go into the typed_value +// group (missing fields have both columns null), residual fields are +// encoded as an object into the value column. Shredded field names never +// appear in the value column. +// - Arrays shred element-wise through the 3-level LIST structure; variant +// null elements are encoded as variant null (0x00) in the element's +// value column. +// +// The row's metadata dictionary contains every object field name of the +// value, shredded or not, so residual values and reconstruction share one +// dictionary. VariantShredding.md: "All value columns within the Variant +// must use the same metadata. All field names of a Variant, whether shredded +// or not, must be present in the metadata." + +// addVariantFieldNames pre-registers all object field names of v in the +// metadata builder, so the row metadata covers shredded and unshredded +// fields alike. +func addVariantFieldNames(b *variant.MetadataBuilder, v variant.Value) { + switch v.Basic() { + case variant.BasicObject: + for _, f := range v.ObjectValue().Fields { + b.Add(f.Name) + addVariantFieldNames(b, f.Value) + } + case variant.BasicArray: + for _, e := range v.ArrayValue().Elements { + addVariantFieldNames(b, e) + } + } +} + +// shredLevels carries the absolute level context for one occurrence of a +// shredded variant group during writing. +type shredLevels struct { + baseDef int // definition level at which the variant group is present + baseRep int // repetition depth of the variant group + rep byte // repetition level for the first value of this occurrence +} + +func (l shredLevels) def(rel int) byte { return byte(l.baseDef + rel) } + +// appendShredded appends a leaf value with the given levels. +func appendShredded(columns [][]Value, colBase uint16, col int, v Value, def, rep byte) { + c := colBase + uint16(col) + v.definitionLevel = def + v.repetitionLevel = rep + v.columnIndex = ^c + columns[c] = append(columns[c], v) +} + +// appendShreddedNulls appends a null to every leaf column in [start, end) at +// the given levels. +func appendShreddedNulls(columns [][]Value, colBase uint16, start, end int, def, rep byte) { + for col := start; col < end; col++ { + appendShredded(columns, colBase, col, Value{}, def, rep) + } +} + +// write encodes one occurrence of the variant group. present=false writes a +// missing occurrence (both value and typed_value null), which is how absent +// object fields are represented. +func (g *shreddedVariantGroup) write(columns [][]Value, colBase uint16, b *variant.MetadataBuilder, v variant.Value, present bool, l shredLevels) { + if !present { + if g.valueCol >= 0 { + appendShredded(columns, colBase, g.valueCol, Value{}, l.def(g.defLevel), l.rep) + } + if g.typed != nil { + appendShreddedNulls(columns, colBase, g.typed.startCol, g.typed.startCol+g.typed.numCols, l.def(g.defLevel), l.rep) + } + return + } + + if g.typed == nil { + g.writeValueFallback(columns, colBase, b, v, l) + return + } + + switch g.typed.kind { + case shreddedTypedPrimitive: + if pv, ok := variantToParquetValue(v, g.typed.typ); ok { + appendShredded(columns, colBase, g.typed.startCol, pv, l.def(g.typed.defLevel), l.rep) + if g.valueCol >= 0 { + appendShredded(columns, colBase, g.valueCol, Value{}, l.def(g.defLevel), l.rep) + } + return + } + + case shreddedTypedList: + if v.Basic() == variant.BasicArray { + g.typed.writeList(columns, colBase, b, v, l) + if g.valueCol >= 0 { + appendShredded(columns, colBase, g.valueCol, Value{}, l.def(g.defLevel), l.rep) + } + return + } + + case shreddedTypedObject: + if v.Basic() == variant.BasicObject { + g.typed.writeObject(columns, colBase, b, v, g, l) + return + } + } + + // The value does not match the shredded type: write it to the value + // column and null out the typed columns. + g.writeValueFallback(columns, colBase, b, v, l) + appendShreddedNulls(columns, colBase, g.typed.startCol, g.typed.startCol+g.typed.numCols, l.def(g.defLevel), l.rep) +} + +// writeValueFallback encodes v as a plain variant value into the value +// column, sharing the row's metadata dictionary. +func (g *shreddedVariantGroup) writeValueFallback(columns [][]Value, colBase uint16, b *variant.MetadataBuilder, v variant.Value, l shredLevels) { + if g.valueCol < 0 { + panic("variant: value does not match the shredded type and the schema has no value column to fall back to") + } + encoded := variant.Encode(b, v) + pv := ByteArrayValue(encoded) + appendShredded(columns, colBase, g.valueCol, pv, l.def(g.defLevel)+1, l.rep) +} + +// writeList shreds an array value through the 3-level LIST structure. +func (t *shreddedTypedValue) writeList(columns [][]Value, colBase uint16, b *variant.MetadataBuilder, v variant.Value, l shredLevels) { + elements := v.ArrayValue().Elements + if len(elements) == 0 { + // typed_value present but the list is empty: every leaf records the + // list's definition level. + for col := t.startCol; col < t.startCol+t.numCols; col++ { + appendShredded(columns, colBase, col, Value{}, l.def(t.defLevel), l.rep) + } + return + } + elemRep := byte(l.baseRep + t.element.repDepth) + for i, elem := range elements { + el := l + if i > 0 { + el.rep = elemRep + } + // Variant null elements are written as variant null (0x00) in the + // element's value column, via the fallback path. + t.element.write(columns, colBase, b, elem, true, el) + } +} + +// writeObject shreds an object value: schema fields go into the typed_value +// group, residual fields into the value column as a variant object. +func (t *shreddedTypedValue) writeObject(columns [][]Value, colBase uint16, b *variant.MetadataBuilder, v variant.Value, g *shreddedVariantGroup, l shredLevels) { + objFields := v.ObjectValue().Fields + for _, f := range t.fields { + fv, ok := findVariantField(objFields, f.name) + f.group.write(columns, colBase, b, fv, ok, l) + } + + var residual []variant.Field + for _, f := range objFields { + if t.fieldByName(f.Name) == nil { + residual = append(residual, f) + } + } + if len(residual) > 0 { + g.writeValueFallback(columns, colBase, b, variant.MakeObject(residual), l) + } else if g.valueCol >= 0 { + appendShredded(columns, colBase, g.valueCol, Value{}, l.def(g.defLevel), l.rep) + } +} + +// findVariantField returns the value of the named field and whether it was +// found. Objects are typically small, so a linear scan beats building a map +// per row. +func findVariantField(fields []variant.Field, name string) (variant.Value, bool) { + for _, f := range fields { + if f.Name == name { + return f.Value, true + } + } + return variant.Value{}, false +} + +// isSignedIntOrNil reports whether lt is absent, or carries a signed INT +// annotation of the given bit width. A physical int column with no annotation +// is treated as a signed integer of its natural width. +func isSignedIntOrNil(lt *format.LogicalType, bitWidth int8) bool { + if lt == nil { + return true + } + it, ok := logicalTypeOf[*format.IntType](lt) + return ok && it.IsSigned && it.BitWidth == bitWidth +} + +// variantToParquetValue converts a variant value to a parquet value of the +// given shredded column type when the types match exactly (following +// parquet-java's strict matching semantics: no numeric widening or +// narrowing). The boolean result reports whether the types matched. +func variantToParquetValue(v variant.Value, typ Type) (Value, bool) { + if v.Basic() != variant.BasicPrimitive && v.Basic() != variant.BasicShortString { + return Value{}, false + } + lt := typ.LogicalType() + switch v.Type() { + case variant.PrimitiveTrue, variant.PrimitiveFalse: + if lt == nil && typ.Kind() == Boolean { + return BooleanValue(v.BoolValue()), true + } + case variant.PrimitiveInt8: + if it, ok := logicalTypeOf[*format.IntType](lt); ok && it.IsSigned && it.BitWidth == 8 { + return Int32Value(int32(v.Int())), true + } + case variant.PrimitiveInt16: + if it, ok := logicalTypeOf[*format.IntType](lt); ok && it.IsSigned && it.BitWidth == 16 { + return Int32Value(int32(v.Int())), true + } + case variant.PrimitiveInt32: + if typ.Kind() == Int32 && isSignedIntOrNil(lt, 32) { + return Int32Value(int32(v.Int())), true + } + case variant.PrimitiveInt64: + if typ.Kind() == Int64 && isSignedIntOrNil(lt, 64) { + return Int64Value(v.Int()), true + } + case variant.PrimitiveFloat: + if lt == nil && typ.Kind() == Float { + return FloatValue(float32(v.FloatValue())), true + } + case variant.PrimitiveDouble: + if lt == nil && typ.Kind() == Double { + return DoubleValue(v.FloatValue()), true + } + case variant.PrimitiveString: + if logicalTypeIs[*format.StringType](lt) { + // Viewing the immutable string data in place avoids an + // allocation per string. Callers either copy the value into + // column buffers or expose it as a read-only parquet.Value + // (the deconstruct path), matching the library's aliasing + // semantics for byte array values. + return ByteArrayValue(unsafeByteArrayFromString(v.Str())), true + } + case variant.PrimitiveBinary: + if lt == nil && typ.Kind() == ByteArray { + return ByteArrayValue(v.Bytes()), true + } + case variant.PrimitiveDate: + if logicalTypeIs[*format.DateType](lt) { + return Int32Value(int32(v.Int())), true + } + case variant.PrimitiveTime: + if tt, ok := logicalTypeOf[*format.TimeType](lt); ok && isMicros(tt.Unit) { + return Int64Value(v.Int()), true + } + case variant.PrimitiveTimestamp: + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok && isMicros(ts.Unit) && ts.IsAdjustedToUTC { + return Int64Value(v.Int()), true + } + case variant.PrimitiveTimestampNTZ: + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok && isMicros(ts.Unit) && !ts.IsAdjustedToUTC { + return Int64Value(v.Int()), true + } + case variant.PrimitiveTimestampNanos: + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok && isNanos(ts.Unit) && ts.IsAdjustedToUTC { + return Int64Value(v.Int()), true + } + case variant.PrimitiveTimestampNTZNanos: + if ts, ok := logicalTypeOf[*format.TimestampType](lt); ok && isNanos(ts.Unit) && !ts.IsAdjustedToUTC { + return Int64Value(v.Int()), true + } + case variant.PrimitiveDecimal4: + if d, ok := logicalTypeOf[*format.DecimalType](lt); ok && typ.Kind() == Int32 && d.Scale == int32(v.Scale()) && + decimal64FitsPrecision(v.Int(), d.Precision) { + return Int32Value(int32(v.Int())), true + } + case variant.PrimitiveDecimal8: + if d, ok := logicalTypeOf[*format.DecimalType](lt); ok && typ.Kind() == Int64 && d.Scale == int32(v.Scale()) && + decimal64FitsPrecision(v.Int(), d.Precision) { + return Int64Value(v.Int()), true + } + case variant.PrimitiveDecimal16: + if dec, ok := logicalTypeOf[*format.DecimalType](lt); ok && dec.Scale == int32(v.Scale()) && + (typ.Kind() == ByteArray || (typ.Kind() == FixedLenByteArray && typ.Length() == 16)) && + decimal128FitsPrecision(v.Decimal16Value(), dec.Precision) { + d := v.Decimal16Value() + be := littleEndianToBigEndian16(d) + if typ.Kind() == ByteArray { + return ByteArrayValue(be[:]), true + } + return FixedLenByteArrayValue(be[:]), true + } + case variant.PrimitiveUUID: + if logicalTypeIs[*format.UUIDType](lt) { + u := v.UUIDValue() + return FixedLenByteArrayValue(u[:]), true + } + } + return Value{}, false +} + +// littleEndianToBigEndian16 converts the little-endian 16-byte decimal +// representation used by variant to parquet's big-endian representation. +func littleEndianToBigEndian16(b [16]byte) [16]byte { + var out [16]byte + for i := range b { + out[i] = b[15-i] + } + return out +} + +// decimal64FitsPrecision reports whether an unscaled decimal value fits in +// a DECIMAL(P, S) column, i.e. has at most P decimal digits. A DECIMAL(P, S) +// column declares that bound to readers, so writing a wider value would +// corrupt it for engines that trust the declaration (DuckDB renders such a +// column as a different decimal type); the value must fall back to the +// value column instead. +func decimal64FitsPrecision(unscaled int64, precision int32) bool { + if precision >= 19 { + return true // int64 has at most 19 digits + } + bound := int64(1) + for range precision { + bound *= 10 + } + return unscaled > -bound && unscaled < bound +} + +// decimal128FitsPrecision is decimal64FitsPrecision for the little-endian +// 16-byte representation used by variant decimal16. +func decimal128FitsPrecision(le [16]byte, precision int32) bool { + if precision >= 39 { + return true // 128 bits hold at most 39 digits + } + neg := le[15]&0x80 != 0 + var hi, lo uint64 + for i := range 8 { + lo |= uint64(le[i]) << (8 * i) + hi |= uint64(le[8+i]) << (8 * i) + } + if neg { // two's complement negation to get the magnitude + lo = ^lo + 1 + hi = ^hi + if lo == 0 { + hi++ + } + } + // magnitude < 10^precision, computed in 128 bits + boundHi, boundLo := uint64(0), uint64(1) + for range precision { + var carry uint64 + carry, boundLo = bits.Mul64(boundLo, 10) + boundHi = boundHi*10 + carry + } + return hi < boundHi || (hi == boundHi && lo < boundLo) +} diff --git a/vendor/github.com/parquet-go/parquet-go/writer.go b/vendor/github.com/parquet-go/parquet-go/writer.go index 645346eb5f0..3ffcc1402fe 100644 --- a/vendor/github.com/parquet-go/parquet-go/writer.go +++ b/vendor/github.com/parquet-go/parquet-go/writer.go @@ -206,6 +206,19 @@ func makeWriteFunc[T any](t reflect.Type, writeRows writeRowsFunc) writeFunc[T] // These fields are usually lazily initialized when writing rows, // we need them to exist now tho. c.columnBuffer = c.newColumnBuffer() + // Record the original buffer so the dictionary-encoded buffer is + // restored when the row group is flushed after a fallback to PLAIN + // switched the column to a different buffer. + c.originalColumnBuffer = c.columnBuffer + w.columns[i] = c.columnBuffer + } + } else { + // The column buffers may have been replaced since the previous call: + // when a column's dictionary outgrows DictionaryMaxBytes its buffer is + // swapped for a PLAIN-encoded one (fallbackDictionaryToPlain), and + // flushing a row group restores the original buffer. Re-resolve the + // cached references so rows are not written into abandoned buffers. + for i, c := range w.base.writer.currentRowGroup.columns { w.columns[i] = c.columnBuffer } } @@ -543,10 +556,37 @@ func (w *Writer) WriteRowGroup(rowGroup RowGroup) (int64, error) { case !EqualNodes(w.schema, rowGroupSchema): return 0, ErrRowGroupSchemaMismatch } + // When the row group is the in-order concatenation of independently writable + // segments and at least one segment can be copied verbatim (e.g. a merge of + // non-overlapping row groups), write each segment as its own output row group + // so the copyable ones take the fast path. Row group sizing below + // MaxRowsPerRowGroup is an unspecified internal; data and order are preserved. + if segments, ok := w.splittableCopyableSegments(rowGroup); ok { + return w.writeSegmentsPacked(segments, rowGroup.Schema(), rowGroup.SortingColumns()) + } if err := w.writer.flush(); err != nil { return 0, err } - w.writer.currentRowGroup.configureBloomFilters(rowGroup.ColumnChunks()) + // Fast path: when the whole row group can be copied verbatim from a source + // file, splice the compressed bytes in directly instead of decoding and + // re-encoding every value (see writer_copy.go). + if srcs, ok := w.copyableColumnChunks(rowGroup); ok { + if err := w.loadCopiedChunks(srcs); err != nil { + return 0, err + } + return w.writer.writeRowGroup(w.writer.currentRowGroup, rowGroup.Schema(), rowGroup.SortingColumns()) + } + // L3 fast path: a file-backed source whose schema matches but cannot be + // copied verbatim (config differs) is re-encoded column-by-column, skipping + // the row assembly/deconstruction round-trip of the path below. + if cols, ok := w.reencodableRowGroup(rowGroup); ok { + w.writer.currentRowGroup.configureBloomFilters(rowGroup.ColumnChunks(), rowGroup.NumRows()) + if err := w.writeRowGroupByColumn(cols); err != nil { + return 0, err + } + return w.writer.writeRowGroup(w.writer.currentRowGroup, rowGroup.Schema(), rowGroup.SortingColumns()) + } + w.writer.currentRowGroup.configureBloomFilters(rowGroup.ColumnChunks(), rowGroup.NumRows()) rows := rowGroup.Rows() defer rows.Close() n, err := CopyRows(w.writer, rows) @@ -723,6 +763,17 @@ func newConcurrentRowGroupWriter(w *writer, config *WriterConfig) *ConcurrentRow } if isDictionaryEncoding(encoding) { + // The deprecated PLAIN_DICTIONARY encoding is normalized to + // RLE_DICTIONARY: the spec defines a single dictionary data + // page layout for both enum values — Encodings.md: "Data page + // format: the bit width used to encode the entry ids stored + // as 1 byte (max bit width = 32), followed by the values + // encoded using the RLE/Bit-Packing described above" — so the + // plain int32 index layout of plain.DictionaryEncoding + // produces pages no reader understands. Schemas derived from + // files written by legacy writers report PLAIN_DICTIONARY as + // the column encoding, which is how the configuration arises. + encoding = &RLEDictionary dictBuffer := columnType.NewValues(make([]byte, 0, defaultDictBufferSize), nil) dictionary = columnType.NewDictionary(columnIndex, 0, dictBuffer) columnType = dictionary.Type() @@ -754,7 +805,7 @@ func newConcurrentRowGroupWriter(w *writer, config *WriterConfig) *ConcurrentRow dictionaryMaxBytes: config.DictionaryMaxBytes, } - if lt := leaf.node.Type().LogicalType(); lt != nil && (lt.Geometry != nil || lt.Geography != nil) { + if lt := leaf.node.Type().LogicalType(); logicalTypeIs[*format.GeometryType](lt) || logicalTypeIs[*format.GeographyType](lt) { c.geospatialAccumulator = newGeospatialBBoxAccumulator() } @@ -834,11 +885,53 @@ func (rg *ConcurrentRowGroupWriter) reset() { } } -func (rg *ConcurrentRowGroupWriter) configureBloomFilters(columnChunks []ColumnChunk) { +func (rg *ConcurrentRowGroupWriter) configureBloomFilters(columnChunks []ColumnChunk, numRows int64) { for i, c := range rg.columns { - if c.columnFilter != nil { - c.resizeBloomFilter(columnChunks[i].NumValues()) + if c.columnFilter == nil { + continue } + // When the source only knows an upper bound of its value count + // (row-range views of repeated columns), leave the filter + // unallocated: flushFilterPages then builds it from the actual + // number of values written, keeping the filter exactly the size + // the configuration prescribes. + if !chunkNumValuesIsExact(columnChunks[i]) { + continue + } + values := columnChunks[i].NumValues() + if numRows > rg.maxRows { + // The input will be split across multiple output row groups, so the + // whole-input value count over-sizes each group's filter. + if c.maxRepetitionLevel > 0 { + // Repeated columns can hold more values than rows, so we can't + // apportion the value count per group ahead of time. Leave the + // filter unallocated and let each group size itself exactly at + // flush time (see flushFilterPages). + continue + } + // Non-repeated columns hold at most one value per row, so a full + // output group holds at most maxRows values. + values = min(values, rg.maxRows) + } + c.resizeBloomFilter(values) + } +} + +// chunkNumValuesIsExact reports whether chunk.NumValues() is the exact number +// of values, as opposed to an upper bound (see rangeColumnChunk). +func chunkNumValuesIsExact(chunk ColumnChunk) bool { + switch c := chunk.(type) { + case *rangeColumnChunk: + return c.exactNumValues() + case *multiColumnChunk: + for _, part := range c.chunks { + if !chunkNumValuesIsExact(part) { + return false + } + } + return true + default: + return true } } @@ -1031,10 +1124,10 @@ func newWriter(output io.Writer, config *WriterConfig) *writer { // column is of logical type decimal. logicalType := nodeType.LogicalType() if logicalType != nil { - elem.LogicalType.Set(*logicalType) - if logicalType.Decimal != nil { - elem.Scale.Set(logicalType.Decimal.Scale) - elem.Precision.Set(logicalType.Decimal.Precision) + elem.LogicalType = *logicalType + if decimal, ok := logicalType.Value.(*format.DecimalType); ok { + elem.Scale.Set(decimal.Scale) + elem.Precision.Set(decimal.Precision) } } @@ -1226,11 +1319,11 @@ func (w *writer) writeFileFooter() error { if w.encryption == nil { return nil } - switch { - case c.CryptoMetadata.EncryptionWithFooterKey != nil: + switch crypto := c.CryptoMetadata.Value.(type) { + case *format.EncryptionWithFooterKey: return w.encryption.cfg.FooterKey - case c.CryptoMetadata.EncryptionWithColumnKey != nil: - return w.encryption.columnKeyFor(columnPathString(c.CryptoMetadata.EncryptionWithColumnKey.PathInSchema)) + case *format.EncryptionWithColumnKey: + return w.encryption.columnKeyFor(columnPathString(crypto.PathInSchema)) default: return nil } @@ -1313,7 +1406,7 @@ func (w *writer) writeFileFooter() error { if w.encryption != nil { enc := w.encryption algo := format.EncryptionAlgorithm{ - AesGcmV1: &format.AesGcmV1{ + Value: &format.AesGcmV1{ AadFileUnique: enc.fileUnique, AadPrefix: enc.cfg.AadPrefix, }, @@ -1433,6 +1526,12 @@ func (w *writer) writeRowGroup(rg *ConcurrentRowGroupWriter, rowGroupSchema *Sch if err := c.Flush(); err != nil { return 0, err } + // Columns copied verbatim carry the source's bloom filter bytes (when + // configured); building a filter from the writer's (empty) buffers would + // produce a bogus one. + if c.copied != nil { + continue + } if err := c.flushFilterPages(); err != nil { return 0, err } @@ -1444,6 +1543,34 @@ func (w *writer) writeRowGroup(rg *ConcurrentRowGroupWriter, rowGroupSchema *Sch fileOffset := w.writer.offset for i, c := range rg.columns { + if c.copied != nil { + // Column copied verbatim: use the source's column index and size + // statistics, and stream the dictionary and data page bytes straight + // from the source file into the output (no intermediate buffer). + cc := c.copied + rg.columnIndex[i] = cc.columnIndex + c.columnChunk.MetaData.SizeStatistics = cc.sizeStats + + if cc.dictLength > 0 { + c.columnChunk.MetaData.DictionaryPageOffset = w.writer.offset + if _, err := w.writer.ReadFrom(io.NewSectionReader(cc.reader, cc.dictOffset, cc.dictLength)); err != nil { + return 0, fmt.Errorf("writing copied dictionary page of row group column %d: %w", i, err) + } + } + + dataPageOffset := w.writer.offset + c.columnChunk.MetaData.DataPageOffset = dataPageOffset + for j := range c.offsetIndex.PageLocations { + c.offsetIndex.PageLocations[j].Offset += dataPageOffset + } + if cc.dataLength > 0 { + if _, err := w.writer.ReadFrom(io.NewSectionReader(cc.reader, cc.dataOffset, cc.dataLength)); err != nil { + return 0, fmt.Errorf("writing copied data pages of row group column %d: %w", i, err) + } + } + continue + } + rg.columnIndex[i] = c.columnIndex.ColumnIndex() rg.columnIndex[i].RepetitionLevelHistogram = append(rg.columnIndex[i].RepetitionLevelHistogram[:0], c.pageRepetitionLevelHistograms...) rg.columnIndex[i].DefinitionLevelHistogram = append(rg.columnIndex[i].DefinitionLevelHistogram[:0], c.pageDefinitionLevelHistograms...) @@ -1483,6 +1610,41 @@ func (w *writer) writeRowGroup(rg *ConcurrentRowGroupWriter, rowGroupSchema *Sch } for i, c := range rg.columns { + // Columns copied verbatim carry the source's bloom filter as a raw byte + // range (header + bitset); stream it through unchanged. + if c.copied != nil && c.copied.bloomLength > 0 { + cc := c.copied + bloom := io.NewSectionReader(cc.reader, cc.bloomOffset, cc.bloomLength) + + if rg.config.DeferredBloomFiltersBuffers != nil { + buf := rg.config.DeferredBloomFiltersBuffers.GetBuffer() + reset := func() { rg.config.DeferredBloomFiltersBuffers.PutBuffer(buf) } + if _, err := io.Copy(buf, bloom); err != nil { + reset() + return 0, fmt.Errorf("copying bloom filter of row group column %d: %w", i, err) + } + if _, err := buf.Seek(0, io.SeekStart); err != nil { + reset() + return 0, err + } + w.deferredBloomFilterSize += cc.bloomLength + w.deferredBloomFilters = append(w.deferredBloomFilters, deferredBloomFilter{ + rowGroup: rowGroupIndex, + column: i, + buf: buf, + reset: reset, + }) + continue + } + + c.columnChunk.MetaData.BloomFilterOffset = w.writer.offset + if _, err := w.writer.ReadFrom(bloom); err != nil { + return 0, fmt.Errorf("copying bloom filter of row group column %d: %w", i, err) + } + c.columnChunk.MetaData.BloomFilterLength = int32(cc.bloomLength) + continue + } + if len(c.filter) == 0 { continue } @@ -1541,12 +1703,12 @@ func (w *writer) writeRowGroup(rg *ConcurrentRowGroupWriter, rowGroupSchema *Sch _, hasColumnKey := w.encryption.cfg.ColumnKeys[path] if !hasColumnKey { c.columnChunk.CryptoMetadata = format.ColumnCryptoMetaData{ - EncryptionWithFooterKey: &format.EncryptionWithFooterKey{}, + Value: &format.EncryptionWithFooterKey{}, } } else { c.columnChunk.CryptoMetadata = format.ColumnCryptoMetaData{ - EncryptionWithColumnKey: &format.EncryptionWithColumnKey{ - PathInSchema: c.columnPath, + Value: &format.EncryptionWithColumnKey{ + PathInSchema: thrift.Slice[string](c.columnPath), }, } } @@ -1639,7 +1801,7 @@ func (w *writer) writeRowGroup(rg *ConcurrentRowGroupWriter, rowGroupSchema *Sch } for i := range columns { c := &columns[i] - c.MetaData.EncodingStats = append(c.MetaData.EncodingStats[:0], rg.columnChunk[i].MetaData.EncodingStats...) + c.MetaData.EncodingStats = slices.Clone(rg.columnChunk[i].MetaData.EncodingStats) } for i := range offsetIndex { @@ -1839,6 +2001,10 @@ type ColumnWriter struct { hasSwitchedToPlain bool // Tracks if dictionary encoding was switched to PLAIN dictionaryMaxBytes int64 // Per-column dictionary size limit + // Set when this column is being copied verbatim from a source file for the + // current row group (see writer_copy.go). nil for the regular re-encode path. + copied *copiedChunk + // Encryption state; nil encKey means column is not encrypted. encKey []byte rowGroupOrdinal int16 @@ -1878,6 +2044,7 @@ func (c *ColumnWriter) reset() { c.pageBuffer = nil } c.numPages = 0 + c.copied = nil // Bloom filters may change in size between row groups, but we retain the // buffer to avoid reallocating large memory blocks. c.filter = c.filter[:0] diff --git a/vendor/github.com/parquet-go/parquet-go/writer_copy.go b/vendor/github.com/parquet-go/parquet-go/writer_copy.go new file mode 100644 index 00000000000..067e35c6a72 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/writer_copy.go @@ -0,0 +1,426 @@ +package parquet + +import ( + "fmt" + "io" + "slices" + "sync/atomic" + + "github.com/parquet-go/parquet-go/encoding/thrift" + "github.com/parquet-go/parquet-go/format" +) + +// copyPathCounter counts column chunks copied verbatim. It exists so tests can +// assert that the L0 fast path was taken; it is otherwise unused. +var copyPathCounter atomic.Int64 + +// disableWriteCopy forces WriteRowGroup onto the regular re-encode path. It +// exists only so benchmarks can measure the copy optimization against an +// otherwise identical baseline. +var disableWriteCopy bool + +// This file implements the "L0" copy optimization for Writer.WriteRowGroup: +// when a source row group's column chunks can be copied verbatim (compressed +// bytes moved through without decompression, decoding, re-encoding, or +// re-compression), the writer splices the source bytes directly into the output +// and copies the associated statistics and page index. +// +// The optimization is transparent: WriteRowGroup detects copyable sources and +// falls back to the regular re-encode path otherwise. It is conservative — it +// only fires when a verbatim copy is provably indistinguishable from the +// configured re-encode behavior (matching type, encoding, codec, data page +// version; no encryption; no writer-requested bloom filter; source statistics +// and page index present). See docs/merge-copy-optimization.md. +// +// Increment 1 is all-or-nothing per row group: every column chunk must be +// copyable, otherwise the whole row group falls back to the regular path. + +// copiedChunk holds the prebuilt metadata for a column chunk copied verbatim +// from a source file, plus the source byte ranges of its dictionary and data +// pages. The bytes are streamed directly from the source into the output during +// row group assembly (no intermediate buffer or per-chunk allocation). +type copiedChunk struct { + reader io.ReaderAt // source file reader + dictOffset int64 // byte offset of the dictionary page in the source + dictLength int64 // length of the dictionary page, 0 if none + dataOffset int64 // byte offset of the first data page in the source + dataLength int64 // length of all data pages + bloomOffset int64 // byte offset of the bloom filter in the source + bloomLength int64 // length of the bloom filter (header + bitset), 0 if not copied + columnIndex format.ColumnIndex + sizeStats format.SizeStatistics + statistics format.Statistics + encodingStats []format.PageEncodingStats + numValues int64 + numRows int64 + + totalUncompressedSize int64 + totalCompressedSize int64 +} + +// orderedRowGroupSegments is implemented by row groups that are the in-order +// concatenation of independently writable sub-row-groups: writing the segments +// in sequence yields the same rows, in the same order, as reading Rows(). It is +// used so the writer can route copyable segments of a merge through the verbatim +// copy fast path. A row group whose order depends on interleaving across its +// children (e.g. an overlapping heap merge) or that applies cross-segment +// deduplication must return nil to opt out. +type orderedRowGroupSegments interface { + rowGroupSegments() []RowGroup +} + +// splittableCopyableSegments returns the writable segments of rowGroup when it +// is a segmented row group and at least one segment can be written through an +// optimized segment path. The writer then emits packed output row groups so +// copyable single segments can take the L0 fast path and multi-segment batches +// can take the L3 column-oriented packing path. Splitting is gated on +// optimization eligibility so that pure re-encode merges keep their existing +// output structure. +func (w *Writer) splittableCopyableSegments(rowGroup RowGroup) ([]RowGroup, bool) { + if disableWriteCopy && disableWriteReencode { + return nil, false + } + v, ok := rowGroup.(orderedRowGroupSegments) + if !ok { + return nil, false + } + segments := v.rowGroupSegments() + if len(segments) <= 1 { + return nil, false + } + for _, seg := range segments { + if _, ok := w.copyableColumnChunks(seg); ok { + return segments, true + } + if _, ok := w.reencodableRowGroup(seg); ok { + return segments, true + } + } + return nil, false +} + +// copyableColumnChunks returns the source column chunks of rowGroup if the whole +// row group can be copied verbatim into the writer's output, along with true. +// Otherwise it returns nil and false, indicating the caller must fall back to +// the regular re-encode path. +func (w *Writer) copyableColumnChunks(rowGroup RowGroup) ([]*FileColumnChunk, bool) { + if disableWriteCopy { + return nil, false + } + // A verbatim byte copy cannot honor encryption: per-page AAD keys depend on + // the output row-group/column/page ordinals, so an encrypted output requires + // re-encoding from plaintext. + if w.writer.encryption != nil { + return nil, false + } + // A verbatim copy reproduces the source row group as a single output row + // group, so it cannot honor a smaller configured MaxRowsPerRowGroup. When the + // source exceeds the limit, demote so the row path splits it correctly. + if rowGroup.NumRows() > w.writer.currentRowGroup.maxRows { + return nil, false + } + // Row groups whose Rows() implements semantics beyond reading the column + // chunks in order cannot be handled at the chunk level. + if !chunkTransparentRowGroup(rowGroup) { + return nil, false + } + + dst := w.writer.currentRowGroup.columns + columns := rowGroup.ColumnChunks() + if len(columns) != len(dst) { + return nil, false + } + + srcs := make([]*FileColumnChunk, len(columns)) + for i, col := range columns { + fc, ok := col.(*FileColumnChunk) + if !ok { + return nil, false + } + if !columnChunkIsCopyable(dst[i], fc) { + return nil, false + } + srcs[i] = fc + } + return srcs, true +} + +// chunkTransparentMarker is implemented by row group types for which reading +// the column chunks in order is equivalent to reading Rows(). The method is +// unexported on purpose: row group implementations outside this package cannot +// opt in, so they always take the row-oriented path, which honors whatever +// semantics their Rows() implements. +type chunkTransparentMarker interface { + chunkTransparentRowGroup() +} + +// chunkTransparentRowGroup reports whether reading rowGroup's column chunks in +// order is equivalent to reading its Rows(). The fast paths in this file and in +// writer_reencode.go operate on the column chunks directly, so they must only +// be applied to row group types that explicitly opt in via +// chunkTransparentMarker. Everything else — including application-defined +// RowGroup implementations — is conservatively assumed to implement semantics +// in Rows() and handled through the row-oriented path. +// +// Known examples of wrappers whose Rows() adds semantics on top of the chunks: +// +// - dedupRowGroup drops duplicated rows in Rows(); its ColumnChunks() are +// promoted unchanged from the wrapped row group, so a chunk-level copy +// would silently retain the duplicates. +// - convertedRowGroup applies value conversion in Rows() (e.g. numeric or +// time unit conversions); its ColumnChunks() expose the unconverted source +// chunks, so a chunk-level copy would emit pre-conversion values under the +// post-conversion schema. Note that a physical type check is not sufficient +// to detect this: conversions such as timestamp millis→micros change values +// while preserving the INT64 physical type. +// +// Identity conversions never produce wrappers (ConvertRowGroup returns the row +// group unwrapped when schemas are equal), so requiring the marker does not +// cost the fast paths anything in the matched-schema case. +func chunkTransparentRowGroup(rowGroup RowGroup) bool { + _, ok := rowGroup.(chunkTransparentMarker) + return ok +} + +// loadCopiedChunks stages every source column chunk into its destination +// ColumnWriter. The per-column work here is cheap (it reads only the page index +// and records byte ranges); the data bytes are streamed straight to the output +// during row group assembly, so this is done sequentially. +func (w *Writer) loadCopiedChunks(srcs []*FileColumnChunk) error { + cols := w.writer.currentRowGroup.columns + for i, src := range srcs { + if err := cols[i].loadCopiedChunk(src); err != nil { + return err + } + } + return nil +} + +// columnChunkIsCopyable reports whether the source chunk can be copied verbatim +// into the column managed by dst, producing output indistinguishable from the +// configured re-encode behavior. +func columnChunkIsCopyable(dst *ColumnWriter, src *FileColumnChunk) bool { + // Source must be plaintext; we cannot copy ciphertext into a plaintext file. + if src.decryptionKey != nil { + return false + } + // Destination must not be encrypting (also covered by the writer-level check, + // kept here for defensiveness). + if dst.encKey != nil { + return false + } + + meta := &src.chunk.MetaData + + // Physical type must match. + if meta.Type != format.Type(dst.columnType.Kind()) { + return false + } + // Compression codec must match the configured codec. + if meta.Codec != dst.compression.CompressionCodec() { + return false + } + // A writer-requested bloom filter can only be satisfied by a verbatim copy + // when the source chunk carries a filter equivalent to the one the writer + // would build; otherwise the filter must be recomputed from decoded values. + if dst.columnFilter != nil && !bloomFilterIsCopyable(dst, src) { + return false + } + // We copy statistics and the page index from the source; require both to be + // present so the output honors the writer's statistics configuration. + if src.chunk.ColumnIndexOffset == 0 || src.chunk.OffsetIndexOffset == 0 { + return false + } + // All data pages must use the configured encoding and data page version, and + // dictionary presence must match the configured encoding. + if !encodingStatsMatch(meta.EncodingStats, dst) { + return false + } + return true +} + +// encodingStatsMatch reports whether every page recorded in the source encoding +// stats is compatible with the destination column's configured encoding and +// data page version. +func encodingStatsMatch(stats []format.PageEncodingStats, dst *ColumnWriter) bool { + if len(stats) == 0 { + return false // cannot verify the source encodings; demote + } + + wantPageType := dst.header.page.Type // DataPage (v1) or DataPageV2 + wantEncoding := dst.encoding.Encoding() + wantDict := dst.dictionary != nil + sawDict := false + + for _, s := range stats { + switch s.PageType { + case format.DictionaryPage: + sawDict = true + if !wantDict { + return false + } + case format.DataPage, format.DataPageV2: + if s.PageType != wantPageType { + return false // data page version mismatch + } + if s.Encoding != wantEncoding { + return false // encoding mismatch + } + default: + return false + } + } + + if wantDict != sawDict { + return false + } + return true +} + +// bloomFilterIsCopyable reports whether the source chunk carries a bloom filter +// equivalent to the one the destination column writer is configured to build, +// so that copying its bytes verbatim is indistinguishable from recomputing it: +// +// - the source records the filter location and length (older files omit the +// length, in which case the byte range is unknown); +// - both source and destination use the uncompressed filter representation +// (this library's default; compressed filters would require comparing +// post-compression content); +// - the source header describes the same algorithm and hash the writer would +// use (split-block, xxhash — the only ones supported); and +// - the source bitset has exactly the size the destination filter would +// allocate for this chunk's value count, i.e. the same bits-per-value. +func bloomFilterIsCopyable(dst *ColumnWriter, src *FileColumnChunk) bool { + meta := &src.chunk.MetaData + if meta.BloomFilterOffset == 0 || meta.BloomFilterLength <= 0 { + return false + } + if dst.bloomFilterCompression != nil && dst.bloomFilterCompression.CompressionCodec() != format.Uncompressed { + return false + } + + section := io.NewSectionReader(src.file.reader, meta.BloomFilterOffset, int64(meta.BloomFilterLength)) + rbuf, rbufpool := getBufioReader(section, 1024) + defer putBufioReader(rbuf, rbufpool) + + var header format.BloomFilterHeader + compact := thrift.CompactProtocol{} + if err := thrift.NewDecoder(compact.NewReader(rbuf)).Decode(&header); err != nil { + return false + } + if !isSplitBlockAlgorithm(&header) || !isXxHash(&header) { + return false + } + if _, ok := header.Compression.Value.(*format.BloomFilterUncompressed); !ok { + return false + } + return int(header.NumBytes) == dst.columnFilter.Size(meta.NumValues) +} + +// loadCopiedChunk prepares the destination ColumnWriter to emit a source column +// chunk verbatim during row group assembly. It does not read the page bytes — +// only the (much smaller) page index and statistics — and records the source +// byte ranges so the data can be streamed straight to the output later, avoiding +// a per-chunk allocation and an extra copy. +func (c *ColumnWriter) loadCopiedChunk(src *FileColumnChunk) error { + meta := &src.chunk.MetaData + + // The dictionary page (if any) and the data pages are contiguous byte ranges + // in the source file. + dataOffset := meta.DataPageOffset + dataLength := meta.TotalCompressedSize + var dictOffset, dictLength int64 + if meta.DictionaryPageOffset != 0 { + dictOffset = meta.DictionaryPageOffset + dictLength = meta.DataPageOffset - meta.DictionaryPageOffset + if dictLength < 0 || dictLength > meta.TotalCompressedSize { + return fmt.Errorf("invalid source column chunk layout: dictionary offset %d, data offset %d, total %d", + meta.DictionaryPageOffset, meta.DataPageOffset, meta.TotalCompressedSize) + } + dataLength = meta.TotalCompressedSize - dictLength + } + + // Copy the column index verbatim (type matches, so the raw min/max bytes are + // directly reusable). + ci, err := src.ColumnIndex() + if err != nil { + return fmt.Errorf("reading source column index: %w", err) + } + + // Rebuild page locations relative to the start of the data region; the writer + // re-absolutizes them once the output data page offset is known. + oi, err := src.OffsetIndex() + if err != nil { + return fmt.Errorf("reading source offset index: %w", err) + } + srcLocations := oi.(*FileOffsetIndex).index.PageLocations + locations := make([]format.PageLocation, len(srcLocations)) + for i, loc := range srcLocations { + loc.Offset -= meta.DataPageOffset + locations[i] = loc + } + + cc := &copiedChunk{ + reader: src.file.reader, + dictOffset: dictOffset, + dictLength: dictLength, + dataOffset: dataOffset, + dataLength: dataLength, + columnIndex: cloneColumnIndex(ci.(*FileColumnIndex).index), + sizeStats: cloneSizeStatistics(meta.SizeStatistics), + statistics: cloneStatistics(meta.Statistics), + encodingStats: slices.Clone(meta.EncodingStats), + numValues: meta.NumValues, + numRows: src.rowGroup.NumRows, + totalUncompressedSize: meta.TotalUncompressedSize, + totalCompressedSize: meta.TotalCompressedSize, + } + + // When the destination column is configured with a bloom filter, the copy + // predicate has already verified that the source carries an equivalent one; + // record its byte range so it is copied verbatim during assembly. + if c.columnFilter != nil { + cc.bloomOffset = meta.BloomFilterOffset + cc.bloomLength = int64(meta.BloomFilterLength) + } + + c.copied = cc + c.numRows = cc.numRows + c.numPages = len(locations) + c.offsetIndex.PageLocations = locations + copyPathCounter.Add(1) + + // Populate the column chunk metadata that the regular path would accumulate + // via recordPageStats. + c.columnChunk.MetaData.NumValues = cc.numValues + c.columnChunk.MetaData.TotalUncompressedSize = cc.totalUncompressedSize + c.columnChunk.MetaData.TotalCompressedSize = cc.totalCompressedSize + c.columnChunk.MetaData.Statistics = cc.statistics + c.columnChunk.MetaData.EncodingStats = append(c.columnChunk.MetaData.EncodingStats[:0], cc.encodingStats...) + return nil +} + +func cloneStatistics(s format.Statistics) format.Statistics { + s.Min = slices.Clone(s.Min) + s.Max = slices.Clone(s.Max) + s.MinValue = slices.Clone(s.MinValue) + s.MaxValue = slices.Clone(s.MaxValue) + return s +} + +func cloneSizeStatistics(s format.SizeStatistics) format.SizeStatistics { + s.RepetitionLevelHistogram = slices.Clone(s.RepetitionLevelHistogram) + s.DefinitionLevelHistogram = slices.Clone(s.DefinitionLevelHistogram) + return s +} + +func cloneColumnIndex(index *format.ColumnIndex) format.ColumnIndex { + out := *index + out.NullPages = slices.Clone(index.NullPages) + out.MinValues = slices.Clone(index.MinValues) + out.MaxValues = slices.Clone(index.MaxValues) + out.NullCounts = slices.Clone(index.NullCounts) + out.RepetitionLevelHistogram = slices.Clone(index.RepetitionLevelHistogram) + out.DefinitionLevelHistogram = slices.Clone(index.DefinitionLevelHistogram) + return out +} diff --git a/vendor/github.com/parquet-go/parquet-go/writer_reencode.go b/vendor/github.com/parquet-go/parquet-go/writer_reencode.go new file mode 100644 index 00000000000..5b91b0884e1 --- /dev/null +++ b/vendor/github.com/parquet-go/parquet-go/writer_reencode.go @@ -0,0 +1,233 @@ +package parquet + +import ( + "io" + "sync/atomic" +) + +// This file implements the "L3" re-encode path for Writer.WriteRowGroup: when a +// single file-backed source row group's schema matches the writer but it cannot +// be copied verbatim (the configured codec/encoding/etc. differ), re-encode it +// column-by-column instead of assembling rows and then deconstructing them. +// +// The regular fallback reads the source columns, interleaves their values into +// Row objects, then immediately tears those rows back apart into columns to +// re-encode. L3 skips that round-trip: it reads each column's values directly +// and writes them straight through the column writer (which still re-encodes, +// re-compresses, computes statistics, and populates bloom filters exactly as the +// row path would). +// +// L3 still decodes and re-encodes values, so it is far less of a win than the +// verbatim copy (L0); its benefit is avoiding the row round-trip (measured +// ~1.4–1.8x faster with notably less garbage). See +// docs/merge-copy-optimization.md. + +// reencodePathCounter counts row groups written via the L3 column-oriented +// re-encode path. Test/benchmark instrumentation only. +var reencodePathCounter atomic.Int64 + +// disableWriteReencode forces WriteRowGroup onto the row-oriented fallback. It +// exists only so benchmarks can measure L3 against an otherwise identical +// baseline. +var disableWriteReencode bool + +// columnOrientedRowGroup reports whether every column of rowGroup can be read +// column-wise while preserving row order, and the row count fits the configured +// row group size. This holds for file-backed chunks (a single row group of a +// parquet file) and for in-memory column buffers (parquet.Buffer / +// GenericBuffer, whose columns are reordered together when sorted); it excludes +// overlapping heap merges, whose row order depends on cross-column +// interleaving. The size check ensures column-wise writing does not produce a +// row group larger than the row path would. Row groups whose Rows() adds +// semantics on top of the chunks (deduplication, value conversion) are rejected +// by chunkTransparentRowGroup — reading their chunks directly would bypass +// those semantics. +func (w *Writer) columnOrientedRowGroup(rowGroup RowGroup) ([]ColumnChunk, bool) { + if !chunkTransparentRowGroup(rowGroup) { + return nil, false + } + dst := w.writer.currentRowGroup.columns + columns := rowGroup.ColumnChunks() + if len(columns) == 0 || len(columns) != len(dst) { + return nil, false + } + for _, col := range columns { + if !columnOrientedChunk(col) { + return nil, false + } + } + if rowGroup.NumRows() > w.writer.currentRowGroup.maxRows { + return nil, false + } + return columns, true +} + +// columnOrientedChunk reports whether a column chunk can be read column-wise +// while preserving row order: file-backed chunks, in-memory column buffers, +// and row-range views over either. +func columnOrientedChunk(col ColumnChunk) bool { + switch c := col.(type) { + case *FileColumnChunk: + return true + case ColumnBuffer: + return true + case *rangeColumnChunk: + return columnOrientedChunk(c.base) + default: + return false + } +} + +// reencodableRowGroup reports whether rowGroup can be written via the L3 +// column-oriented re-encode path. +func (w *Writer) reencodableRowGroup(rowGroup RowGroup) ([]ColumnChunk, bool) { + if disableWriteReencode { + return nil, false + } + return w.columnOrientedRowGroup(rowGroup) +} + +// writeSegmentsPacked writes the segments of a split merge, packing consecutive +// file-backed (non-overlapping) segments into output row groups up to the +// configured MaxRowsPerRowGroup. A single-segment batch is written through the +// normal path (preserving the verbatim L0 fast path for the 1:1 case); a +// multi-segment batch is consolidated column-by-column via L3 into one output +// row group, undershooting MaxRowsPerRowGroup as needed. Non-file-backed +// segments (overlapping heap merges) or segments larger than the limit flush the +// pending batch and are written individually through the row path. +func (w *Writer) writeSegmentsPacked(segments []RowGroup, schema *Schema, sortingColumns []SortingColumn) (int64, error) { + maxRows := w.writer.currentRowGroup.maxRows + + var ( + total int64 + pending []RowGroup + pendingRows int64 + ) + + flushPending := func() error { + var ( + n int64 + err error + ) + switch len(pending) { + case 0: + return nil + case 1: + n, err = w.WriteRowGroup(pending[0]) + default: + n, err = w.packSegmentsByColumn(pending, schema, sortingColumns) + } + total += n + pending = pending[:0] + pendingRows = 0 + return err + } + + for _, seg := range segments { + if _, ok := w.columnOrientedRowGroup(seg); ok { + if pendingRows > 0 && pendingRows+seg.NumRows() > maxRows { + if err := flushPending(); err != nil { + return total, err + } + } + pending = append(pending, seg) + pendingRows += seg.NumRows() + continue + } + if err := flushPending(); err != nil { + return total, err + } + n, err := w.WriteRowGroup(seg) + total += n + if err != nil { + return total, err + } + } + if err := flushPending(); err != nil { + return total, err + } + return total, nil +} + +// packSegmentsByColumn consolidates several file-backed segments into a single +// output row group by re-encoding each column across all segments in order. +func (w *Writer) packSegmentsByColumn(segments []RowGroup, schema *Schema, sortingColumns []SortingColumn) (int64, error) { + if err := w.writer.flush(); err != nil { + return 0, err + } + dst := w.writer.currentRowGroup.columns + w.configureBloomFiltersForSegments(segments) + for _, seg := range segments { + columns := seg.ColumnChunks() + for i := range columns { + if err := copyColumnValues(dst[i], columns[i]); err != nil { + return 0, err + } + } + } + reencodePathCounter.Add(1) + return w.writer.writeRowGroup(w.writer.currentRowGroup, schema, sortingColumns) +} + +// configureBloomFiltersForSegments sizes each column's bloom filter for the +// total number of values across all segments being packed together. Columns +// whose value count is only an upper bound (row-range views of repeated +// columns) are left unallocated so flushFilterPages sizes the filter from the +// number of values actually written. +func (w *Writer) configureBloomFiltersForSegments(segments []RowGroup) { + for i, c := range w.writer.currentRowGroup.columns { + if c.columnFilter == nil { + continue + } + total := int64(0) + exact := true + for _, seg := range segments { + chunk := seg.ColumnChunks()[i] + exact = exact && chunkNumValuesIsExact(chunk) + total += chunk.NumValues() + } + if exact { + c.resizeBloomFilter(total) + } + } +} + +// writeRowGroupByColumn re-encodes each source column chunk into its destination +// column writer, reading values column-wise instead of materializing rows. +func (w *Writer) writeRowGroupByColumn(columns []ColumnChunk) error { + dst := w.writer.currentRowGroup.columns + for i, col := range columns { + if err := copyColumnValues(dst[i], col); err != nil { + return err + } + } + reencodePathCounter.Add(1) + return nil +} + +// reencodeValueBufferSize is the batch size for column-wise value copies. Larger +// than the default value buffer to amortize per-call overhead. +const reencodeValueBufferSize = 1024 + +// copyColumnValues reads every value of src in order and writes it to dst, +// without materializing rows. +func copyColumnValues(dst *ColumnWriter, src ColumnChunk) error { + reader := NewColumnChunkValueReader(src) + defer reader.Close() + + buf := make([]Value, reencodeValueBufferSize) + for { + n, err := reader.ReadValues(buf) + if n > 0 { + if _, werr := dst.WriteRowValues(buf[:n]); werr != nil { + return werr + } + } + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } +} diff --git a/vendor/github.com/prometheus/client_golang/api/client.go b/vendor/github.com/prometheus/client_golang/api/client.go index 0e647b6756f..66844900d0c 100644 --- a/vendor/github.com/prometheus/client_golang/api/client.go +++ b/vendor/github.com/prometheus/client_golang/api/client.go @@ -27,13 +27,18 @@ import ( ) // DefaultRoundTripper is used if no RoundTripper is set in Config. +// refer https://github.com/golang/go/blob/master/src/net/http/transport.go#L46 var DefaultRoundTripper http.RoundTripper = &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, - TLSHandshakeTimeout: 10 * time.Second, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, } // Config defines configuration parameters for a new client. @@ -136,21 +141,21 @@ func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, } var body []byte - done := make(chan error, 1) + done := make(chan struct{}) + var readErr error go func() { + defer close(done) var buf bytes.Buffer - _, err := buf.ReadFrom(resp.Body) + _, readErr = buf.ReadFrom(resp.Body) body = buf.Bytes() - done <- err }() select { case <-ctx.Done(): resp.Body.Close() - <-done return resp, nil, ctx.Err() - case err = <-done: + case <-done: resp.Body.Close() - return resp, body, err + return resp, body, readErr } } diff --git a/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go b/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go index 8a72f9bfc7b..61094cb1ae2 100644 --- a/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go +++ b/vendor/github.com/prometheus/client_golang/api/prometheus/v1/api.go @@ -380,7 +380,9 @@ const ( epBuildinfo = apiPrefix + "/status/buildinfo" epRuntimeinfo = apiPrefix + "/status/runtimeinfo" epTSDB = apiPrefix + "/status/tsdb" + epTSDBBlocks = apiPrefix + "/status/tsdb/blocks" epWalReplay = apiPrefix + "/status/walreplay" + epFormatQuery = apiPrefix + "/format_query" ) // AlertState models the state of an alert. @@ -475,7 +477,7 @@ type API interface { // Flags returns the flag values that Prometheus was launched with. Flags(ctx context.Context) (FlagsResult, error) // LabelNames returns the unique label names present in the block in sorted order by given time range and matchers. - LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error) + LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelNames, Warnings, error) // LabelValues performs a query for the values of the given label, time range and matchers. LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error) // Query performs a query for the given time. @@ -494,7 +496,7 @@ type API interface { // under the TSDB's data directory and returns the directory as response. Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) // Rules returns a list of alerting and recording rules that are currently loaded. - Rules(ctx context.Context) (RulesResult, error) + Rules(ctx context.Context, matches []string) (RulesResult, error) // Targets returns an overview of the current state of the Prometheus target discovery. Targets(ctx context.Context) (TargetsResult, error) // TargetsMetadata returns metadata about metrics currently scraped by the target. @@ -503,8 +505,12 @@ type API interface { Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error) // TSDB returns the cardinality statistics. TSDB(ctx context.Context, opts ...Option) (TSDBResult, error) + // TSDBBlocks returns the list of currently loaded TSDB blocks and their metadata. + TSDBBlocks(ctx context.Context) (TSDBBlocksResult, error) // WalReplay returns the current replay status of the wal. WalReplay(ctx context.Context) (WalReplayStatus, error) + // FormatQuery formats a PromQL expression in a prettified way. + FormatQuery(ctx context.Context, query string) (string, error) } // AlertsResult contains the result from querying the alerts endpoint. @@ -586,7 +592,7 @@ type RuleGroup struct { // default: // fmt.Printf("unknown rule type %s", v) // } -type Rules []interface{} +type Rules []any // AlertingRule models a alerting rule. type AlertingRule struct { @@ -666,7 +672,7 @@ type Metadata struct { // queryResult contains result data for a query. type queryResult struct { Type model.ValueType `json:"resultType"` - Result interface{} `json:"result"` + Result any `json:"result"` // The decoded value. v model.Value @@ -690,6 +696,40 @@ type TSDBHeadStats struct { MaxTime int `json:"maxTime"` } +// TSDBBlocksResult contains the results from querying the tsdb blocks endpoint. +type TSDBBlocksResult struct { + Status string `json:"status"` + Data TSDBBlocksData `json:"data"` +} + +// TSDBBlocksData contains the metadata for the tsdb blocks. +type TSDBBlocksData struct { + Blocks []TSDBBlocksBlockMetadata `json:"blocks"` +} + +// TSDBBlocksBlockMetadata contains the metadata for a single tsdb block. +type TSDBBlocksBlockMetadata struct { + Ulid string `json:"ulid"` + MinTime int64 `json:"minTime"` + MaxTime int64 `json:"maxTime"` + Stats TSDBBlocksStats `json:"stats"` + Compaction TSDBBlocksCompaction `json:"compaction"` + Version int `json:"version"` +} + +// TSDBBlocksStats contains block stats for a single tsdb block. +type TSDBBlocksStats struct { + NumSamples int `json:"numSamples"` + NumSeries int `json:"numSeries"` + NumChunks int `json:"numChunks"` +} + +// TSDBBlocksCompaction contains block compaction details for a single block. +type TSDBBlocksCompaction struct { + Level int `json:"level"` + Sources []string `json:"sources"` +} + // WalReplayStatus represents the wal replay status. type WalReplayStatus struct { Min int `json:"min"` @@ -1024,7 +1064,7 @@ func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) { return res, err } -func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error) { +func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelNames, Warnings, error) { u := h.client.URL(epLabels, nil) q := addOptionalURLParams(u.Query(), opts) @@ -1042,7 +1082,7 @@ func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, e if err != nil { return nil, w, err } - var labelNames []string + var labelNames model.LabelNames err = json.Unmarshal(body, &labelNames) return labelNames, w, err } @@ -1235,8 +1275,15 @@ func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, return res, err } -func (h *httpAPI) Rules(ctx context.Context) (RulesResult, error) { +func (h *httpAPI) Rules(ctx context.Context, matches []string) (RulesResult, error) { u := h.client.URL(epRules, nil) + q := u.Query() + + for _, m := range matches { + q.Add("match[]", m) + } + + u.RawQuery = q.Encode() req, err := http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { @@ -1340,6 +1387,24 @@ func (h *httpAPI) TSDB(ctx context.Context, opts ...Option) (TSDBResult, error) return res, err } +func (h *httpAPI) TSDBBlocks(ctx context.Context) (TSDBBlocksResult, error) { + u := h.client.URL(epTSDBBlocks, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return TSDBBlocksResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return TSDBBlocksResult{}, err + } + + var res TSDBBlocksResult + err = json.Unmarshal(body, &res) + return res, err +} + func (h *httpAPI) WalReplay(ctx context.Context) (WalReplayStatus, error) { u := h.client.URL(epWalReplay, nil) @@ -1380,6 +1445,19 @@ func (h *httpAPI) QueryExemplars(ctx context.Context, query string, startTime, e return res, err } +func (h *httpAPI) FormatQuery(ctx context.Context, query string) (string, error) { + u := h.client.URL(epFormatQuery, nil) + q := u.Query() + q.Set("query", query) + + _, body, _, err := h.client.DoGetFallback(ctx, u, q) + if err != nil { + return "", err + } + + return string(body), nil +} + // Warnings is an array of non critical errors type Warnings []string @@ -1467,8 +1545,8 @@ func (h *apiClientImpl) Do(ctx context.Context, req *http.Request) (*http.Respon return resp, []byte(result.Data), result.Warnings, err } -// DoGetFallback will attempt to do the request as-is, and on a 405 or 501 it -// will fallback to a GET request. +// DoGetFallback will attempt to do the request as-is, and on a 403, 405, or +// 501 it will fallback to a GET request. func (h *apiClientImpl) DoGetFallback(ctx context.Context, u *url.URL, args url.Values) (*http.Response, []byte, Warnings, error) { encodedArgs := args.Encode() req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(encodedArgs)) @@ -1486,7 +1564,7 @@ func (h *apiClientImpl) DoGetFallback(ctx context.Context, u *url.URL, args url. req.Header["Idempotency-Key"] = nil resp, body, warnings, err := h.Do(ctx, req) - if resp != nil && (resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented) { + if resp != nil && (resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented) { u.RawQuery = encodedArgs req, err = http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { diff --git a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go b/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go index 8547c8dfd18..820bf436aba 100644 --- a/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go +++ b/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go @@ -90,7 +90,7 @@ loop: s = skipSpace(s[1:]) } } - return + return specs } func skipSpace(s string) (rest string) { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_go116.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_go116.go deleted file mode 100644 index effc57840ae..00000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_go116.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !go1.17 -// +build !go1.17 - -package collectors - -import "github.com/prometheus/client_golang/prometheus" - -// NewGoCollector returns a collector that exports metrics about the current Go -// process. This includes memory stats. To collect those, runtime.ReadMemStats -// is called. This requires to “stop the world”, which usually only happens for -// garbage collection (GC). Take the following implications into account when -// deciding whether to use the Go collector: -// -// 1. The performance impact of stopping the world is the more relevant the more -// frequently metrics are collected. However, with Go1.9 or later the -// stop-the-world time per metrics collection is very short (~25µs) so that the -// performance impact will only matter in rare cases. However, with older Go -// versions, the stop-the-world duration depends on the heap size and can be -// quite significant (~1.7 ms/GiB as per -// https://go-review.googlesource.com/c/go/+/34937). -// -// 2. During an ongoing GC, nothing else can stop the world. Therefore, if the -// metrics collection happens to coincide with GC, it will only complete after -// GC has finished. Usually, GC is fast enough to not cause problems. However, -// with a very large heap, GC might take multiple seconds, which is enough to -// cause scrape timeouts in common setups. To avoid this problem, the Go -// collector will use the memstats from a previous collection if -// runtime.ReadMemStats takes more than 1s. However, if there are no previously -// collected memstats, or their collection is more than 5m ago, the collection -// will block until runtime.ReadMemStats succeeds. -// -// NOTE: The problem is solved in Go 1.15, see -// https://github.com/golang/go/issues/19812 for the related Go issue. -func NewGoCollector() prometheus.Collector { - return prometheus.NewGoCollector() -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go index cc4ef1077e8..d29ade654fd 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go @@ -90,13 +90,13 @@ func WithGoCollectorMemStatsMetricsDisabled() func(options *internal.GoCollector // GoRuntimeMetricsRule allow enabling and configuring particular group of runtime/metrics. // TODO(bwplotka): Consider adding ability to adjust buckets. type GoRuntimeMetricsRule struct { - // Matcher represents RE2 expression will match the runtime/metrics from https://golang.bg/src/runtime/metrics/description.go + // Matcher represents RE2 expression will match the runtime/metrics from https://pkg.go.dev/runtime/metrics // Use `regexp.MustCompile` or `regexp.Compile` to create this field. Matcher *regexp.Regexp } // WithGoCollectorRuntimeMetrics allows enabling and configuring particular group of runtime/metrics. -// See the list of metrics https://golang.bg/src/runtime/metrics/description.go (pick the Go version you use there!). +// See the list of metrics https://pkg.go.dev/runtime/metrics (pick the Go version you use there!). // You can use this option in repeated manner, which will add new rules. The order of rules is important, the last rule // that matches particular metrics is applied. func WithGoCollectorRuntimeMetrics(rules ...GoRuntimeMetricsRule) func(options *internal.GoCollectorOptions) { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collectors/version/version.go b/vendor/github.com/prometheus/client_golang/prometheus/collectors/version/version.go index c96e187126f..0306b5878c3 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collectors/version/version.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collectors/version/version.go @@ -15,15 +15,44 @@ package version import ( "fmt" + "maps" "github.com/prometheus/common/version" "github.com/prometheus/client_golang/prometheus" ) +type Option func(*options) + +type options struct { + extraConstLabels prometheus.Labels +} + +func WithExtraConstLabels(l prometheus.Labels) Option { + return func(o *options) { + o.extraConstLabels = l + } +} + // NewCollector returns a collector that exports metrics about current version // information. -func NewCollector(program string) prometheus.Collector { +func NewCollector(program string, opts ...Option) prometheus.Collector { + o := options{} + for _, opt := range opts { + opt(&o) + } + + constLabels := prometheus.Labels{ + "version": version.Version, + "revision": version.GetRevision(), + "branch": version.Branch, + "goversion": version.GoVersion, + "goos": version.GoOS, + "goarch": version.GoArch, + "tags": version.GetTags(), + } + maps.Copy(constLabels, o.extraConstLabels) + return prometheus.NewGaugeFunc( prometheus.GaugeOpts{ Namespace: program, @@ -32,15 +61,7 @@ func NewCollector(program string) prometheus.Collector { "A metric with a constant '1' value labeled by version, revision, branch, goversion from which %s was built, and the goos and goarch for the build.", program, ), - ConstLabels: prometheus.Labels{ - "version": version.Version, - "revision": version.GetRevision(), - "branch": version.Branch, - "goversion": version.GoVersion, - "goos": version.GoOS, - "goarch": version.GoArch, - "tags": version.GetTags(), - }, + ConstLabels: constLabels, }, func() float64 { return 1 }, ) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go index 4ce84e7a80e..7d963d3afb8 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/counter.go @@ -85,11 +85,12 @@ type CounterVecOpts struct { // Both internal tracking values are added up in the Write method. This has to // be taken into account when it comes to precision and overflow behavior. func NewCounter(opts CounterOpts) Counter { - desc := NewDesc( + desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - nil, + UnconstrainedLabels(nil), opts.ConstLabels, + WithUnit(opts.Unit), ) if opts.now == nil { opts.now = time.Now @@ -205,6 +206,7 @@ func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec { opts.Help, opts.VariableLabels, opts.ConstLabels, + WithUnit(opts.Unit), ) if opts.now == nil { opts.now = time.Now @@ -349,10 +351,11 @@ type CounterFunc interface { // // Check out the ExampleGaugeFunc examples for the similar GaugeFunc. func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc { - return newValueFunc(NewDesc( + return newValueFunc(V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - nil, + UnconstrainedLabels(nil), opts.ConstLabels, + WithUnit(opts.Unit), ), CounterValue, function) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go index 2331b8b4f3b..a3c92e7a4c1 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/desc.go @@ -47,6 +47,8 @@ type Desc struct { fqName string // help provides some helpful information about this metric. help string + // unit provides the unit of this metric. + unit string // constLabelPairs contains precalculated DTO label pairs based on // the constant labels. constLabelPairs []*dto.LabelPair @@ -66,6 +68,16 @@ type Desc struct { err error } +// DescOpt allows setting optional fields for NewDesc. +type DescOpt func(*Desc) + +// WithUnit sets the unit for a Desc. +func WithUnit(unit string) DescOpt { + return func(d *Desc) { + d.unit = unit + } +} + // NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc // and will be reported on registration time. variableLabels and constLabels can // be nil if no such labels should be set. fqName must not be empty. @@ -89,14 +101,17 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * // // For constLabels, the label values are constant. Therefore, they are fully // specified in the Desc. See the Collector example for a usage pattern. -func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc { +func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels, opts ...DescOpt) *Desc { d := &Desc{ fqName: fqName, help: help, variableLabels: variableLabels.compile(), } - //nolint:staticcheck // TODO: Don't use deprecated model.NameValidationScheme. - if !model.NameValidationScheme.IsValidMetricName(fqName) { + + for _, opt := range opts { + opt(d) + } + if !model.UTF8Validation.IsValidMetricName(fqName) { d.err = fmt.Errorf("%q is not a valid metric name", fqName) return d } @@ -150,11 +165,13 @@ func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, const d.id = xxh.Sum64() // Sort labelNames so that order doesn't matter for the hash. sort.Strings(labelNames) - // Now hash together (in this order) the help string and the sorted + // Now hash together (in this order) the help string, the unit string and the sorted // label names. xxh.Reset() xxh.WriteString(help) xxh.Write(separatorByteSlice) + xxh.WriteString(d.unit) + xxh.Write(separatorByteSlice) for _, labelName := range labelNames { xxh.WriteString(labelName) xxh.Write(separatorByteSlice) @@ -182,6 +199,15 @@ func NewInvalidDesc(err error) *Desc { } } +// Err returns an error that occurred during construction, if any. +// +// Calling this method is optional. It can be used to detect construction +// errors early, before invoking other methods on the Desc. If an error is +// present, later operations may not behave as expected. +func (d *Desc) Err() error { + return d.err +} + func (d *Desc) String() string { lpStrings := make([]string, 0, len(d.constLabelPairs)) for _, lp := range d.constLabelPairs { @@ -202,9 +228,10 @@ func (d *Desc) String() string { } } return fmt.Sprintf( - "Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}", + "Desc{fqName: %q, help: %q, unit: %q, constLabels: {%s}, variableLabels: {%s}}", d.fqName, d.help, + d.unit, strings.Join(lpStrings, ","), strings.Join(vlStrings, ","), ) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go index de5a8562931..327746f4337 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go @@ -47,14 +47,14 @@ func (e *expvarCollector) Collect(ch chan<- Metric) { if expVar == nil { continue } - var v interface{} + var v any labels := make([]string, len(desc.variableLabels.names)) if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil { ch <- NewInvalidMetric(desc, err) continue } - var processValue func(v interface{}, i int) - processValue = func(v interface{}, i int) { + var processValue func(v any, i int) + processValue = func(v any, i int) { if i >= len(labels) { copiedLabels := append(make([]string, 0, len(labels)), labels...) switch v := v.(type) { @@ -72,7 +72,7 @@ func (e *expvarCollector) Collect(ch chan<- Metric) { ch <- m return } - vm, ok := v.(map[string]interface{}) + vm, ok := v.(map[string]any) if !ok { return } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go index dd2eac94067..41e54bf270a 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go @@ -76,11 +76,12 @@ type GaugeVecOpts struct { // scenarios for Gauges and Counters, where the former tends to be Set-heavy and // the latter Inc-heavy. func NewGauge(opts GaugeOpts) Gauge { - desc := NewDesc( + desc := V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - nil, + UnconstrainedLabels(nil), opts.ConstLabels, + WithUnit(opts.Unit), ) result := &gauge{desc: desc, labelPairs: desc.constLabelPairs} result.init(result) // Init self-collection. @@ -163,6 +164,7 @@ func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec { opts.Help, opts.VariableLabels, opts.ConstLabels, + WithUnit(opts.Unit), ) return &GaugeVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { @@ -302,10 +304,11 @@ type GaugeFunc interface { // value of 1. Example: // https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56 func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc { - return newValueFunc(NewDesc( + return newValueFunc(V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - nil, + UnconstrainedLabels(nil), opts.ConstLabels, + WithUnit(opts.Unit), ), GaugeValue, function) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go deleted file mode 100644 index 897a6e906b3..00000000000 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2021 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !go1.17 -// +build !go1.17 - -package prometheus - -import ( - "runtime" - "sync" - "time" -) - -type goCollector struct { - base baseGoCollector - - // ms... are memstats related. - msLast *runtime.MemStats // Previously collected memstats. - msLastTimestamp time.Time - msMtx sync.Mutex // Protects msLast and msLastTimestamp. - msMetrics memStatsMetrics - msRead func(*runtime.MemStats) // For mocking in tests. - msMaxWait time.Duration // Wait time for fresh memstats. - msMaxAge time.Duration // Maximum allowed age of old memstats. -} - -// NewGoCollector is the obsolete version of collectors.NewGoCollector. -// See there for documentation. -// -// Deprecated: Use collectors.NewGoCollector instead. -func NewGoCollector() Collector { - msMetrics := goRuntimeMemStats() - msMetrics = append(msMetrics, struct { - desc *Desc - eval func(*runtime.MemStats) float64 - valType ValueType - }{ - // This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 - desc: NewDesc( - memstatNamespace("gc_cpu_fraction"), - "The fraction of this program's available CPU time used by the GC since the program started.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, - valType: GaugeValue, - }) - return &goCollector{ - base: newBaseGoCollector(), - msLast: &runtime.MemStats{}, - msRead: runtime.ReadMemStats, - msMaxWait: time.Second, - msMaxAge: 5 * time.Minute, - msMetrics: msMetrics, - } -} - -// Describe returns all descriptions of the collector. -func (c *goCollector) Describe(ch chan<- *Desc) { - c.base.Describe(ch) - for _, i := range c.msMetrics { - ch <- i.desc - } -} - -// Collect returns the current state of all metrics of the collector. -func (c *goCollector) Collect(ch chan<- Metric) { - var ( - ms = &runtime.MemStats{} - done = make(chan struct{}) - ) - // Start reading memstats first as it might take a while. - go func() { - c.msRead(ms) - c.msMtx.Lock() - c.msLast = ms - c.msLastTimestamp = time.Now() - c.msMtx.Unlock() - close(done) - }() - - // Collect base non-memory metrics. - c.base.Collect(ch) - - timer := time.NewTimer(c.msMaxWait) - select { - case <-done: // Our own ReadMemStats succeeded in time. Use it. - timer.Stop() // Important for high collection frequencies to not pile up timers. - c.msCollect(ch, ms) - return - case <-timer.C: // Time out, use last memstats if possible. Continue below. - } - c.msMtx.Lock() - if time.Since(c.msLastTimestamp) < c.msMaxAge { - // Last memstats are recent enough. Collect from them under the lock. - c.msCollect(ch, c.msLast) - c.msMtx.Unlock() - return - } - // If we are here, the last memstats are too old or don't exist. We have - // to wait until our own ReadMemStats finally completes. For that to - // happen, we have to release the lock. - c.msMtx.Unlock() - <-done - c.msCollect(ch, ms) -} - -func (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) { - for _, i := range c.msMetrics { - ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms)) - } -} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go index 6b8684731c9..1db1c4be09a 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go @@ -98,7 +98,7 @@ type goCollector struct { // snapshot is always produced by Collect. mu sync.Mutex - // Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed). + // Contains all samples that have to be retrieved from runtime/metrics (not all of them will be exposed). sampleBuf []metrics.Sample // sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums. sampleMap map[string]*metrics.Sample @@ -210,16 +210,26 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] + // Extract unit from the runtime/metrics name (e.g., "/gc/heap/allocs:bytes" -> "bytes") + // and sanitize to match Prometheus naming conventions (e.g., "cpu-seconds" -> "cpu_seconds") + var unit string + if idx := strings.IndexRune(d.Name, ':'); idx >= 0 { + unit = d.Name[idx+1:] + unit = strings.ReplaceAll(unit, "-", "_") + unit = strings.ReplaceAll(unit, "*", "_") + unit = strings.ReplaceAll(unit, "/", "_per_") + } + var m collectorMetric if d.Kind == metrics.KindFloat64Histogram { _, hasSum := opt.RuntimeMetricSumForHist[d.Name] - unit := d.Name[strings.IndexRune(d.Name, ':')+1:] m = newBatchHistogram( - NewDesc( + V2.NewDesc( BuildFQName(namespace, subsystem, name), help, + UnconstrainedLabels(nil), nil, - nil, + WithUnit(unit), ), internal.RuntimeMetricsBucketsForUnit(bucketsMap[d.Name], unit), hasSum, @@ -230,6 +240,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { Subsystem: subsystem, Name: name, Help: help, + Unit: unit, }, ) } else { @@ -238,6 +249,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { Subsystem: subsystem, Name: name, Help: help, + Unit: unit, }) } metricSet = append(metricSet, m) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go index c453b754a7f..88bae3b32c2 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go @@ -378,6 +378,9 @@ type HistogramOpts struct { // string. Help string + // Unit provides the unit of this Histogram. + Unit string + // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. @@ -522,11 +525,12 @@ type HistogramVecOpts struct { // for each bucket. func NewHistogram(opts HistogramOpts) Histogram { return newHistogram( - NewDesc( + V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - nil, + UnconstrainedLabels(nil), opts.ConstLabels, + WithUnit(opts.Unit), ), opts, ) @@ -966,7 +970,7 @@ func (h *histogram) maybeReset( // We are using the possibly mocked h.now() rather than // time.Since(h.lastResetTime) to enable testing. if h.nativeHistogramMinResetDuration == 0 || // No reset configured. - h.resetScheduled || // Do not interefere if a reset is already scheduled. + h.resetScheduled || // Do not interfere if a reset is already scheduled. h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration { return false } @@ -1053,8 +1057,8 @@ func (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool { atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold)) // ...and then merge the newly deleted buckets into the wider zero // bucket. - mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool { - return func(k, v interface{}) bool { + mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v any) bool { + return func(k, v any) bool { key := k.(int) bucket := v.(*int64) if key == smallestKey { @@ -1107,8 +1111,8 @@ func (h *histogram) doubleBucketWidth(hot, cold *histogramCounts) { // ...adjust the schema in the cold counts, too... atomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema) // ...and then merge the cold buckets into the wider hot buckets. - merge := func(hotBuckets *sync.Map) func(k, v interface{}) bool { - return func(k, v interface{}) bool { + merge := func(hotBuckets *sync.Map) func(k, v any) bool { + return func(k, v any) bool { key := k.(int) bucket := v.(*int64) // Adjust key to match the bucket to merge into. @@ -1190,6 +1194,7 @@ func (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec { opts.Help, opts.VariableLabels, opts.ConstLabels, + WithUnit(opts.Unit), ) return &HistogramVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { @@ -1476,7 +1481,7 @@ func pickSchema(bucketFactor float64) int32 { func makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) { var ii []int - buckets.Range(func(k, v interface{}) bool { + buckets.Range(func(k, v any) bool { ii = append(ii, k.(int)) return true }) @@ -1553,8 +1558,8 @@ func addToBucket(buckets *sync.Map, key int, increment int64) bool { // according to the buckets ranged through. It then resets all buckets ranged // through to 0 (but leaves them in place so that they don't need to get // recreated on the next scrape). -func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface{}) bool { - return func(k, v interface{}) bool { +func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v any) bool { + return func(k, v any) bool { bucket := v.(*int64) if addToBucket(hotBuckets, k.(int), atomic.LoadInt64(bucket)) { atomic.AddUint32(bucketNumber, 1) @@ -1565,7 +1570,7 @@ func addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface } func deleteSyncMap(m *sync.Map) { - m.Range(func(k, v interface{}) bool { + m.Range(func(k, v any) bool { m.Delete(k) return true }) @@ -1573,7 +1578,7 @@ func deleteSyncMap(m *sync.Map) { func findSmallestKey(m *sync.Map) int { result := math.MaxInt32 - m.Range(func(k, v interface{}) bool { + m.Range(func(k, v any) bool { key := k.(int) if key < result { result = key diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go index 7bac0da33df..2db270f2166 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go @@ -78,7 +78,7 @@ type OpCode struct { // notion, pairing up elements that appear uniquely in each sequence. // That, and the method here, appear to yield more intuitive difference // reports than does diff. This method appears to be the least vulnerable -// to synching up on blocks of "junk lines", though (like blank lines in +// to syncing up on blocks of "junk lines", though (like blank lines in // ordinary text files, or maybe "

" lines in HTML files). That may be // because this is the only method of the 3 that has a *concept* of // "junk" . @@ -567,7 +567,7 @@ type UnifiedDiff struct { func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { buf := bufio.NewWriter(writer) defer buf.Flush() - wf := func(format string, args ...interface{}) error { + wf := func(format string, args ...any) error { _, err := fmt.Fprintf(buf, format, args...) return err } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go index 5fe8d3b4d29..a0285489a08 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/labels.go @@ -184,6 +184,5 @@ func validateLabelValues(vals []string, expectedNumberOfValues int) error { } func checkLabelName(l string) bool { - //nolint:staticcheck // TODO: Don't use deprecated model.NameValidationScheme. - return model.NameValidationScheme.IsValidLabelName(l) && !strings.HasPrefix(l, reservedLabelPrefix) + return model.UTF8Validation.IsValidLabelName(l) && !strings.HasPrefix(l, reservedLabelPrefix) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go index 76e59f12880..c5cb90adf8f 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go @@ -81,6 +81,9 @@ type Opts struct { // string. Help string + // Unit provides the unit of this metric as per https://prometheus.io/docs/specs/om + Unit string + // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go index b32c95fa3fa..2b16298f406 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go @@ -72,7 +72,13 @@ func getOpenFileCount() (float64, error) { } func (c *processCollector) processCollect(ch chan<- Metric) { - if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", os.Getpid()); err == nil { + pid, err := c.pidFn() + if err != nil { + c.reportError(ch, nil, err) + return + } + + if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", pid); err == nil { if len(procs) == 1 { startTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9) ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime) @@ -84,6 +90,11 @@ func (c *processCollector) processCollect(ch chan<- Metric) { c.reportError(ch, c.startTime, err) } + if pid != os.Getpid() { + c.reportError(ch, nil, fmt.Errorf("collecting metrics for pid %d is not supported on darwin: process metrics collection is limited to the current process (pid %d)", pid, os.Getpid())) + return + } + // The proc structure returned by kern.proc.pid above has an Rusage member, // but it is not filled in, so it needs to be fetched by getrusage(2). For // that call, the UTime, STime, and Maxrss members are filled out, but not diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go index fa474289ef8..c08dd05f031 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go @@ -30,6 +30,10 @@ var ( procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount") + + openProcess = windows.OpenProcess + closeHandle = windows.CloseHandle + getProcessTimes = windows.GetProcessTimes ) type processMemoryCounters struct { @@ -79,10 +83,21 @@ func getProcessHandleCount(handle windows.Handle) (uint32, error) { } func (c *processCollector) processCollect(ch chan<- Metric) { - h := windows.CurrentProcess() + pid, err := c.pidFn() + if err != nil { + c.reportError(ch, nil, err) + return + } + + h, err := openProcess(windows.PROCESS_QUERY_INFORMATION|windows.PROCESS_VM_READ, false, uint32(pid)) + if err != nil { + c.reportError(ch, nil, err) + return + } + defer closeHandle(h) var startTime, exitTime, kernelTime, userTime windows.Filetime - err := windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime) + err = getProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime) if err != nil { c.reportError(ch, nil, err) return diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index 763d99e3623..c28af5ce2ba 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -37,10 +37,12 @@ import ( "fmt" "io" "net/http" + "slices" "strconv" "sync" "time" + dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil" @@ -74,11 +76,118 @@ func defaultCompressionFormats() []Compression { } var gzipPool = sync.Pool{ - New: func() interface{} { + New: func() any { return gzip.NewWriter(nil) }, } +// coalescingGatherer wraps a TransactionalGatherer to deduplicate concurrent +// Gather calls. When a Gather is already in flight, new callers join the +// existing cycle and receive the same result once it completes. The underlying +// done function is called exactly once, when the last joined caller releases. +// +// This prevents goroutine pile-up when the scrape rate is faster than the +// time collectors need to produce metrics. +type coalescingGatherer struct { + g prometheus.TransactionalGatherer + mu sync.Mutex + cycle *gatherCycle +} + +// gatherCycle tracks a single in-flight Gather and all HTTP handlers sharing it. +type gatherCycle struct { + ready chan struct{} // closed when Gather completes; happens-before reads of mfs/err/done + mfs []*dto.MetricFamily // canonical result, set before ready is closed; callers get a slices.Clone, the element values stay shared and must not be mutated + err error // set before ready is closed + done func() // underlying done callback; set before ready is closed + refs int // number of handlers using this cycle; protected by coalescingGatherer.mu +} + +var _ prometheus.TransactionalGatherer = (*coalescingGatherer)(nil) // compile-time interface check + +// errGatherPanicked is returned to callers that joined an in-flight coalesced +// Gather whose underlying gatherer panicked. See the panic guard in Gather for +// why joiners receive this error instead of the panic itself. +var errGatherPanicked = errors.New("coalesced gather panicked") + +func (c *coalescingGatherer) Gather() ([]*dto.MetricFamily, func(), error) { + c.mu.Lock() + if cy := c.cycle; cy != nil { + // c.cycle is non-nil while Gather runs or handlers are still consuming its results. + cy.refs++ + c.mu.Unlock() + <-cy.ready + // Each caller gets its own slice header so it can filter or reorder + // without racing other callers sharing this cycle. The *dto.MetricFamily + // values remain shared and must not be mutated in place. + return slices.Clone(cy.mfs), c.releaseFunc(cy), cy.err + } + cy := &gatherCycle{ + ready: make(chan struct{}), + done: func() {}, + refs: 1, + } + c.cycle = cy + c.mu.Unlock() + + // Guard against a panic in c.g.Gather. The common case, a panicking + // Collector, never reaches here: Registry.Gather recovers Collector panics + // and returns them as an error. This guard only covers the rare case where + // the wrapped gatherer itself panics. + // + // We deliberately do not recover: the leader's panic propagates and is + // handled by net/http exactly as it would be without coalescing. We only + // set cy.err before closing cy.ready so joiners waiting on <-cy.ready fail + // with that error instead of silently returning an empty, successful + // response, and we clear c.cycle so the next Gather starts a fresh cycle. + // + // The leader never runs its own releaseFunc on this path, so its ref is + // not decremented; that is harmless because the cycle is detached (c.cycle + // = nil) and cy.done is still the no-op set at construction (c.g.Gather + // panicked before assigning a real done). If cy.done is ever made non-nil + // before c.g.Gather runs, this path would need to release it. + panicked := true + defer func() { + if panicked { + c.mu.Lock() + if c.cycle == cy { + c.cycle = nil + } + c.mu.Unlock() + cy.err = errGatherPanicked // set before close: happens-before joiners' reads + close(cy.ready) + } + }() + cy.mfs, cy.done, cy.err = c.g.Gather() + panicked = false + close(cy.ready) // happens-before joiners' reads of cy.mfs/err/done + + // Clone here too so cy.mfs stays the write-once canonical slice: joiners + // read it concurrently via slices.Clone, so the leader must not hand out + // (and potentially reorder) the same backing array. + return slices.Clone(cy.mfs), c.releaseFunc(cy), cy.err +} + +// releaseFunc returns the done callback for one caller sharing cy. +// When the last caller releases, the underlying done is invoked and the +// cycle is cleared so the next Gather starts fresh. +func (c *coalescingGatherer) releaseFunc(cy *gatherCycle) func() { + return func() { + c.mu.Lock() + cy.refs-- + if cy.refs > 0 { + c.mu.Unlock() + return + } + // Last caller. + if c.cycle == cy { + c.cycle = nil + } + c.mu.Unlock() + cy.done() // called outside the lock to avoid holding it during done + } +} + // Handler returns an http.Handler for the prometheus.DefaultGatherer, using // default HandlerOpts, i.e. it reports the first error as an HTTP error, it has // no error logging, and it applies compression if requested by the client. @@ -89,6 +198,10 @@ var gzipPool = sync.Pool{ // metrics used for instrumentation will be shared between them, providing // global scrape counts. // +// The handler supports filtering metrics by name using the `name[]` query parameter. +// Multiple metric names can be specified by providing the parameter multiple times. +// When no name[] parameters are provided, all metrics are returned. +// // This function is meant to cover the bulk of basic use cases. If you are doing // anything that requires more customization (including using a non-default // Gatherer, different instrumentation, and non-default HandlerOpts), use the @@ -105,6 +218,10 @@ func Handler() http.Handler { // Gatherers, with non-default HandlerOpts, and/or with custom (or no) // instrumentation. Use the InstrumentMetricHandler function to apply the same // kind of instrumentation as it is used by the Handler function. +// +// The handler supports filtering metrics by name using the `name[]` query parameter. +// Multiple metric names can be specified by providing the parameter multiple times. +// When no name[] parameters are provided, all metrics are returned. func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts) } @@ -112,7 +229,15 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { // HandlerForTransactional is like HandlerFor, but it uses transactional gather, which // can safely change in-place returned *dto.MetricFamily before call to `Gather` and after // call to `done` of that `Gather`. +// +// The handler supports filtering metrics by name using the `name[]` query parameter. +// Multiple metric names can be specified by providing the parameter multiple times. +// When no name[] parameters are provided, all metrics are returned. func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler { + if opts.CoalesceGather { + reg = &coalescingGatherer{g: reg} + } + var ( inFlightSem chan struct{} errCnt = prometheus.NewCounterVec( @@ -214,12 +339,14 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO rsp.Header().Set(contentEncodingHeader, encodingHeader) } - var enc expfmt.Encoder + var ( + enc expfmt.Encoder + encOpts []expfmt.EncoderOption + ) if opts.EnableOpenMetricsTextCreatedSamples { - enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines()) - } else { - enc = expfmt.NewEncoder(w, contentType) + encOpts = append(encOpts, expfmt.WithCreatedLines()) } + enc = expfmt.NewEncoder(w, contentType, encOpts...) // handleError handles the error according to opts.ErrorHandling // and returns true if we have to abort after the handling. @@ -245,7 +372,24 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO return false } + // Build metric name filter set from query params (if any). The URL + // can be nil on hand-constructed requests. + var metricFilter map[string]struct{} + if req.URL != nil { + if metricNames := req.URL.Query()["name[]"]; len(metricNames) > 0 { + metricFilter = make(map[string]struct{}, len(metricNames)) + for _, name := range metricNames { + metricFilter[name] = struct{}{} + } + } + } + for _, mf := range mfs { + if metricFilter != nil { + if _, ok := metricFilter[mf.GetName()]; !ok { + continue + } + } if handleError(enc.Encode(mf)) { return } @@ -353,7 +497,7 @@ const ( // log.Logger from the standard library implements this interface, and it is // easy to implement by custom loggers, if they don't do so already anyway. type Logger interface { - Println(v ...interface{}) + Println(v ...any) } // HandlerOpts specifies options how to serve metrics via an http.Handler. The @@ -400,6 +544,40 @@ type HandlerOpts struct { // Service Unavailable and a suitable message in the body. If // MaxRequestsInFlight is 0 or negative, no limit is applied. MaxRequestsInFlight int + // CoalesceGather, if true, deduplicates concurrent Gather calls so that + // only one collection runs at a time. Additional requests that arrive + // while a Gather is in flight will receive the same result once it + // completes. This prevents goroutine pile-up when the scrape rate is + // faster than the time collectors need to produce metrics. + // + // When enabled, concurrent scrapers share a single metric snapshot per + // collection cycle. Each request receives its own copy of the returned + // slice, so filtering or reordering it (for example via name[] query + // parameters) is safe. The pointed-to MetricFamily values are still + // shared: the built-in handler only reads them, so this is safe in + // practice, but a custom TransactionalGatherer that mutates the returned + // families in place after Gather returns must not use this option. + // + // Because the snapshot is shared, a request that arrives while a cycle is + // in flight receives that cycle's result even though collection began + // before the request; two scrapers joined to one cycle observe the same + // timestamps rather than independently gathered data. + // + // Consider using CoalesceGather together with Timeout. Timeout bounds the + // client-facing response time and keeps at most one collection running at + // a time, but it does not cancel the underlying Gather: a joined request + // that times out still holds a MaxRequestsInFlight slot until the shared + // collection completes. + // + // Panic handling: a panicking Collector is already turned into an error by + // the registry, so joiners receive that error like any other. In the rare + // case where the wrapped gatherer itself panics, the panicking request's + // panic propagates as usual (handled by net/http), while requests that + // joined the same cycle receive an error rather than an empty response. + // + // NOTE: This option is experimental and may change or be removed in a + // future release. + CoalesceGather bool // If handling a request takes longer than Timeout, it is responded to // with 503 ServiceUnavailable and a suitable Message. No timeout is // applied if Timeout is 0 or negative. Note that with the current @@ -407,8 +585,9 @@ type HandlerOpts struct { // described above (and even that only if sending of the body hasn't // started yet), while the bulk work of gathering all the metrics keeps // running in the background (with the eventual result to be thrown - // away). Until the implementation is improved, it is recommended to - // implement a separate timeout in potentially slow Collectors. + // away). When CoalesceGather is enabled, only one such background Gather + // can be in flight at a time. It is also recommended to implement a + // separate timeout in potentially slow Collectors. Timeout time.Duration // If true, the experimental OpenMetrics encoding is added to the // possible options during content negotiation. Note that Prometheus @@ -460,7 +639,7 @@ func httpError(rsp http.ResponseWriter, err error) { // negotiateEncodingWriter reads the Accept-Encoding header from a request and // selects the right compression based on an allow-list of supported -// compressions. It returns a writer implementing the compression and an the +// compressions. It returns a writer implementing the compression and the // correct value that the caller can set in the response header. func negotiateEncodingWriter(r *http.Request, rw io.Writer, compressions []string) (_ io.Writer, encodingHeaderValue string, closeWriter func(), _ error) { if len(compressions) == 0 { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go index d3482c40ca7..0248579742a 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go @@ -75,10 +75,10 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou resp, err := next.RoundTrip(r) if err == nil { l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...) - for label, resolve := range rtOpts.extraLabelsFromCtx { - l[label] = resolve(resp.Request.Context()) + for label, resolve := range rtOpts.extraLabelsFromRequest { + l[label] = resolve(resp.Request) } - addWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r.Context())) + addWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r)) } return resp, err } @@ -119,10 +119,10 @@ func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundT resp, err := next.RoundTrip(r) if err == nil { l := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...) - for label, resolve := range rtOpts.extraLabelsFromCtx { - l[label] = resolve(resp.Request.Context()) + for label, resolve := range rtOpts.extraLabelsFromRequest { + l[label] = resolve(resp.Request) } - observeWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r)) } return resp, err } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go index 9332b0249a9..9dec091ac71 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go @@ -28,24 +28,36 @@ import ( // magicString is used for the hacky label test in checkLabels. Remove once fixed. const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" -// observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver], -// which falls back to [prometheus.Observer.Observe] if no labels are provided. +// observeWithExemplar records val on obs. If labels is non-nil and obs +// implements [prometheus.ExemplarObserver], the exemplar is attached via +// ObserveWithExemplar; otherwise the exemplar is dropped and the value is +// recorded with a plain [prometheus.Observer.Observe]. This mirrors the +// safe-cast pattern in [prometheus.Timer.ObserveDurationWithExemplar] and +// ensures we never panic when callers pass an ObserverVec backed by a +// summary, which cannot carry exemplars in the Prometheus exposition format. func observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) { - if labels == nil { - obs.Observe(val) - return + if labels != nil { + if eo, ok := obs.(prometheus.ExemplarObserver); ok { + eo.ObserveWithExemplar(val, labels) + return + } } - obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) + obs.Observe(val) } -// addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar], -// which falls back to [prometheus.Counter.Add] if no labels are provided. -func addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) { - if labels == nil { - obs.Add(val) - return +// addWithExemplar records val on c. If labels is non-nil and c implements +// [prometheus.ExemplarAdder], the exemplar is attached via AddWithExemplar; +// otherwise the exemplar is dropped and the value is recorded with a plain +// [prometheus.Counter.Add]. The safe-cast keeps the helper robust against +// custom Counter implementations that do not advertise exemplar support. +func addWithExemplar(c prometheus.Counter, val float64, labels map[string]string) { + if labels != nil { + if ea, ok := c.(prometheus.ExemplarAdder); ok { + ea.AddWithExemplar(val, labels) + return + } } - obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels) + c.Add(val) } // InstrumentHandlerInFlight is a middleware that wraps the provided @@ -97,10 +109,10 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op next.ServeHTTP(d, r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r)) } } @@ -108,10 +120,10 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op now := time.Now() next.ServeHTTP(w, r) l := labels(code, method, r.Method, 0, hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r)) } } @@ -147,10 +159,10 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, next.ServeHTTP(d, r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) + addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r)) } } @@ -158,10 +170,10 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, next.ServeHTTP(w, r) l := labels(code, method, r.Method, 0, hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) + addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r)) } } @@ -200,10 +212,10 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha now := time.Now() d := newDelegator(w, func(status int) { l := labels(code, method, r.Method, status, hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r)) }) next.ServeHTTP(d, r) } @@ -244,10 +256,10 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, size := computeApproximateRequestSize(r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r)) } } @@ -256,10 +268,10 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, size := computeApproximateRequestSize(r) l := labels(code, method, r.Method, 0, hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r)) } } @@ -296,10 +308,10 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler next.ServeHTTP(d, r) l := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...) - for label, resolve := range hOpts.extraLabelsFromCtx { - l[label] = resolve(r.Context()) + for label, resolve := range hOpts.extraLabelsFromRequest { + l[label] = resolve(r) } - observeWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r)) }) } @@ -366,7 +378,7 @@ func checkLabels(c prometheus.Collector) (code, method bool) { panic("metric partitioned with non-supported labels") } } - return + return code, method } func isLabelCurried(c prometheus.Collector, label string) bool { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go index 5d4383aa14a..d4c0954f366 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go @@ -15,6 +15,7 @@ package promhttp import ( "context" + "net/http" "github.com/prometheus/client_golang/prometheus" ) @@ -24,28 +25,31 @@ type Option interface { apply(*options) } +// LabelValueFromRequest is used to compute the label value from request. +type LabelValueFromRequest func(request *http.Request) string + // LabelValueFromCtx are used to compute the label value from request context. // Context can be filled with values from request through middleware. type LabelValueFromCtx func(ctx context.Context) string // options store options for both a handler or round tripper. type options struct { - extraMethods []string - getExemplarFn func(requestCtx context.Context) prometheus.Labels - extraLabelsFromCtx map[string]LabelValueFromCtx + extraMethods []string + getExemplarFn func(req *http.Request) prometheus.Labels + extraLabelsFromRequest map[string]LabelValueFromRequest } func defaultOptions() *options { return &options{ - getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }, - extraLabelsFromCtx: map[string]LabelValueFromCtx{}, + getExemplarFn: func(req *http.Request) prometheus.Labels { return nil }, + extraLabelsFromRequest: map[string]LabelValueFromRequest{}, } } func (o *options) emptyDynamicLabels() prometheus.Labels { labels := prometheus.Labels{} - for label := range o.extraLabelsFromCtx { + for label := range o.extraLabelsFromRequest { labels[label] = "" } @@ -66,19 +70,39 @@ func WithExtraMethods(methods ...string) Option { }) } -// WithExemplarFromContext allows to inject function that will get exemplar from context that will be put to counter and histogram metrics. +// WithExemplarFromRequest allows you to inject a function that will get exemplar from request that will be put to counter and histogram metrics. // If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but // metric will continue to observe/increment. -func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { +func WithExemplarFromRequest(getExemplarFn func(req *http.Request) prometheus.Labels) Option { return optionApplyFunc(func(o *options) { o.getExemplarFn = getExemplarFn }) } +// WithExemplarFromContext allows you to inject a function that will get exemplar from context that will be put to counter and histogram metrics. +// If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but +// metric will continue to observe/increment. +func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { + return optionApplyFunc(func(o *options) { + o.getExemplarFn = func(req *http.Request) prometheus.Labels { + return getExemplarFn(req.Context()) + } + }) +} + +// WithLabelFromRequest registers a label for dynamic resolution with access to the request. +func WithLabelFromRequest(name string, valueFn LabelValueFromRequest) Option { + return optionApplyFunc(func(o *options) { + o.extraLabelsFromRequest[name] = valueFn + }) +} + // WithLabelFromCtx registers a label for dynamic resolution with access to context. // See the example for ExampleInstrumentHandlerWithLabelResolver for example usage func WithLabelFromCtx(name string, valueFn LabelValueFromCtx) Option { return optionApplyFunc(func(o *options) { - o.extraLabelsFromCtx[name] = valueFn + o.extraLabelsFromRequest[name] = func(req *http.Request) string { + return valueFn(req.Context()) + } }) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/push/push.go b/vendor/github.com/prometheus/client_golang/prometheus/push/push.go index 1eb35ac9afa..c65b6a665ac 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/push/push.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/push/push.go @@ -182,8 +182,7 @@ func (p *Pusher) Error() error { // For convenience, this method returns a pointer to the Pusher itself. func (p *Pusher) Grouping(name, value string) *Pusher { if p.error == nil { - //nolint:staticcheck // TODO: Don't use deprecated model.NameValidationScheme. - if !model.NameValidationScheme.IsValidLabelName(name) { + if !model.UTF8Validation.IsValidLabelName(name) { p.error = fmt.Errorf("grouping label has invalid name: %s", name) return p } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go index c6fd2f58b74..ed0681c8b4e 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go @@ -214,6 +214,19 @@ func (err AlreadyRegisteredError) Error() string { // by a Gatherer to report multiple errors during MetricFamily gathering. type MultiError []error +// SafeMultiError is a thread-safe wrapper around MultiError using a mutex. +type SafeMultiError struct { + mu sync.Mutex + errs MultiError +} + +// Appends the provided error to the contained MultiError in a thread-safe way. +func (s *SafeMultiError) Append(err error) { + s.mu.Lock() + s.errs.Append(err) + s.mu.Unlock() +} + // Error formats the contained errors as a bullet point list, preceded by the // total number of errors. Note that this results in a multi-line string. func (errs MultiError) Error() string { @@ -408,6 +421,16 @@ func (r *Registry) MustRegister(cs ...Collector) { } } +// MustGather implements Gatherer. +// Wraps around Gather and panics if Gather fails for any reason. +func (r *Registry) MustGather() []*dto.MetricFamily { + mfs, err := r.Gather() + if err != nil { + panic(err) + } + return mfs +} + // Gather implements Gatherer. func (r *Registry) Gather() ([]*dto.MetricFamily, error) { r.mtx.RLock() @@ -423,7 +446,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { uncheckedMetricChan = make(chan Metric, capMetricChan) metricHashes = map[uint64]struct{}{} wg sync.WaitGroup - errs MultiError // The collected errors to return in the end. + safeErrs = &SafeMultiError{} // To collect errors in a threadsafe way registeredDescIDs map[uint64]struct{} // Only used for pedantic checks ) @@ -453,9 +476,9 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { for { select { case collector := <-checkedCollectors: - collector.Collect(checkedMetricChan) + safeErrs.Append((safeCollect(collector, checkedMetricChan))) case collector := <-uncheckedCollectors: - collector.Collect(uncheckedMetricChan) + safeErrs.Append(safeCollect(collector, uncheckedMetricChan)) default: return } @@ -499,7 +522,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { cmc = nil break } - errs.Append(processMetric( + safeErrs.Append(processMetric( metric, metricFamiliesByName, metricHashes, registeredDescIDs, @@ -509,7 +532,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { umc = nil break } - errs.Append(processMetric( + safeErrs.Append(processMetric( metric, metricFamiliesByName, metricHashes, nil, @@ -526,7 +549,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { cmc = nil break } - errs.Append(processMetric( + safeErrs.Append(processMetric( metric, metricFamiliesByName, metricHashes, registeredDescIDs, @@ -536,7 +559,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { umc = nil break } - errs.Append(processMetric( + safeErrs.Append(processMetric( metric, metricFamiliesByName, metricHashes, nil, @@ -556,7 +579,8 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { break } } - return internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap() + + return internal.NormalizeMetricFamilies(metricFamiliesByName), safeErrs.errs.MaybeUnwrap() } // Describe implements Collector. @@ -571,6 +595,24 @@ func (r *Registry) Describe(ch chan<- *Desc) { } } +// Helper wrapper around Collector.Collect. +// It tries to collect from the channel, recovers on panic and +// if it has recovered from a panic, then it sends an InvalidMetric into +// the channel with an InvalidDesc, and an error that includes a stack trace. +func safeCollect(c Collector, ch chan<- Metric) (err error) { + defer func() { + if r := recover(); r != nil { + buf := make([]byte, 64<<10) // 64 KB + n := runtime.Stack(buf, false) + err = fmt.Errorf("prometheus collector panic recovered: type=%T: error=%v\nstack trace=%s", c, r, buf[:n]) + ch <- NewInvalidMetric(NewInvalidDesc(err), err) + } + }() + c.Collect(ch) + + return err +} + // Collect implements Collector. func (r *Registry) Collect(ch chan<- Metric) { r.mtx.RLock() @@ -599,10 +641,12 @@ func WriteToTextfile(filename string, g Gatherer) error { mfs, err := g.Gather() if err != nil { + tmp.Close() return err } for _, mf := range mfs { if _, err := expfmt.MetricFamilyToText(tmp, mf); err != nil { + tmp.Close() return err } } @@ -685,6 +729,9 @@ func processMetric( metricFamily = &dto.MetricFamily{} metricFamily.Name = proto.String(desc.fqName) metricFamily.Help = proto.String(desc.help) + if desc.unit != "" { + metricFamily.Unit = proto.String(desc.unit) + } // TODO(beorn7): Simplify switch once Desc has type. switch { case dtoMetric.Gauge != nil: diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go index ac5203c6faa..c12b8d13d4b 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/summary.go @@ -101,6 +101,9 @@ type SummaryOpts struct { // string. Help string + // Unit provides the unit of this Summary. + Unit string + // ConstLabels are used to attach fixed labels to this metric. Metrics // with the same fully-qualified name must have the same label names in // their ConstLabels. @@ -181,11 +184,12 @@ type SummaryVecOpts struct { // NewSummary creates a new Summary based on the provided SummaryOpts. func NewSummary(opts SummaryOpts) Summary { return newSummary( - NewDesc( + V2.NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, - nil, + UnconstrainedLabels(nil), opts.ConstLabels, + WithUnit(opts.Unit), ), opts, ) @@ -578,6 +582,7 @@ func (v2) NewSummaryVec(opts SummaryVecOpts) *SummaryVec { opts.Help, opts.VariableLabels, opts.ConstLabels, + WithUnit(opts.Unit), ) return &SummaryVec{ MetricVec: NewMetricVec(desc, func(lvs ...string) Metric { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/timer.go b/vendor/github.com/prometheus/client_golang/prometheus/timer.go index 52344fef53f..c1318ffb51e 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/timer.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/timer.go @@ -37,10 +37,10 @@ type Timer struct { // or // // func TimeMeWithExemplar() { -// timer := NewTimer(myHistogram) -// defer timer.ObserveDurationWithExemplar(exemplar) -// // Do actual work. -// } +// timer := NewTimer(myHistogram) +// defer timer.ObserveDurationWithExemplar(exemplar) +// // Do actual work. +// } func NewTimer(o Observer) *Timer { return &Timer{ begin: time.Now(), @@ -66,7 +66,7 @@ func (t *Timer) ObserveDuration() time.Duration { // ObserveDurationWithExemplar is like ObserveDuration, but it will also // observe exemplar with the duration unless exemplar is nil or provided Observer can't -// be casted to ExemplarObserver. +// be cast to ExemplarObserver. func (t *Timer) ObserveDurationWithExemplar(exemplar Labels) time.Duration { d := time.Since(t.begin) eo, ok := t.observer.(ExemplarObserver) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go index 487b466563b..121d2a96390 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go @@ -193,9 +193,11 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) { // // Keeping the Metric for later use is possible (and should be considered if // performance is critical), but keep in mind that Reset, DeleteLabelValues and -// Delete can be used to delete the Metric from the MetricVec. In that case, the -// Metric will still exist, but it will not be exported anymore, even if a -// Metric with the same label values is created later. +// Delete can be used to delete the Metric from the MetricVec. In that case, if +// you have previously kept a reference to that Metric, the Metric object still +// exists and can be used, but it will not be exported anymore. If a Metric with +// the same label values is created later, updates to the old Metric reference +// will not be exported. // // An error is returned if the number of label values is not the same as the // number of variable labels in Desc (minus any curried labels). @@ -657,7 +659,7 @@ func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string { } var labelsPool = &sync.Pool{ - New: func() interface{} { + New: func() any { return make(Labels) }, } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go index 2ed1285068e..697f55558bd 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go @@ -230,6 +230,7 @@ func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc { return &Desc{ fqName: desc.fqName, help: desc.help, + unit: desc.unit, variableLabels: desc.variableLabels, constLabelPairs: desc.constLabelPairs, err: fmt.Errorf("attempted wrapping with already existing label name %q", ln), @@ -238,8 +239,8 @@ func wrapDesc(desc *Desc, prefix string, labels Labels) *Desc { constLabels[ln] = lv } // NewDesc will do remaining validations. - newDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels) - // Propagate errors if there was any. This will override any errer + newDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels, WithUnit(desc.unit)) + // Propagate errors if there was any. This will override any error // created by NewDesc above, i.e. earlier errors get precedence. if desc.err != nil { newDesc.err = desc.err diff --git a/vendor/github.com/prometheus/common/config/http_config.go b/vendor/github.com/prometheus/common/config/http_config.go index 88457375ff1..d633479c690 100644 --- a/vendor/github.com/prometheus/common/config/http_config.go +++ b/vendor/github.com/prometheus/common/config/http_config.go @@ -132,7 +132,7 @@ func (tv *TLSVersion) String() string { return s } } - return fmt.Sprintf("%d", tv) + return fmt.Sprintf("%d", *tv) } // BasicAuth contains basic HTTP authentication credentials. @@ -1178,10 +1178,8 @@ func originalRequestHost(req *http.Request) string { } // sensitiveHeadersOnRedirect lists the headers that must not be forwarded when -// following a redirect to a different host. The first four entries match the -// list stripped by makeHeadersCopier in net/http/client.go; we additionally -// strip the Proxy-* headers, which net/http does not, to avoid leaking proxy -// credentials to an untrusted host. +// following a redirect to a different host. The list matches the one stripped +// by makeHeadersCopier in net/http/client.go. var sensitiveHeadersOnRedirect = map[string]struct{}{ "Authorization": {}, // "Www-Authenticate" is the canonical form produced by diff --git a/vendor/github.com/prometheus/common/route/route.go b/vendor/github.com/prometheus/common/route/route.go index 18039fac0d5..b1f274c15d4 100644 --- a/vendor/github.com/prometheus/common/route/route.go +++ b/vendor/github.com/prometheus/common/route/route.go @@ -20,6 +20,11 @@ import ( "github.com/julienschmidt/httprouter" ) +// MethodQuery is the QUERY HTTP method. It is a safe, idempotent method that +// carries a request body, see https://datatracker.ietf.org/doc/rfc10008/. +// It is not yet part of net/http, so it is defined here. +const MethodQuery = "QUERY" + type param string // Param returns param p for the context, or the empty string when @@ -114,6 +119,11 @@ func (r *Router) Head(path string, h http.HandlerFunc) { r.rtr.HEAD(r.prefix+path, r.handle(path, h)) } +// Query registers a new QUERY route. +func (r *Router) Query(path string, h http.HandlerFunc) { + r.rtr.Handle(MethodQuery, r.prefix+path, r.handle(path, h)) +} + // Redirect takes an absolute path and sends an internal HTTP redirect for it, // prefixed by the router's path prefix. Note that this method does not include // functionality for handling relative paths or full URL redirects. diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go index 69d07944516..f74dd3bed04 100644 --- a/vendor/github.com/prometheus/procfs/net_wireless.go +++ b/vendor/github.com/prometheus/procfs/net_wireless.go @@ -114,47 +114,47 @@ func parseWireless(r io.Reader) ([]*Wireless, error) { qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], ".")) if err != nil { - return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, qlink, err) + return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, stats[1], err) } qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], ".")) if err != nil { - return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, qlevel, err) + return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, stats[2], err) } qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], ".")) if err != nil { - return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, qnoise, err) + return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, stats[3], err) } dnwid, err := strconv.Atoi(stats[4]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, dnwid, err) + return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, stats[4], err) } dcrypt, err := strconv.Atoi(stats[5]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, dcrypt, err) + return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, stats[5], err) } dfrag, err := strconv.Atoi(stats[6]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, dfrag, err) + return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, stats[6], err) } dretry, err := strconv.Atoi(stats[7]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, dretry, err) + return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, stats[7], err) } dmisc, err := strconv.Atoi(stats[8]) if err != nil { - return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, dmisc, err) + return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, stats[8], err) } mbeacon, err := strconv.Atoi(stats[9]) if err != nil { - return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, mbeacon, err) + return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, stats[9], err) } w := &Wireless{ diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go index 535c08d6fc0..7e8a122978f 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go @@ -60,7 +60,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) { } cgroup.HierarchyID, err = strconv.Atoi(fields[0]) if err != nil { - return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, cgroup.HierarchyID) + return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, fields[0]) } if fields[1] != "" { ssNames := strings.Split(fields[1], ",") diff --git a/vendor/github.com/stretchr/objx/README.md b/vendor/github.com/stretchr/objx/README.md index 78dc1f8b03e..e9ba8307354 100644 --- a/vendor/github.com/stretchr/objx/README.md +++ b/vendor/github.com/stretchr/objx/README.md @@ -1,8 +1,6 @@ # Objx [![Build Status](https://travis-ci.org/stretchr/objx.svg?branch=master)](https://travis-ci.org/stretchr/objx) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/objx)](https://goreportcard.com/report/github.com/stretchr/objx) -[![Maintainability](https://api.codeclimate.com/v1/badges/1d64bc6c8474c2074f2b/maintainability)](https://codeclimate.com/github/stretchr/objx/maintainability) -[![Test Coverage](https://api.codeclimate.com/v1/badges/1d64bc6c8474c2074f2b/test_coverage)](https://codeclimate.com/github/stretchr/objx/test_coverage) [![Sourcegraph](https://sourcegraph.com/github.com/stretchr/objx/-/badge.svg)](https://sourcegraph.com/github.com/stretchr/objx) [![GoDoc](https://pkg.go.dev/badge/github.com/stretchr/objx?utm_source=godoc)](https://pkg.go.dev/github.com/stretchr/objx) @@ -19,49 +17,62 @@ Objx provides the `objx.Map` type, which is a `map[string]interface{}` that expo ### Pattern Objx uses a predictable pattern to make access data from within `map[string]interface{}` easy. Call one of the `objx.` functions to create your `objx.Map` to get going: - m, err := objx.FromJSON(json) +```go +m, err := objx.FromJSON(json) +``` NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, the rest will be optimistic and try to figure things out without panicking. Use `Get` to access the value you're interested in. You can use dot and array notation too: - m.Get("places[0].latlng") +```go +m.Get("places[0].latlng") +``` Once you have sought the `Value` you're interested in, you can use the `Is*` methods to determine its type. - if m.Get("code").IsStr() { // Your code... } +```go +if m.Get("code").IsStr() { // Your code... } +``` Or you can just assume the type, and use one of the strong type methods to extract the real value: - m.Get("code").Int() +```go +m.Get("code").Int() +``` If there's no value there (or if it's the wrong type) then a default value will be returned, or you can be explicit about the default value. - Get("code").Int(-1) - +```go +Get("code").Int(-1) +``` If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating, manipulating and selecting that data. You can find out more by exploring the index below. ### Reading data A simple example of how to use Objx: - // Use MustFromJSON to make an objx.Map from some JSON - m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) +```go +// Use MustFromJSON to make an objx.Map from some JSON +m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) - // Get the details - name := m.Get("name").Str() - age := m.Get("age").Int() +// Get the details +name := m.Get("name").Str() +age := m.Get("age").Int() - // Get their nickname (or use their name if they don't have one) - nickname := m.Get("nickname").Str(name) +// Get their nickname (or use their name if they don't have one) +nickname := m.Get("nickname").Str(name) +``` ### Ranging Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For example, to `range` the data, do what you would expect: - m := objx.MustFromJSON(json) - for key, value := range m { - // Your code... - } +```go +m := objx.MustFromJSON(json) +for key, value := range m { + // Your code... +} +``` ## Installation To install Objx, use go get: diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go index c592f6ad5fb..a19a89279cc 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -84,7 +84,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -124,7 +124,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Errorf(t, err, "error message %s", "formatted") @@ -144,8 +144,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -190,10 +190,10 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// assert.EventuallyWithTf(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -552,7 +552,7 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool return NoDirExists(t, path, append([]interface{}{msg}, args...)...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoErrorf(t, err, "error message %s", "formatted") { @@ -849,7 +849,19 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index 58db928450d..cd2a86061c6 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -146,7 +146,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs return Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -158,7 +158,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... return EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -240,7 +240,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string return Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -269,8 +269,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. return ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -281,8 +281,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . return ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -311,7 +311,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter return ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -372,10 +372,10 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor // time.Sleep(8*time.Second) // externalValue = true // }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// a.EventuallyWithTf(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1096,7 +1096,7 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) return NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoError(err) { @@ -1109,7 +1109,7 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoErrorf(err, "error message %s", "formatted") { @@ -1690,7 +1690,19 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti return WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1698,7 +1710,19 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf return YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go index 2fdf80fdd30..a44b40ed3f5 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go @@ -9,7 +9,7 @@ import ( func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { objKind := reflect.TypeOf(object).Kind() if objKind != reflect.Slice && objKind != reflect.Array { - return false + return Fail(t, fmt.Sprintf("object %T is not an ordered collection", object), msgAndArgs...) } objValue := reflect.ValueOf(object) @@ -50,6 +50,9 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR // assert.IsIncreasing(t, []float{1, 2}) // assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } @@ -59,6 +62,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonIncreasing(t, []float{2, 1}) // assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } @@ -68,6 +74,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // assert.IsDecreasing(t, []float{2, 1}) // assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } @@ -77,5 +86,8 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonDecreasing(t, []float{1, 2}) // assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index de8de0cb6c4..166f63726cf 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -17,11 +17,10 @@ import ( "unicode" "unicode/utf8" - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" - - // Wrapper around gopkg.in/yaml.v3 + // Wrapper around go.yaml.in/yaml/v3 "github.com/stretchr/testify/assert/yaml" + "github.com/stretchr/testify/internal/difflib" + "github.com/stretchr/testify/internal/spew" ) //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" @@ -33,19 +32,19 @@ type TestingT interface { // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful // for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool +type ComparisonAssertionFunc = func(TestingT, interface{}, interface{}, ...interface{}) bool // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful // for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool +type ValueAssertionFunc = func(TestingT, interface{}, ...interface{}) bool // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful // for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool +type BoolAssertionFunc = func(TestingT, bool, ...interface{}) bool // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful // for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool +type ErrorAssertionFunc = func(TestingT, error, ...interface{}) bool // PanicAssertionFunc is a common function prototype when validating a panic value. Can be useful // for table driven tests. @@ -325,13 +324,15 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { func indentMessageLines(message string, longestLabelLen int) string { outBuf := new(bytes.Buffer) - for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { - // no need to align first line because it starts at the correct location (after the label) - if i != 0 { - // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab - outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") + scanner := bufio.NewScanner(strings.NewReader(message)) + for firstLine := true; scanner.Scan(); firstLine = false { + if !firstLine { + fmt.Fprint(outBuf, "\n\t"+strings.Repeat(" ", longestLabelLen+1)+"\t") } - outBuf.WriteString(scanner.Text()) + fmt.Fprint(outBuf, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return fmt.Sprintf("cannot display message: %s", err) } return outBuf.String() @@ -544,9 +545,8 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b if !same { // both are pointers but not the same type & pointing to the same address return Fail(t, fmt.Sprintf("Not same: \n"+ - "expected: %p %#[1]v\n"+ - "actual : %p %#[2]v", - expected, actual), msgAndArgs...) + "expected: %[2]s (%[1]T)(%[1]p)\n"+ + "actual : %[4]s (%[3]T)(%[3]p)", expected, truncatingFormat("%#v", expected), actual, truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -571,8 +571,8 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} if same { return Fail(t, fmt.Sprintf( - "Expected and actual point to the same object: %p %#[1]v", - expected), msgAndArgs...) + "Expected and actual point to the same object: %p %s", + expected, truncatingFormat("%#v", expected)), msgAndArgs...) } return true } @@ -604,25 +604,26 @@ func samePointers(first, second interface{}) (same bool, ok bool) { // to a type conversion in the Go grammar. func formatUnequalValues(expected, actual interface{}) (e string, a string) { if reflect.TypeOf(expected) != reflect.TypeOf(actual) { - return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), - fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) + return fmt.Sprintf("%T(%s)", expected, truncatingFormat("%#v", expected)), + fmt.Sprintf("%T(%s)", actual, truncatingFormat("%#v", actual)) } switch expected.(type) { case time.Duration: return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) } - return truncatingFormat(expected), truncatingFormat(actual) + return truncatingFormat("%#v", expected), truncatingFormat("%#v", actual) } // truncatingFormat formats the data and truncates it if it's too long. // // This helps keep formatted error messages lines from exceeding the // bufio.MaxScanTokenSize max line length that the go testing framework imposes. -func truncatingFormat(data interface{}) string { - value := fmt.Sprintf("%#v", data) - max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. - if len(value) > max { - value = value[0:max] + "<... truncated>" +func truncatingFormat(format string, data interface{}) string { + value := fmt.Sprintf(format, data) + // Give us space for two truncated objects and the surrounding sentence. + maxMessageSize := bufio.MaxScanTokenSize/2 - 100 + if len(value) > maxMessageSize { + value = value[0:maxMessageSize] + "<... truncated>" } return value } @@ -743,7 +744,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("Expected nil, but got: %s", truncatingFormat("%#v", object)), msgAndArgs...) } // isEmpty gets whether the specified object is considered empty or not. @@ -793,7 +794,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + Fail(t, fmt.Sprintf("Should be empty, but was %s", truncatingFormat("%v", object)), msgAndArgs...) } return pass @@ -836,11 +837,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) } l, ok := getLen(object) if !ok { - return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", truncatingFormat("%v", object)), msgAndArgs...) } if l != length { - return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q should have %d item(s), but has %d", truncatingFormat("%v", object), length, l), msgAndArgs...) } return true } @@ -889,7 +890,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{ } if ObjectsAreEqual(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -904,7 +905,7 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte } if ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -964,10 +965,10 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -986,10 +987,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if found { - return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s should not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -1031,10 +1032,10 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok av := actualMap.MapIndex(k) if !av.IsValid() { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } if !ObjectsAreEqual(ev.Interface(), av.Interface()) { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } } @@ -1056,7 +1057,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", list), element), msgAndArgs...) } } @@ -1082,12 +1083,12 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) listKind := reflect.TypeOf(list).Kind() if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v has an unsupported type %s", list, listKind), msgAndArgs...) } subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v has an unsupported type %s", subset, subsetKind), msgAndArgs...) } if subsetKind == reflect.Map && listKind == reflect.Map { @@ -1106,7 +1107,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } subsetList := reflect.ValueOf(subset) @@ -1121,14 +1122,14 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { - return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { return true } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified @@ -1343,9 +1344,15 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . if !funcDidPanic { return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) } - panicErr, ok := panicValue.(error) - if !ok || panicErr.Error() != errString { - return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) + panicErr, isError := panicValue.(error) + if !isError || panicErr.Error() != errString { + msg := fmt.Sprintf("func %#v should panic with error message:\t%#v\n", f, errString) + if isError { + msg += fmt.Sprintf("\tError message:\t%#v\n", panicErr.Error()) + } + msg += fmt.Sprintf("\tPanic value:\t%#v\n", panicValue) + msg += fmt.Sprintf("\tPanic stack:\t%s\n", panickedStack) + return Fail(t, msg, msgAndArgs...) } return true @@ -1624,7 +1631,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m Errors */ -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoError(t, err) { @@ -1635,13 +1642,13 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error:\n%s", truncatingFormat("%+v", err)), msgAndArgs...) } return true } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Error(t, err) @@ -1656,7 +1663,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { return true } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -1674,13 +1681,13 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte if expected != actual { return Fail(t, fmt.Sprintf("Error message not equal:\n"+ "expected: %q\n"+ - "actual : %q", expected, actual), msgAndArgs...) + "actual : %s", expected, truncatingFormat("%q", actual)), msgAndArgs...) } return true } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContains(t, err, expectedErrorSubString) @@ -1694,7 +1701,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in actual := theError.Error() if !strings.Contains(actual, contains) { - return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("Error %s does not contain %#v", truncatingFormat("%#v", actual), contains), msgAndArgs...) } return true @@ -1760,7 +1767,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { h.Helper() } if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should be zero, but was %s", truncatingFormat("%v", i)), msgAndArgs...) } return true } @@ -1874,7 +1881,19 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -2188,8 +2207,8 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ - "expected: %q\n"+ - "in chain: %s", expectedText, chain, + "expected: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2211,8 +2230,8 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ - "found: %q\n"+ - "in chain: %s", expectedText, chain, + "found: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2236,7 +2255,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ "expected: %s\n"+ - "in chain: %s", expectedType, chain, + "in chain: %s", expectedType, truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2254,7 +2273,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ "found: %s\n"+ - "in chain: %s", reflect.TypeOf(target).Elem().String(), chain, + "in chain: %s", reflect.TypeOf(target).Elem().String(), truncatingFormat("%s", chain), ), msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go index a0b953aa5cf..c111589c7eb 100644 --- a/vendor/github.com/stretchr/testify/assert/doc.go +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -40,8 +40,8 @@ // // # Assertions // -// Assertions allow you to easily write test code, and are global funcs in the `assert` package. -// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// Assertions allow you to easily write test code, and are global funcs in the assert package. +// All assertion functions take, as the first argument, the [*testing.T] object provided by the // testing framework. This allows the assertion funcs to write the failings and other details to // the correct place. // diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go index 5a74c4f4d5b..956227ca272 100644 --- a/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go +++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go @@ -7,7 +7,7 @@ // go test -tags testify_yaml_custom // // This implementation can be used at build time to replace the default implementation -// to avoid linking with [gopkg.in/yaml.v3]. +// to avoid linking with [go.yaml.in/yaml/v3]. // // In your test package: // diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go index 0bae80e34a3..dd89ac03aab 100644 --- a/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go +++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go @@ -6,7 +6,7 @@ // indirection with an alternative implementation of this package that uses // another implementation of YAML deserialization. This allows to not either not // use YAML deserialization at all, or to use another implementation than -// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). +// [go.yaml.in/yaml/v3] (for example for license compatibility reasons, see [PR #1120]). // // Alternative implementations are selected using build tags: // @@ -28,9 +28,9 @@ // [PR #1120]: https://github.com/stretchr/testify/pull/1120 package yaml -import goyaml "gopkg.in/yaml.v3" +import goyaml "go.yaml.in/yaml/v3" -// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal]. +// Unmarshal is just a wrapper of [go.yaml.in/yaml/v3.Unmarshal]. func Unmarshal(in []byte, out interface{}) error { return goyaml.Unmarshal(in, out) } diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go index 8041803fd2f..a51d2792508 100644 --- a/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go +++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go @@ -3,7 +3,7 @@ // Package yaml is an implementation of YAML functions that always fail. // // This implementation can be used at build time to replace the default implementation -// to avoid linking with [gopkg.in/yaml.v3]: +// to avoid linking with [go.yaml.in/yaml/v3]: // // go test -tags testify_yaml_fail package yaml diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/stretchr/testify/internal/difflib/LICENSE similarity index 95% rename from vendor/github.com/pmezard/go-difflib/LICENSE rename to vendor/github.com/stretchr/testify/internal/difflib/LICENSE index c67dad612a3..485be13c67b 100644 --- a/vendor/github.com/pmezard/go-difflib/LICENSE +++ b/vendor/github.com/stretchr/testify/internal/difflib/LICENSE @@ -24,4 +24,4 @@ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/stretchr/testify/internal/difflib/difflib.go similarity index 77% rename from vendor/github.com/pmezard/go-difflib/difflib/difflib.go rename to vendor/github.com/stretchr/testify/internal/difflib/difflib.go index 003e99fadb4..9984599b4ff 100644 --- a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go +++ b/vendor/github.com/stretchr/testify/internal/difflib/difflib.go @@ -8,11 +8,14 @@ // // - unified_diff // -// - context_diff -// // Getting unified diffs was the main goal of the port. Keep in mind this code // is mostly suitable to output text differences in a human friendly way, there // are no guarantees generated diffs are consumable by patch(1). +// +// This package was adopted from [github.com/pmezard/go-difflib] which +// is no longer maintained. +// +// [github.com/pmezard/go-difflib]: https://github.com/pmezard/go-difflib package difflib import ( @@ -37,13 +40,6 @@ func max(a, b int) int { return b } -func calculateRatio(matches, length int) float64 { - if length > 0 { - return 2.0 * float64(matches) / float64(length) - } - return 1.0 -} - type Match struct { A int B int @@ -103,14 +99,6 @@ func NewMatcher(a, b []string) *SequenceMatcher { return &m } -func NewMatcherWithJunk(a, b []string, autoJunk bool, - isJunk func(string) bool) *SequenceMatcher { - - m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} - m.SetSeqs(a, b) - return &m -} - // Set two sequences to be compared. func (m *SequenceMatcher) SetSeqs(a, b []string) { m.SetSeq1(a) @@ -199,12 +187,15 @@ func (m *SequenceMatcher) isBJunk(s string) bool { // If IsJunk is not defined: // // Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where -// alo <= i <= i+k <= ahi -// blo <= j <= j+k <= bhi +// +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// // and for all (i',j',k') meeting those conditions, -// k >= k' -// i <= i' -// and if i == i', j <= j' +// +// k >= k' +// i <= i' +// and if i == i', j <= j' // // In other words, of all maximal matching blocks, return one that // starts earliest in a, and of all those maximal matching blocks that @@ -451,66 +442,6 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { return groups } -// Return a measure of the sequences' similarity (float in [0,1]). -// -// Where T is the total number of elements in both sequences, and -// M is the number of matches, this is 2.0*M / T. -// Note that this is 1 if the sequences are identical, and 0 if -// they have nothing in common. -// -// .Ratio() is expensive to compute if you haven't already computed -// .GetMatchingBlocks() or .GetOpCodes(), in which case you may -// want to try .QuickRatio() or .RealQuickRation() first to get an -// upper bound. -func (m *SequenceMatcher) Ratio() float64 { - matches := 0 - for _, m := range m.GetMatchingBlocks() { - matches += m.Size - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() relatively quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute. -func (m *SequenceMatcher) QuickRatio() float64 { - // viewing a and b as multisets, set matches to the cardinality - // of their intersection; this counts the number of matches - // without regard to order, so is clearly an upper bound - if m.fullBCount == nil { - m.fullBCount = map[string]int{} - for _, s := range m.b { - m.fullBCount[s] = m.fullBCount[s] + 1 - } - } - - // avail[x] is the number of times x appears in 'b' less the - // number of times we've seen it in 'a' so far ... kinda - avail := map[string]int{} - matches := 0 - for _, s := range m.a { - n, ok := avail[s] - if !ok { - n = m.fullBCount[s] - } - avail[s] = n - 1 - if n > 0 { - matches += 1 - } - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() very quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute than either .Ratio() or .QuickRatio(). -func (m *SequenceMatcher) RealQuickRatio() float64 { - la, lb := len(m.a), len(m.b) - return calculateRatio(min(la, lb), la+lb) -} - // Convert range to the "ed" format func formatRangeUnified(start, stop int) string { // Per the diff spec at http://www.unix.org/single_unix_specification/ @@ -652,117 +583,6 @@ func formatRangeContext(start, stop int) string { return fmt.Sprintf("%d,%d", beginning, beginning+length-1) } -type ContextDiff UnifiedDiff - -// Compare two sequences of lines; generate the delta as a context diff. -// -// Context diffs are a compact way of showing line changes and a few -// lines of context. The number of context lines is set by diff.Context -// which defaults to three. -// -// By default, the diff control lines (those with *** or ---) are -// created with a trailing newline. -// -// For inputs that do not have trailing newlines, set the diff.Eol -// argument to "" so that the output will be uniformly newline free. -// -// The context diff format normally has a header for filenames and -// modification times. Any or all of these may be specified using -// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. -// The modification times are normally expressed in the ISO 8601 format. -// If not specified, the strings default to blanks. -func WriteContextDiff(writer io.Writer, diff ContextDiff) error { - buf := bufio.NewWriter(writer) - defer buf.Flush() - var diffErr error - wf := func(format string, args ...interface{}) { - _, err := buf.WriteString(fmt.Sprintf(format, args...)) - if diffErr == nil && err != nil { - diffErr = err - } - } - ws := func(s string) { - _, err := buf.WriteString(s) - if diffErr == nil && err != nil { - diffErr = err - } - } - - if len(diff.Eol) == 0 { - diff.Eol = "\n" - } - - prefix := map[byte]string{ - 'i': "+ ", - 'd': "- ", - 'r': "! ", - 'e': " ", - } - - started := false - m := NewMatcher(diff.A, diff.B) - for _, g := range m.GetGroupedOpCodes(diff.Context) { - if !started { - started = true - fromDate := "" - if len(diff.FromDate) > 0 { - fromDate = "\t" + diff.FromDate - } - toDate := "" - if len(diff.ToDate) > 0 { - toDate = "\t" + diff.ToDate - } - if diff.FromFile != "" || diff.ToFile != "" { - wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) - wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) - } - } - - first, last := g[0], g[len(g)-1] - ws("***************" + diff.Eol) - - range1 := formatRangeContext(first.I1, last.I2) - wf("*** %s ****%s", range1, diff.Eol) - for _, c := range g { - if c.Tag == 'r' || c.Tag == 'd' { - for _, cc := range g { - if cc.Tag == 'i' { - continue - } - for _, line := range diff.A[cc.I1:cc.I2] { - ws(prefix[cc.Tag] + line) - } - } - break - } - } - - range2 := formatRangeContext(first.J1, last.J2) - wf("--- %s ----%s", range2, diff.Eol) - for _, c := range g { - if c.Tag == 'r' || c.Tag == 'i' { - for _, cc := range g { - if cc.Tag == 'd' { - continue - } - for _, line := range diff.B[cc.J1:cc.J2] { - ws(prefix[cc.Tag] + line) - } - } - break - } - } - } - return diffErr -} - -// Like WriteContextDiff but returns the diff a string. -func GetContextDiffString(diff ContextDiff) (string, error) { - w := &bytes.Buffer{} - err := WriteContextDiff(w, diff) - return string(w.Bytes()), err -} - // Split a string on "\n" while preserving them. The output can be used // as input for UnifiedDiff and ContextDiff structures. func SplitLines(s string) []string { diff --git a/vendor/github.com/stretchr/testify/internal/spew/LICENSE b/vendor/github.com/stretchr/testify/internal/spew/LICENSE new file mode 100644 index 00000000000..bc52e96f2b0 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2012-2016 Dave Collins + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/internal/spew/README.md b/vendor/github.com/stretchr/testify/internal/spew/README.md new file mode 100644 index 00000000000..51a909e2ef0 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/README.md @@ -0,0 +1,12 @@ +go-spew +======= + +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) + +Go-spew implements a deep pretty printer for Go data structures to aid in +debugging. A comprehensive suite of tests with 100% test coverage is provided +to ensure proper functionality. + +## License + +Go-spew is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/vendor/github.com/stretchr/testify/internal/spew/bypass.go b/vendor/github.com/stretchr/testify/internal/spew/bypass.go new file mode 100644 index 00000000000..70ddeaad3e5 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/bypass.go @@ -0,0 +1,146 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is not running on Google App Engine, compiled by GopherJS, and +// "-tags safe" is not added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// Go versions prior to 1.4 are disabled because they use a different layout +// for interfaces which make the implementation of unsafeReflectValue more complex. +//go:build !js && !appengine && !safe && !disableunsafe && go1.4 +// +build !js,!appengine,!safe,!disableunsafe,go1.4 + +package spew + +import ( + "reflect" + "unsafe" +) + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = false + + // ptrSize is the size of a pointer on the current arch. + ptrSize = unsafe.Sizeof((*byte)(nil)) +) + +type flag uintptr + +var ( + // flagRO indicates whether the value field of a reflect.Value + // is read-only. + flagRO flag + + // flagAddr indicates whether the address of the reflect.Value's + // value may be taken. + flagAddr flag +) + +// flagKindMask holds the bits that make up the kind +// part of the flags field. In all the supported versions, +// it is in the lower 5 bits. +const flagKindMask = flag(0x1f) + +// Different versions of Go have used different +// bit layouts for the flags type. This table +// records the known combinations. +var okFlags = []struct { + ro, addr flag +}{{ + // From Go 1.4 to 1.5 + ro: 1 << 5, + addr: 1 << 7, +}, { + // Up to Go tip. + ro: 1<<5 | 1<<6, + addr: 1 << 8, +}} + +var flagValOffset = func() uintptr { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + return field.Offset +}() + +// flagField returns a pointer to the flag field of a reflect.Value. +func flagField(v *reflect.Value) *flag { + return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) +} + +// unsafeReflectValue converts the passed reflect.Value into a one that bypasses +// the typical safety restrictions preventing access to unaddressable and +// unexported data. It works by digging the raw pointer to the underlying +// value out of the protected value and generating a new unprotected (unsafe) +// reflect.Value to it. +// +// This allows us to check for implementations of the Stringer and error +// interfaces to be used for pretty printing ordinarily unaddressable and +// inaccessible values such as unexported struct fields. +func unsafeReflectValue(v reflect.Value) reflect.Value { + if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { + return v + } + flagFieldPtr := flagField(&v) + *flagFieldPtr &^= flagRO + *flagFieldPtr |= flagAddr + return v +} + +// Sanity checks against future reflect package changes +// to the type or semantics of the Value.flag field. +func init() { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { + panic("reflect.Value flag field has changed kind") + } + type t0 int + var t struct { + A t0 + // t0 will have flagEmbedRO set. + t0 + // a will have flagStickyRO set + a t0 + } + vA := reflect.ValueOf(t).FieldByName("A") + va := reflect.ValueOf(t).FieldByName("a") + vt0 := reflect.ValueOf(t).FieldByName("t0") + + // Infer flagRO from the difference between the flags + // for the (otherwise identical) fields in t. + flagPublic := *flagField(&vA) + flagWithRO := *flagField(&va) | *flagField(&vt0) + flagRO = flagPublic ^ flagWithRO + + // Infer flagAddr from the difference between a value + // taken from a pointer and not. + vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") + flagNoPtr := *flagField(&vA) + flagPtr := *flagField(&vPtrA) + flagAddr = flagNoPtr ^ flagPtr + + // Check that the inferred flags tally with one of the known versions. + for _, f := range okFlags { + if flagRO == f.ro && flagAddr == f.addr { + return + } + } + panic("reflect.Value read-only flag has changed semantics") +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go b/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go new file mode 100644 index 00000000000..5e2d890d6ac --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go @@ -0,0 +1,39 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is running on Google App Engine, compiled by GopherJS, or +// "-tags safe" is added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +//go:build js || appengine || safe || disableunsafe || !go1.4 +// +build js appengine safe disableunsafe !go1.4 + +package spew + +import "reflect" + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = true +) + +// unsafeReflectValue typically converts the passed reflect.Value into a one +// that bypasses the typical safety restrictions preventing access to +// unaddressable and unexported data. However, doing this relies on access to +// the unsafe package. This is a stub version which simply returns the passed +// reflect.Value when the unsafe package is not available. +func unsafeReflectValue(v reflect.Value) reflect.Value { + return v +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/common.go b/vendor/github.com/stretchr/testify/internal/spew/common.go new file mode 100644 index 00000000000..1be8ce94576 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/common.go @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "reflect" + "sort" + "strconv" +) + +// Some constants in the form of bytes to avoid string overhead. This mirrors +// the technique used in the fmt package. +var ( + panicBytes = []byte("(PANIC=") + plusBytes = []byte("+") + iBytes = []byte("i") + trueBytes = []byte("true") + falseBytes = []byte("false") + interfaceBytes = []byte("(interface {})") + commaNewlineBytes = []byte(",\n") + newlineBytes = []byte("\n") + openBraceBytes = []byte("{") + openBraceNewlineBytes = []byte("{\n") + closeBraceBytes = []byte("}") + asteriskBytes = []byte("*") + colonBytes = []byte(":") + colonSpaceBytes = []byte(": ") + openParenBytes = []byte("(") + closeParenBytes = []byte(")") + spaceBytes = []byte(" ") + pointerChainBytes = []byte("->") + nilAngleBytes = []byte("") + maxNewlineBytes = []byte("\n") + maxShortBytes = []byte("") + circularBytes = []byte("") + circularShortBytes = []byte("") + invalidAngleBytes = []byte("") + openBracketBytes = []byte("[") + closeBracketBytes = []byte("]") + percentBytes = []byte("%") + precisionBytes = []byte(".") + openAngleBytes = []byte("<") + closeAngleBytes = []byte(">") + openMapBytes = []byte("map[") + closeMapBytes = []byte("]") + lenEqualsBytes = []byte("len=") + capEqualsBytes = []byte("cap=") +) + +// hexDigits is used to map a decimal value to a hex digit. +var hexDigits = "0123456789abcdef" + +// catchPanic handles any panics that might occur during the handleMethods +// calls. +func catchPanic(w io.Writer, v reflect.Value) { + if err := recover(); err != nil { + w.Write(panicBytes) + fmt.Fprintf(w, "%v", err) + w.Write(closeParenBytes) + } +} + +// handleMethods attempts to call the Error and String methods on the underlying +// type the passed reflect.Value represents and outputes the result to Writer w. +// +// It handles panics in any called methods by catching and displaying the error +// as the formatted value. +func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { + // We need an interface to check if the type implements the error or + // Stringer interface. However, the reflect package won't give us an + // interface on certain things like unexported struct fields in order + // to enforce visibility rules. We use unsafe, when it's available, + // to bypass these restrictions since this package does not mutate the + // values. + if !v.CanInterface() { + if UnsafeDisabled { + return false + } + + v = unsafeReflectValue(v) + } + + // Choose whether or not to do error and Stringer interface lookups against + // the base type or a pointer to the base type depending on settings. + // Technically calling one of these methods with a pointer receiver can + // mutate the value, however, types which choose to satisify an error or + // Stringer interface with a pointer receiver should not be mutating their + // state inside these interface methods. + if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { + v = unsafeReflectValue(v) + } + if v.CanAddr() { + v = v.Addr() + } + + // Is it an error or Stringer? + switch iface := v.Interface().(type) { + case error: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.Error())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + + w.Write([]byte(iface.Error())) + return true + + case fmt.Stringer: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.String())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + w.Write([]byte(iface.String())) + return true + } + return false +} + +// printBool outputs a boolean value as true or false to Writer w. +func printBool(w io.Writer, val bool) { + if val { + w.Write(trueBytes) + } else { + w.Write(falseBytes) + } +} + +// printInt outputs a signed integer value to Writer w. +func printInt(w io.Writer, val int64, base int) { + w.Write([]byte(strconv.FormatInt(val, base))) +} + +// printUint outputs an unsigned integer value to Writer w. +func printUint(w io.Writer, val uint64, base int) { + w.Write([]byte(strconv.FormatUint(val, base))) +} + +// printFloat outputs a floating point value using the specified precision, +// which is expected to be 32 or 64bit, to Writer w. +func printFloat(w io.Writer, val float64, precision int) { + w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) +} + +// printComplex outputs a complex value using the specified float precision +// for the real and imaginary parts to Writer w. +func printComplex(w io.Writer, c complex128, floatPrecision int) { + r := real(c) + w.Write(openParenBytes) + w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) + i := imag(c) + if i >= 0 { + w.Write(plusBytes) + } + w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) + w.Write(iBytes) + w.Write(closeParenBytes) +} + +// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' +// prefix to Writer w. +func printHexPtr(w io.Writer, p uintptr) { + // Null pointer. + num := uint64(p) + if num == 0 { + w.Write(nilAngleBytes) + return + } + + // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix + buf := make([]byte, 18) + + // It's simpler to construct the hex string right to left. + base := uint64(16) + i := len(buf) - 1 + for num >= base { + buf[i] = hexDigits[num%base] + num /= base + i-- + } + buf[i] = hexDigits[num] + + // Add '0x' prefix. + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + + // Strip unused leading bytes. + buf = buf[i:] + w.Write(buf) +} + +// valuesSorter implements sort.Interface to allow a slice of reflect.Value +// elements to be sorted. +type valuesSorter struct { + values []reflect.Value + strings []string // either nil or same len and values + cs *ConfigState +} + +// newValuesSorter initializes a valuesSorter instance, which holds a set of +// surrogate keys on which the data should be sorted. It uses flags in +// ConfigState to decide if and how to populate those surrogate keys. +func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { + vs := &valuesSorter{values: values, cs: cs} + if canSortSimply(vs.values[0].Kind()) { + return vs + } + if !cs.DisableMethods { + vs.strings = make([]string, len(values)) + for i := range vs.values { + b := bytes.Buffer{} + if !handleMethods(cs, &b, vs.values[i]) { + vs.strings = nil + break + } + vs.strings[i] = b.String() + } + } + if vs.strings == nil && cs.SpewKeys { + vs.strings = make([]string, len(values)) + for i := range vs.values { + vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) + } + } + return vs +} + +// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted +// directly, or whether it should be considered for sorting by surrogate keys +// (if the ConfigState allows it). +func canSortSimply(kind reflect.Kind) bool { + // This switch parallels valueSortLess, except for the default case. + switch kind { + case reflect.Bool: + return true + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return true + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.String: + return true + case reflect.Uintptr: + return true + case reflect.Array: + return true + } + return false +} + +// Len returns the number of values in the slice. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Len() int { + return len(s.values) +} + +// Swap swaps the values at the passed indices. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Swap(i, j int) { + s.values[i], s.values[j] = s.values[j], s.values[i] + if s.strings != nil { + s.strings[i], s.strings[j] = s.strings[j], s.strings[i] + } +} + +// valueSortLess returns whether the first value should sort before the second +// value. It is used by valueSorter.Less as part of the sort.Interface +// implementation. +func valueSortLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Bool: + return !a.Bool() && b.Bool() + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return a.Int() < b.Int() + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return a.Uint() < b.Uint() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.String: + return a.String() < b.String() + case reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Array: + // Compare the contents of both arrays. + l := a.Len() + for i := 0; i < l; i++ { + av := a.Index(i) + bv := b.Index(i) + if av.Interface() == bv.Interface() { + continue + } + return valueSortLess(av, bv) + } + } + return a.String() < b.String() +} + +// Less returns whether the value at index i should sort before the +// value at index j. It is part of the sort.Interface implementation. +func (s *valuesSorter) Less(i, j int) bool { + if s.strings == nil { + return valueSortLess(s.values[i], s.values[j]) + } + return s.strings[i] < s.strings[j] +} + +// sortValues is a sort function that handles both native types and any type that +// can be converted to error or Stringer. Other inputs are sorted according to +// their Value.String() value to ensure display stability. +func sortValues(values []reflect.Value, cs *ConfigState) { + if len(values) == 0 { + return + } + sort.Sort(newValuesSorter(values, cs)) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/config.go b/vendor/github.com/stretchr/testify/internal/spew/config.go new file mode 100644 index 00000000000..161895fc6db --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/config.go @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "os" +) + +// ConfigState houses the configuration options used by spew to format and +// display values. There is a global instance, Config, that is used to control +// all top-level Formatter and Dump functionality. Each ConfigState instance +// provides methods equivalent to the top-level functions. +// +// The zero value for ConfigState provides no indentation. You would typically +// want to set it to a space or a tab. +// +// Alternatively, you can use NewDefaultConfig to get a ConfigState instance +// with default settings. See the documentation of NewDefaultConfig for default +// values. +type ConfigState struct { + // Indent specifies the string to use for each indentation level. The + // global config instance that all top-level functions use set this to a + // single space by default. If you would like more indentation, you might + // set this to a tab with "\t" or perhaps two spaces with " ". + Indent string + + // MaxDepth controls the maximum number of levels to descend into nested + // data structures. The default, 0, means there is no limit. + // + // NOTE: Circular data structures are properly detected, so it is not + // necessary to set this value unless you specifically want to limit deeply + // nested data structures. + MaxDepth int + + // DisableMethods specifies whether or not error and Stringer interfaces are + // invoked for types that implement them. + DisableMethods bool + + // DisablePointerMethods specifies whether or not to check for and invoke + // error and Stringer interfaces on types which only accept a pointer + // receiver when the current type is not a pointer. + // + // NOTE: This might be an unsafe action since calling one of these methods + // with a pointer receiver could technically mutate the value, however, + // in practice, types which choose to satisify an error or Stringer + // interface with a pointer receiver should not be mutating their state + // inside these interface methods. As a result, this option relies on + // access to the unsafe package, so it will not have any effect when + // running in environments without access to the unsafe package such as + // Google App Engine or with the "safe" build tag specified. + DisablePointerMethods bool + + // DisablePointerAddresses specifies whether to disable the printing of + // pointer addresses. This is useful when diffing data structures in tests. + DisablePointerAddresses bool + + // DisableCapacities specifies whether to disable the printing of capacities + // for arrays, slices, maps and channels. This is useful when diffing + // data structures in tests. + DisableCapacities bool + + // ContinueOnMethod specifies whether or not recursion should continue once + // a custom error or Stringer interface is invoked. The default, false, + // means it will print the results of invoking the custom error or Stringer + // interface and return immediately instead of continuing to recurse into + // the internals of the data type. + // + // NOTE: This flag does not have any effect if method invocation is disabled + // via the DisableMethods or DisablePointerMethods options. + ContinueOnMethod bool + + // SortKeys specifies map keys should be sorted before being printed. Use + // this to have a more deterministic, diffable output. Note that only + // native types (bool, int, uint, floats, uintptr and string) and types + // that support the error or Stringer interfaces (if methods are + // enabled) are supported, with other types sorted according to the + // reflect.Value.String() output which guarantees display stability. + SortKeys bool + + // SpewKeys specifies that, as a last resort attempt, map keys should + // be spewed to strings and sorted by those strings. This is only + // considered if SortKeys is true. + SpewKeys bool +} + +// Config is the active configuration of the top-level functions. +// The configuration can be changed by modifying the contents of spew.Config. +var Config = ConfigState{Indent: " "} + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the formatted string as a value that satisfies error. See NewFormatter +// for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, c.convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, c.convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, c.convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a Formatter interface returned by c.NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, c.convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Print(a ...interface{}) (n int, err error) { + return fmt.Print(c.convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, c.convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Println(a ...interface{}) (n int, err error) { + return fmt.Println(c.convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprint(a ...interface{}) string { + return fmt.Sprint(c.convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, c.convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a Formatter interface returned by c.NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintln(a ...interface{}) string { + return fmt.Sprintln(c.convertArgs(a)...) +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +c.Printf, c.Println, or c.Printf. +*/ +func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(c, v) +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { + fdump(c, w, a...) +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by modifying the public members +of c. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func (c *ConfigState) Dump(a ...interface{}) { + fdump(c, os.Stdout, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func (c *ConfigState) Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(c, &buf, a...) + return buf.String() +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a spew Formatter interface using +// the ConfigState associated with s. +func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = newFormatter(c, arg) + } + return formatters +} + +// NewDefaultConfig returns a ConfigState with the following default settings. +// +// Indent: " " +// MaxDepth: 0 +// DisableMethods: false +// DisablePointerMethods: false +// ContinueOnMethod: false +// SortKeys: false +func NewDefaultConfig() *ConfigState { + return &ConfigState{Indent: " "} +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/doc.go b/vendor/github.com/stretchr/testify/internal/spew/doc.go new file mode 100644 index 00000000000..722e9aa7912 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/doc.go @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +Package spew implements a deep pretty printer for Go data structures to aid in +debugging. + +A quick overview of the additional features spew provides over the built-in +printing facilities for Go data types are as follows: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output (only when using + Dump style) + +There are two different approaches spew allows for dumping Go data structures: + + - Dump style which prints with newlines, customizable indentation, + and additional debug information such as types and all pointer addresses + used to indirect to the final value + - A custom Formatter interface that integrates cleanly with the standard fmt + package and replaces %v, %+v, %#v, and %#+v to provide inline printing + similar to the default %v while providing the additional functionality + outlined above and passing unsupported format verbs such as %x and %q + along to fmt + +# Quick Start + +This section demonstrates how to quickly get started with spew. See the +sections below for further details on formatting and configuration options. + +To dump a variable with full newlines, indentation, type, and pointer +information use Dump, Fdump, or Sdump: + + spew.Dump(myVar1, myVar2, ...) + spew.Fdump(someWriter, myVar1, myVar2, ...) + str := spew.Sdump(myVar1, myVar2, ...) + +Alternatively, if you would prefer to use format strings with a compacted inline +printing style, use the convenience wrappers Printf, Fprintf, etc with +%v (most compact), %+v (adds pointer addresses), %#v (adds types), or +%#+v (adds types and pointer addresses): + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +# Configuration Options + +Configuration of spew is handled by fields in the ConfigState type. For +convenience, all of the top-level functions use a global state available +via the spew.Config global. + +It is also possible to create a ConfigState instance that provides methods +equivalent to the top-level functions. This allows concurrent configuration +options. See the ConfigState documentation for more details. + +The following configuration options are available: + + - Indent + String to use for each indentation level for Dump functions. + It is a single space by default. A popular alternative is "\t". + + - MaxDepth + Maximum number of levels to descend into nested data structures. + There is no limit by default. + + - DisableMethods + Disables invocation of error and Stringer interface methods. + Method invocation is enabled by default. + + - DisablePointerMethods + Disables invocation of error and Stringer interface methods on types + which only accept pointer receivers from non-pointer variables. + Pointer method invocation is enabled by default. + + - DisablePointerAddresses + DisablePointerAddresses specifies whether to disable the printing of + pointer addresses. This is useful when diffing data structures in tests. + + - DisableCapacities + DisableCapacities specifies whether to disable the printing of + capacities for arrays, slices, maps and channels. This is useful when + diffing data structures in tests. + + - ContinueOnMethod + Enables recursion into types after invoking error and Stringer interface + methods. Recursion after method invocation is disabled by default. + + - SortKeys + Specifies map keys should be sorted before being printed. Use + this to have a more deterministic, diffable output. Note that + only native types (bool, int, uint, floats, uintptr and string) + and types which implement error or Stringer interfaces are + supported with other types sorted according to the + reflect.Value.String() output which guarantees display + stability. Natural map order is used by default. + + - SpewKeys + Specifies that, as a last resort attempt, map keys should be + spewed to strings and sorted by those strings. This is only + considered if SortKeys is true. + +# Dump Usage + +Simply call spew.Dump with a list of variables you want to dump: + + spew.Dump(myVar1, myVar2, ...) + +You may also call spew.Fdump if you would prefer to output to an arbitrary +io.Writer. For example, to dump to standard error: + + spew.Fdump(os.Stderr, myVar1, myVar2, ...) + +A third option is to call spew.Sdump to get the formatted output as a string: + + str := spew.Sdump(myVar1, myVar2, ...) + +# Sample Dump Output + +See the Dump example for details on the setup of the types and variables being +shown here. + + (main.Foo) { + unexportedField: (*main.Bar)(0xf84002e210)({ + flag: (main.Flag) flagTwo, + data: (uintptr) + }), + ExportedField: (map[interface {}]interface {}) (len=1) { + (string) (len=3) "one": (bool) true + } + } + +Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C +command as shown. + + ([]uint8) (len=32 cap=32) { + 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | + 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| + 00000020 31 32 |12| + } + +# Custom Formatter + +Spew provides a custom formatter that implements the fmt.Formatter interface +so that it integrates cleanly with standard fmt package printing functions. The +formatter is useful for inline printing of smaller data types similar to the +standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +# Custom Formatter Usage + +The simplest way to make use of the spew custom formatter is to call one of the +convenience functions such as spew.Printf, spew.Println, or spew.Printf. The +functions have syntax you are most likely already familiar with: + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Println(myVar, myVar2) + spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +See the Index for the full list convenience functions. + +# Sample Formatter Output + +Double pointer to a uint8: + + %v: <**>5 + %+v: <**>(0xf8400420d0->0xf8400420c8)5 + %#v: (**uint8)5 + %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 + +Pointer to circular struct with a uint8 field and a pointer to itself: + + %v: <*>{1 <*>} + %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} + %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} + %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} + +See the Printf example for details on the setup of variables being shown +here. + +# Errors + +Since it is possible for custom Stringer/error interfaces to panic, spew +detects them and handles them internally by printing the panic information +inline with the output. Since spew is intended to provide deep pretty printing +capabilities on structures, it intentionally does not return any errors. +*/ +package spew diff --git a/vendor/github.com/stretchr/testify/internal/spew/dump.go b/vendor/github.com/stretchr/testify/internal/spew/dump.go new file mode 100644 index 00000000000..8323041a481 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/dump.go @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "encoding/hex" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + // uint8Type is a reflect.Type representing a uint8. It is used to + // convert cgo types to uint8 slices for hexdumping. + uint8Type = reflect.TypeOf(uint8(0)) + + // cCharRE is a regular expression that matches a cgo char. + // It is used to detect character arrays to hexdump them. + cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) + + // cUnsignedCharRE is a regular expression that matches a cgo unsigned + // char. It is used to detect unsigned character arrays to hexdump + // them. + cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) + + // cUint8tCharRE is a regular expression that matches a cgo uint8_t. + // It is used to detect uint8_t arrays to hexdump them. + cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) +) + +// dumpState contains information about the state of a dump operation. +type dumpState struct { + w io.Writer + depth int + pointers map[uintptr]int + ignoreNextType bool + ignoreNextIndent bool + cs *ConfigState +} + +// indent performs indentation according to the depth level and cs.Indent +// option. +func (d *dumpState) indent() { + if d.ignoreNextIndent { + d.ignoreNextIndent = false + return + } + d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) +} + +// unpackValue returns values inside of non-nil interfaces when possible. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface && !v.IsNil() { + v = v.Elem() + } + return v +} + +// dumpPtr handles formatting of pointers by indirecting them as necessary. +func (d *dumpState) dumpPtr(v reflect.Value) { + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range d.pointers { + if depth >= d.depth { + delete(d.pointers, k) + } + } + + // Keep list of all dereferenced pointers to show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by dereferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := d.pointers[addr]; ok && pd < d.depth { + cycleFound = true + indirects-- + break + } + d.pointers[addr] = d.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type information. + d.w.Write(openParenBytes) + d.w.Write(bytes.Repeat(asteriskBytes, indirects)) + d.w.Write([]byte(ve.Type().String())) + d.w.Write(closeParenBytes) + + // Display pointer information. + if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { + d.w.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + d.w.Write(pointerChainBytes) + } + printHexPtr(d.w, addr) + } + d.w.Write(closeParenBytes) + } + + // Display dereferenced value. + d.w.Write(openParenBytes) + switch { + case nilFound: + d.w.Write(nilAngleBytes) + + case cycleFound: + d.w.Write(circularBytes) + + default: + d.ignoreNextType = true + d.dump(ve) + } + d.w.Write(closeParenBytes) +} + +// dumpSlice handles formatting of arrays and slices. Byte (uint8 under +// reflection) arrays and slices are dumped in hexdump -C fashion. +func (d *dumpState) dumpSlice(v reflect.Value) { + // Determine whether this type should be hex dumped or not. Also, + // for types which should be hexdumped, try to use the underlying data + // first, then fall back to trying to convert them to a uint8 slice. + var buf []uint8 + doConvert := false + doHexDump := false + numEntries := v.Len() + if numEntries > 0 { + vt := v.Index(0).Type() + vts := vt.String() + switch { + // C types that need to be converted. + case cCharRE.MatchString(vts): + fallthrough + case cUnsignedCharRE.MatchString(vts): + fallthrough + case cUint8tCharRE.MatchString(vts): + doConvert = true + + // Try to use existing uint8 slices and fall back to converting + // and copying if that fails. + case vt.Kind() == reflect.Uint8: + // We need an addressable interface to convert the type + // to a byte slice. However, the reflect package won't + // give us an interface on certain things like + // unexported struct fields in order to enforce + // visibility rules. We use unsafe, when available, to + // bypass these restrictions since this package does not + // mutate the values. + vs := v + if !vs.CanInterface() || !vs.CanAddr() { + vs = unsafeReflectValue(vs) + } + if !UnsafeDisabled { + vs = vs.Slice(0, numEntries) + + // Use the existing uint8 slice if it can be + // type asserted. + iface := vs.Interface() + if slice, ok := iface.([]uint8); ok { + buf = slice + doHexDump = true + break + } + } + + // The underlying data needs to be converted if it can't + // be type asserted to a uint8 slice. + doConvert = true + } + + // Copy and convert the underlying type if needed. + if doConvert && vt.ConvertibleTo(uint8Type) { + // Convert and copy each element into a uint8 byte + // slice. + buf = make([]uint8, numEntries) + for i := 0; i < numEntries; i++ { + vv := v.Index(i) + buf[i] = uint8(vv.Convert(uint8Type).Uint()) + } + doHexDump = true + } + } + + // Hexdump the entire slice as needed. + if doHexDump { + indent := strings.Repeat(d.cs.Indent, d.depth) + str := indent + hex.Dump(buf) + str = strings.Replace(str, "\n", "\n"+indent, -1) + str = strings.TrimRight(str, d.cs.Indent) + d.w.Write([]byte(str)) + return + } + + // Recursively call dump for each item. + for i := 0; i < numEntries; i++ { + d.dump(d.unpackValue(v.Index(i))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } +} + +// dump is the main workhorse for dumping a value. It uses the passed reflect +// value to figure out what kind of object we are dealing with and formats it +// appropriately. It is a recursive function, however circular data structures +// are detected and handled properly. +func (d *dumpState) dump(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + d.w.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + d.indent() + d.dumpPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !d.ignoreNextType { + d.indent() + d.w.Write(openParenBytes) + d.w.Write([]byte(v.Type().String())) + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + d.ignoreNextType = false + + // Display length and capacity if the built-in len and cap functions + // work with the value's kind and the len/cap itself is non-zero. + valueLen, valueCap := 0, 0 + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Chan: + valueLen, valueCap = v.Len(), v.Cap() + case reflect.Map, reflect.String: + valueLen = v.Len() + } + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { + d.w.Write(openParenBytes) + if valueLen != 0 { + d.w.Write(lenEqualsBytes) + printInt(d.w, int64(valueLen), 10) + } + if !d.cs.DisableCapacities && valueCap != 0 { + if valueLen != 0 { + d.w.Write(spaceBytes) + } + d.w.Write(capEqualsBytes) + printInt(d.w, int64(valueCap), 10) + } + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + + // Call Stringer/error interfaces if they exist and the handle methods flag + // is enabled + if !d.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(d.cs, d.w, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(d.w, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(d.w, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(d.w, v.Uint(), 10) + + case reflect.Float32: + printFloat(d.w, v.Float(), 32) + + case reflect.Float64: + printFloat(d.w, v.Float(), 64) + + case reflect.Complex64: + printComplex(d.w, v.Complex(), 32) + + case reflect.Complex128: + printComplex(d.w, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + d.dumpSlice(v) + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.String: + d.w.Write([]byte(strconv.Quote(v.String()))) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + d.w.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + numEntries := v.Len() + keys := v.MapKeys() + if d.cs.SortKeys { + sortValues(keys, d.cs) + } + for i, key := range keys { + d.dump(d.unpackValue(key)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.MapIndex(key))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Struct: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + vt := v.Type() + numFields := v.NumField() + for i := 0; i < numFields; i++ { + d.indent() + vtf := vt.Field(i) + d.w.Write([]byte(vtf.Name)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.Field(i))) + if i < (numFields - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(d.w, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(d.w, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it in case any new + // types are added. + default: + if v.CanInterface() { + fmt.Fprintf(d.w, "%v", v.Interface()) + } else { + fmt.Fprintf(d.w, "%v", v.String()) + } + } +} + +// fdump is a helper function to consolidate the logic from the various public +// methods which take varying writers and config states. +func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { + for _, arg := range a { + if arg == nil { + w.Write(interfaceBytes) + w.Write(spaceBytes) + w.Write(nilAngleBytes) + w.Write(newlineBytes) + continue + } + + d := dumpState{w: w, cs: cs} + d.pointers = make(map[uintptr]int) + d.dump(reflect.ValueOf(arg)) + d.w.Write(newlineBytes) + } +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func Fdump(w io.Writer, a ...interface{}) { + fdump(&Config, w, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(&Config, &buf, a...) + return buf.String() +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by an exported package global, +spew.Config. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func Dump(a ...interface{}) { + fdump(&Config, os.Stdout, a...) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/format.go b/vendor/github.com/stretchr/testify/internal/spew/format.go new file mode 100644 index 00000000000..b04edb7d7ac --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/format.go @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + "strings" +) + +// supportedFlags is a list of all the character flags supported by fmt package. +const supportedFlags = "0-+# " + +// formatState implements the fmt.Formatter interface and contains information +// about the state of a formatting operation. The NewFormatter function can +// be used to get a new Formatter which can be used directly as arguments +// in standard fmt package printing calls. +type formatState struct { + value interface{} + fs fmt.State + depth int + pointers map[uintptr]int + ignoreNextType bool + cs *ConfigState +} + +// buildDefaultFormat recreates the original format string without precision +// and width information to pass in to fmt.Sprintf in the case of an +// unrecognized type. Unless new types are added to the language, this +// function won't ever be called. +func (f *formatState) buildDefaultFormat() (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + buf.WriteRune('v') + + format = buf.String() + return format +} + +// constructOrigFormat recreates the original format string including precision +// and width information to pass along to the standard fmt package. This allows +// automatic deferral of all format strings this package doesn't support. +func (f *formatState) constructOrigFormat(verb rune) (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + if width, ok := f.fs.Width(); ok { + buf.WriteString(strconv.Itoa(width)) + } + + if precision, ok := f.fs.Precision(); ok { + buf.Write(precisionBytes) + buf.WriteString(strconv.Itoa(precision)) + } + + buf.WriteRune(verb) + + format = buf.String() + return format +} + +// unpackValue returns values inside of non-nil interfaces when possible and +// ensures that types for values which have been unpacked from an interface +// are displayed when the show types flag is also set. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (f *formatState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface { + f.ignoreNextType = false + if !v.IsNil() { + v = v.Elem() + } + } + return v +} + +// formatPtr handles formatting of pointers by indirecting them as necessary. +func (f *formatState) formatPtr(v reflect.Value) { + // Display nil if top level pointer is nil. + showTypes := f.fs.Flag('#') + if v.IsNil() && (!showTypes || f.ignoreNextType) { + f.fs.Write(nilAngleBytes) + return + } + + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range f.pointers { + if depth >= f.depth { + delete(f.pointers, k) + } + } + + // Keep list of all dereferenced pointers to possibly show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by derferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := f.pointers[addr]; ok && pd < f.depth { + cycleFound = true + indirects-- + break + } + f.pointers[addr] = f.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type or indirection level depending on flags. + if showTypes && !f.ignoreNextType { + f.fs.Write(openParenBytes) + f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) + f.fs.Write([]byte(ve.Type().String())) + f.fs.Write(closeParenBytes) + } else { + if nilFound || cycleFound { + indirects += strings.Count(ve.Type().String(), "*") + } + f.fs.Write(openAngleBytes) + f.fs.Write([]byte(strings.Repeat("*", indirects))) + f.fs.Write(closeAngleBytes) + } + + // Display pointer information depending on flags. + if f.fs.Flag('+') && (len(pointerChain) > 0) { + f.fs.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + f.fs.Write(pointerChainBytes) + } + printHexPtr(f.fs, addr) + } + f.fs.Write(closeParenBytes) + } + + // Display dereferenced value. + switch { + case nilFound: + f.fs.Write(nilAngleBytes) + + case cycleFound: + f.fs.Write(circularShortBytes) + + default: + f.ignoreNextType = true + f.format(ve) + } +} + +// format is the main workhorse for providing the Formatter interface. It +// uses the passed reflect value to figure out what kind of object we are +// dealing with and formats it appropriately. It is a recursive function, +// however circular data structures are detected and handled properly. +func (f *formatState) format(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + f.fs.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + f.formatPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !f.ignoreNextType && f.fs.Flag('#') { + f.fs.Write(openParenBytes) + f.fs.Write([]byte(v.Type().String())) + f.fs.Write(closeParenBytes) + } + f.ignoreNextType = false + + // Call Stringer/error interfaces if they exist and the handle methods + // flag is enabled. + if !f.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(f.cs, f.fs, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(f.fs, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(f.fs, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(f.fs, v.Uint(), 10) + + case reflect.Float32: + printFloat(f.fs, v.Float(), 32) + + case reflect.Float64: + printFloat(f.fs, v.Float(), 64) + + case reflect.Complex64: + printComplex(f.fs, v.Complex(), 32) + + case reflect.Complex128: + printComplex(f.fs, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + f.fs.Write(openBracketBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + numEntries := v.Len() + for i := 0; i < numEntries; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(v.Index(i))) + } + } + f.depth-- + f.fs.Write(closeBracketBytes) + + case reflect.String: + f.fs.Write([]byte(v.String())) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + f.fs.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + + f.fs.Write(openMapBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + keys := v.MapKeys() + if f.cs.SortKeys { + sortValues(keys, f.cs) + } + for i, key := range keys { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(key)) + f.fs.Write(colonBytes) + f.ignoreNextType = true + f.format(f.unpackValue(v.MapIndex(key))) + } + } + f.depth-- + f.fs.Write(closeMapBytes) + + case reflect.Struct: + numFields := v.NumField() + f.fs.Write(openBraceBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + vt := v.Type() + for i := 0; i < numFields; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + vtf := vt.Field(i) + if f.fs.Flag('+') || f.fs.Flag('#') { + f.fs.Write([]byte(vtf.Name)) + f.fs.Write(colonBytes) + } + f.format(f.unpackValue(v.Field(i))) + } + } + f.depth-- + f.fs.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(f.fs, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(f.fs, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it if any get added. + default: + format := f.buildDefaultFormat() + if v.CanInterface() { + fmt.Fprintf(f.fs, format, v.Interface()) + } else { + fmt.Fprintf(f.fs, format, v.String()) + } + } +} + +// Format satisfies the fmt.Formatter interface. See NewFormatter for usage +// details. +func (f *formatState) Format(fs fmt.State, verb rune) { + f.fs = fs + + // Use standard formatting for verbs that are not v. + if verb != 'v' { + format := f.constructOrigFormat(verb) + fmt.Fprintf(fs, format, f.value) + return + } + + if f.value == nil { + if fs.Flag('#') { + fs.Write(interfaceBytes) + } + fs.Write(nilAngleBytes) + return + } + + f.format(reflect.ValueOf(f.value)) +} + +// newFormatter is a helper function to consolidate the logic from the various +// public methods which take varying config states. +func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { + fs := &formatState{value: v, cs: cs} + fs.pointers = make(map[uintptr]int) + return fs +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +Printf, Println, or Fprintf. +*/ +func NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(&Config, v) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/spew.go b/vendor/github.com/stretchr/testify/internal/spew/spew.go new file mode 100644 index 00000000000..32c0e338825 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/spew.go @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "fmt" + "io" +) + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the formatted string as a value that satisfies error. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a default Formatter interface returned by NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) +func Print(a ...interface{}) (n int, err error) { + return fmt.Print(convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) +func Println(a ...interface{}) (n int, err error) { + return fmt.Println(convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprint(a ...interface{}) string { + return fmt.Sprint(convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintln(a ...interface{}) string { + return fmt.Sprintln(convertArgs(a)...) +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a default spew Formatter interface. +func convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = NewFormatter(arg) + } + return formatters +} diff --git a/vendor/github.com/stretchr/testify/mock/mock.go b/vendor/github.com/stretchr/testify/mock/mock.go index efc89deff38..7f4d28d5ee6 100644 --- a/vendor/github.com/stretchr/testify/mock/mock.go +++ b/vendor/github.com/stretchr/testify/mock/mock.go @@ -11,11 +11,11 @@ import ( "sync" "time" - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" "github.com/stretchr/objx" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/internal/difflib" + "github.com/stretchr/testify/internal/spew" ) // regex for GCCGO functions @@ -470,7 +470,7 @@ func callString(method string, arguments Arguments, includeArgumentValues bool) // Called tells the mock object that a method has been called, and gets an array // of arguments to return. Panics if the call is unexpected (i.e. not preceded by -// appropriate .On .Return() calls) +// appropriate [Mock.On] calls) // If Call.WaitFor is set, blocks until the channel is closed or receives a message. func (m *Mock) Called(arguments ...interface{}) Arguments { // get the calling function's name @@ -493,7 +493,7 @@ func (m *Mock) Called(arguments ...interface{}) Arguments { // MethodCalled tells the mock object that the given method has been called, and gets // an array of arguments to return. Panics if the call is unexpected (i.e. not preceded -// by appropriate .On .Return() calls) +// by appropriate [Mock.On] calls) // If Call.WaitFor is set, blocks until the channel is closed or receives a message. func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments { m.mutex.Lock() @@ -510,8 +510,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen // as the return arguments. This is because: // // a) this is a totally unexpected call to this method, - // b) the arguments are not what was expected, or - // c) the developer has forgotten to add an accompanying On...Return pair. + // b) the arguments are not what was expected closestCall, mismatch := m.findClosestCall(methodName, arguments...) m.mutex.Unlock() @@ -595,7 +594,7 @@ type assertExpectationiser interface { AssertExpectations(TestingT) bool } -// AssertExpectationsForObjects asserts that everything specified with On and Return +// AssertExpectationsForObjects asserts that everything specified with [Mock.On] // of the specified objects was in fact called as expected. // // Calls may have occurred in any order. @@ -604,11 +603,12 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { h.Helper() } for _, obj := range testObjects { - if m, ok := obj.(*Mock); ok { - t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)") - obj = m + m, ok := obj.(assertExpectationiser) + if !ok { + t.Errorf("Invalid test object type %T. Expected reference to a mock.Mock, eg: 'AssertExpectationsForObjects(t, myMock)' or 'AssertExpectationsForObjects(t, &myMock.Mock)'", obj) + continue + } - m := obj.(assertExpectationiser) if !m.AssertExpectations(t) { t.Logf("Expectations didn't match for Mock: %+v", reflect.TypeOf(m)) return false @@ -617,7 +617,7 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { return true } -// AssertExpectations asserts that everything specified with On and Return was +// AssertExpectations asserts that everything specified with [Mock.On] was // in fact called as expected. Calls may have occurred in any order. func (m *Mock) AssertExpectations(t TestingT) bool { if s, ok := t.(interface{ Skipped() bool }); ok && s.Skipped() { @@ -712,8 +712,8 @@ func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...inter return true } -// IsMethodCallable checking that the method can be called -// If the method was called more than `Repeatability` return false +// IsMethodCallable returns true if given methodName and arguments have an +// unsatisfied expected call registered in the Mock. func (m *Mock) IsMethodCallable(t TestingT, methodName string, arguments ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -833,6 +833,10 @@ type IsTypeArgument struct { // For example: // // args.Assert(t, IsType(""), IsType(0)) +// +// Mock cannot match interface types because the contained type will be passed +// to both IsType and Mock.Called, for the zero value of all interfaces this +// will be type. func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: reflect.TypeOf(t)} } @@ -1012,7 +1016,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { actualT := reflect.TypeOf(actual) if actualT != expected.t { differences++ - output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt) + output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, safeTypeName(expected.t), safeTypeName(actualT), actualFmt) } case *FunctionalOptionsArgument: var name string @@ -1141,6 +1145,15 @@ func (args Arguments) Bool(index int) bool { return s } +// safeTypeName returns the reflect.Type's name without causing a panic. +// If the provided reflect.Type is nil, it returns the placeholder string "" +func safeTypeName(t reflect.Type) string { + if t == nil { + return "" + } + return t.Name() +} + func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { t := reflect.TypeOf(v) k := t.Kind() diff --git a/vendor/github.com/stretchr/testify/require/doc.go b/vendor/github.com/stretchr/testify/require/doc.go index c8e3f94a803..ee84cc47916 100644 --- a/vendor/github.com/stretchr/testify/require/doc.go +++ b/vendor/github.com/stretchr/testify/require/doc.go @@ -1,4 +1,4 @@ -// Package require implements the same assertions as the `assert` package but +// Package require implements the same assertions as the assert package but // stops test execution when a test fails. // // # Example Usage @@ -21,8 +21,8 @@ // // # Assertions // -// The `require` package have same global functions as in the `assert` package, -// but instead of returning a boolean result they call `t.FailNow()`. +// The require package have same global functions as in the assert package, +// but instead of returning a boolean result they call [testing.T.FailNow]. // A consequence of this is that it must be called from the goroutine running // the test function, not from other goroutines created during the test. // diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go index 2d02f9bcef1..652871f2eb7 100644 --- a/vendor/github.com/stretchr/testify/require/require.go +++ b/vendor/github.com/stretchr/testify/require/require.go @@ -180,7 +180,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i t.FailNow() } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -195,7 +195,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte t.FailNow() } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -295,7 +295,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar t.FailNow() } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // require.Error(t, err) @@ -333,8 +333,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int t.FailNow() } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // require.ErrorContains(t, err, expectedErrorSubString) @@ -348,8 +348,8 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in t.FailNow() } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -387,7 +387,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface t.FailNow() } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // require.Errorf(t, err, "error message %s", "formatted") @@ -429,7 +429,7 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // time.Sleep(8*time.Second) // externalValue = true // }() -// require.EventuallyWithT(t, func(c *require.CollectT) { +// require.EventuallyWithT(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") @@ -457,10 +457,10 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF // time.Sleep(8*time.Second) // externalValue = true // }() -// require.EventuallyWithTf(t, func(c *require.CollectT, "error message %s", "formatted") { +// require.EventuallyWithTf(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // require.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -671,8 +671,6 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // body that contains a string. // // require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -687,8 +685,6 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // body that contains a string. // // require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -703,8 +699,6 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // body that does not contain a string. // // require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -719,8 +713,6 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // body that does not contain a string. // // require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -734,8 +726,6 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPError asserts that a specified handler returns an error status code. // // require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -749,8 +739,6 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPErrorf asserts that a specified handler returns an error status code. // // require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -764,8 +752,6 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirect asserts that a specified handler returns a redirect status code. // // require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -779,8 +765,6 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // HTTPRedirectf asserts that a specified handler returns a redirect status code. // // require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -794,8 +778,6 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCode asserts that a specified handler returns a specified status code. // // require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -809,8 +791,6 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // HTTPStatusCodef asserts that a specified handler returns a specified status code. // // require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -824,8 +804,6 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccess asserts that a specified handler returns a success status code. // // require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -839,8 +817,6 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // HTTPSuccessf asserts that a specified handler returns a success status code. // // require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1385,12 +1361,11 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { t.FailNow() } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if require.NoError(t, err) { -// require.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// require.NoError(t, err) +// require.Equal(t, expectedObj, actualObj) func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1401,12 +1376,11 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { t.FailNow() } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if require.NoErrorf(t, err, "error message %s", "formatted") { -// require.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// require.NoErrorf(t, err, "error message %s", "formatted") +// require.Equal(t, expectedObj, actualObj) func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1515,9 +1489,8 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str // NotEmpty asserts that the specified object is NOT [Empty]. // -// if require.NotEmpty(t, obj) { -// require.Equal(t, "two", obj[1]) -// } +// require.NotEmpty(t, obj) +// require.Equal(t, "two", obj[1]) func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1530,9 +1503,8 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT [Empty]. // -// if require.NotEmptyf(t, obj, "error message %s", "formatted") { -// require.Equal(t, "two", obj[1]) -// } +// require.NotEmptyf(t, obj, "error message %s", "formatted") +// require.Equal(t, "two", obj[1]) func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2135,7 +2107,19 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, t.FailNow() } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// require.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2146,7 +2130,19 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ t.FailNow() } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// require.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/require/require.go.tmpl b/vendor/github.com/stretchr/testify/require/require.go.tmpl index 8b328368509..6a975501ee7 100644 --- a/vendor/github.com/stretchr/testify/require/require.go.tmpl +++ b/vendor/github.com/stretchr/testify/require/require.go.tmpl @@ -1,4 +1,4 @@ -{{ replace .Comment "assert." "require."}} +{{.CommentRequire}} func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { if h, ok := t.(tHelper); ok { h.Helper() } if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go index e6f7e944684..edac147ef46 100644 --- a/vendor/github.com/stretchr/testify/require/require_forward.go +++ b/vendor/github.com/stretchr/testify/require/require_forward.go @@ -147,7 +147,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -159,7 +159,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -241,7 +241,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -270,8 +270,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -282,8 +282,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -312,7 +312,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -373,10 +373,10 @@ func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), w // time.Sleep(8*time.Second) // externalValue = true // }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// a.EventuallyWithTf(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -539,8 +539,6 @@ func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args . // body that contains a string. // // a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -552,8 +550,6 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u // body that contains a string. // // a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -565,8 +561,6 @@ func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, // body that does not contain a string. // // a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -578,8 +572,6 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string // body that does not contain a string. // // a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -590,8 +582,6 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin // HTTPError asserts that a specified handler returns an error status code. // // a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -602,8 +592,6 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri // HTTPErrorf asserts that a specified handler returns an error status code. // // a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -614,8 +602,6 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str // HTTPRedirect asserts that a specified handler returns a redirect status code. // // a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -626,8 +612,6 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s // HTTPRedirectf asserts that a specified handler returns a redirect status code. // // a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -638,8 +622,6 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url // HTTPStatusCode asserts that a specified handler returns a specified status code. // // a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -650,8 +632,6 @@ func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url // HTTPStatusCodef asserts that a specified handler returns a specified status code. // // a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -662,8 +642,6 @@ func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, ur // HTTPSuccess asserts that a specified handler returns a success status code. // // a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -674,8 +652,6 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // // a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1097,12 +1073,11 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// a.NoError(err) +// a.Equal(expectedObj, actualObj) func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1110,12 +1085,11 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// a.NoErrorf(err, "error message %s", "formatted") +// a.Equal(expectedObj, actualObj) func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1203,9 +1177,8 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg // NotEmpty asserts that the specified object is NOT [Empty]. // -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } +// a.NotEmpty(obj) +// a.Equal("two", obj[1]) func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1215,9 +1188,8 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT [Empty]. // -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// a.NotEmptyf(obj, "error message %s", "formatted") +// a.Equal("two", obj[1]) func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1691,7 +1663,19 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1699,7 +1683,19 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl b/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl index 54124df1d3b..b3b751de48a 100644 --- a/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl +++ b/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl @@ -1,4 +1,4 @@ -{{.CommentWithoutT "a"}} +{{.CommentRequireWithoutT "a"}} func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) { if h, ok := a.t.(tHelper); ok { h.Helper() } {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go index 6b7ce929eb1..375adb0a6ad 100644 --- a/vendor/github.com/stretchr/testify/require/requirements.go +++ b/vendor/github.com/stretchr/testify/require/requirements.go @@ -12,18 +12,18 @@ type tHelper = interface { // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful // for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) +type ComparisonAssertionFunc = func(TestingT, interface{}, interface{}, ...interface{}) // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful // for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) +type ValueAssertionFunc = func(TestingT, interface{}, ...interface{}) // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful // for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) +type BoolAssertionFunc = func(TestingT, bool, ...interface{}) // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful // for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) +type ErrorAssertionFunc = func(TestingT, error, ...interface{}) //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs" diff --git a/vendor/github.com/tinylib/msgp/msgp/json.go b/vendor/github.com/tinylib/msgp/msgp/json.go index 896d690ba09..49bd54bf124 100644 --- a/vendor/github.com/tinylib/msgp/msgp/json.go +++ b/vendor/github.com/tinylib/msgp/msgp/json.go @@ -131,11 +131,35 @@ func rwMap(dst jsWriter, src *Reader) (n int, err error) { n++ } - field, err = src.ReadMapKeyPtr() + var kt Type + kt, err = src.NextType() if err != nil { return } - nn, err = rwquoted(dst, field) + switch kt { + case IntType: + var i64 int64 + i64, err = src.ReadInt64() + if err != nil { + return + } + src.scratch = strconv.AppendInt(src.scratch[:0], i64, 10) + nn, err = rwquoted(dst, src.scratch) + case UintType: + var u64 uint64 + u64, err = src.ReadUint64() + if err != nil { + return + } + src.scratch = strconv.AppendUint(src.scratch[:0], u64, 10) + nn, err = rwquoted(dst, src.scratch) + default: + field, err = src.ReadMapKeyPtr() + if err != nil { + return + } + nn, err = rwquoted(dst, field) + } n += nn if err != nil { return diff --git a/vendor/github.com/tinylib/msgp/msgp/json_bytes.go b/vendor/github.com/tinylib/msgp/msgp/json_bytes.go index 7efd162f199..4aced1b16c3 100644 --- a/vendor/github.com/tinylib/msgp/msgp/json_bytes.go +++ b/vendor/github.com/tinylib/msgp/msgp/json_bytes.go @@ -144,6 +144,27 @@ func rwMapBytes(w jsWriter, msg []byte, scratch []byte, depth int) ([]byte, []by } func rwMapKeyBytes(w jsWriter, msg []byte, scratch []byte, depth int) ([]byte, []byte, error) { + if len(msg) < 1 { + return msg, scratch, ErrShortBytes + } + switch getType(msg[0]) { + case IntType: + i, msg, err := ReadInt64Bytes(msg) + if err != nil { + return msg, scratch, err + } + scratch = strconv.AppendInt(scratch[:0], i, 10) + _, err = rwquoted(w, scratch) + return msg, scratch, err + case UintType: + u, msg, err := ReadUint64Bytes(msg) + if err != nil { + return msg, scratch, err + } + scratch = strconv.AppendUint(scratch[:0], u, 10) + _, err = rwquoted(w, scratch) + return msg, scratch, err + } msg, scratch, err := rwStringBytes(w, msg, scratch, depth) if err != nil { if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType { diff --git a/vendor/github.com/tinylib/msgp/msgp/read.go b/vendor/github.com/tinylib/msgp/msgp/read.go index 264933ad0ef..b029e5740c7 100644 --- a/vendor/github.com/tinylib/msgp/msgp/read.go +++ b/vendor/github.com/tinylib/msgp/msgp/read.go @@ -121,6 +121,10 @@ func Decode(r io.Reader, d Decodable) error { // reader will be buffered. func NewReader(r io.Reader) *Reader { p := readerPool.Get().(*Reader) + p.recursionDepth = 0 + p.maxElements = 0 + p.maxRecursionDepth = 0 + p.maxStrLen = 0 if p.R == nil { p.R = fwd.NewReader(r) } else { @@ -1009,6 +1013,62 @@ func (m *Reader) ReadBytes(scratch []byte) (b []byte, err error) { return } +// ReadBytesLimit reads a MessagePack 'bin' object +// from the reader and returns its value. It may +// use 'scratch' for storage if it is non-nil. +// If n >= 0 this will be the maximum bytes read. +// If n < 0, the cap(scratch) will be the limit. +// If SetMaxElements has been used on the Reader, +// that will only be checked if the scratch is too small. +func (m *Reader) ReadBytesLimit(scratch []byte, n int64) (b []byte, err error) { + var p []byte + var lead byte + p, err = m.R.Peek(2) + if err != nil { + return + } + lead = p[0] + var read int64 + switch lead { + case mbin8: + read = int64(p[1]) + m.R.Skip(2) + case mbin16: + p, err = m.R.Next(3) + if err != nil { + return + } + read = int64(big.Uint16(p[1:])) + case mbin32: + p, err = m.R.Next(5) + if err != nil { + return + } + read = int64(big.Uint32(p[1:])) + default: + err = badPrefix(BinType, lead) + return + } + if n < 0 { + n = int64(cap(scratch)) + } + if read > n { + err = ErrLimitExceeded + return + } + if int64(cap(scratch)) < read { + b = make([]byte, read) + if read > int64(m.GetMaxElements()) { + err = ErrLimitExceeded + return + } + } else { + b = scratch[0:read] + } + _, err = m.R.ReadFull(b) + return +} + // ReadBytesHeader reads the size header // of a MessagePack 'bin' object. The user // is responsible for dealing with the next diff --git a/vendor/github.com/tjhop/slog-gokit/handler.go b/vendor/github.com/tjhop/slog-gokit/handler.go index 4743e301e0e..61d45d34fc5 100644 --- a/vendor/github.com/tjhop/slog-gokit/handler.go +++ b/vendor/github.com/tjhop/slog-gokit/handler.go @@ -4,6 +4,10 @@ import ( "context" "log/slog" "os" + "runtime" + "strconv" + "strings" + "sync" "github.com/go-kit/log" ) @@ -12,19 +16,32 @@ var _ slog.Handler = (*GoKitHandler)(nil) var defaultGoKitLogger = log.NewLogfmtLogger(os.Stderr) -// Pay boxing cost once at package init, save 2 heap escapes per Handle() call. +// Pay boxing cost once at package init, save 3 heap escapes per Handle() call. var ( - timeKey any = slog.TimeKey - msgKey any = slog.MessageKey + timeKey any = slog.TimeKey + msgKey any = slog.MessageKey + callerKey any = "caller" ) +// callerCache memoizes resolved caller strings keyed by record PC. A PC's +// file:line mapping is fixed for the process lifetime and log call sites are +// static, so the cache is write-once, read-many and bounded by the number of +// distinct call sites. +// +// Kubernetes's klog does something similar to cache per-call-site verbosity +// levels by PC (`vmap` in +// https://github.com/kubernetes/klog/blob/main/klog.go). +// +// Values are stored pre-boxed as `any` so cache hits append into the pairs +// slice with zero allocations, and no need to walk the call stack. +var callerCache sync.Map // map[uintptr]any, values are `file:line` strings. + // GoKitHandler implements the slog.Handler interface. It holds an internal // go-kit logger that is used to perform the true logging. type GoKitHandler struct { level slog.Leveler logger log.Logger - levelLoggers *levelLoggerCache // pre-built leveled loggers - preformatted []any // pre-flattened key-value pairs, ready to pass directly to logger.Log() + preformatted []any // pre-flattened key-value pairs, ready to pass directly to logger.Log() group string } @@ -32,23 +49,23 @@ type GoKitHandler struct { // logger. Calls to the slog logger are chained to the handler's internal // go-kit logger. If provided a level, it will be used to filter log events in // the handler's Enabled() method. +// +// The handler adds a `caller` key to each record, resolved from the program +// counter that slog captured at the log call site. Records handled directly +// (without going through an slog.Logger) have no PC set, and thus omit the +// caller. func NewGoKitHandler(logger log.Logger, level slog.Leveler) slog.Handler { if logger == nil { logger = defaultGoKitLogger } - // Adjust runtime call depth to compensate for the adapter and point to - // the appropriate source line. - logger = log.With(logger, "caller", log.Caller(6)) - if level == nil { level = &slog.LevelVar{} // Info level by default. } return &GoKitHandler{ - logger: logger, - level: level, - levelLoggers: newLevelCache(logger), + logger: logger, + level: level, } } @@ -63,21 +80,51 @@ func (h *GoKitHandler) Enabled(_ context.Context, level slog.Level) bool { // are formatted and added to the log call as individual key/value pairs. It // implements slog.Handler. func (h *GoKitHandler) Handle(_ context.Context, record slog.Record) error { - logger := h.levelLoggers.get(record.Level) - - // Pre-compute slice capacity. h.preformatted is already flattened to []any - // key-value pairs at WithAttrs time, so len(h.preformatted) is the exact - // item count -- no expansion buffer needed for that portion. Record attrs - // may contain groups that expand beyond 2 items per attr, so include a 50% - // buffer for that portion's estimated capacity only. - // - // We know we need: + // Pre-compute slice capacity, sized exactly for records with flat attrs + // (the common shape): + // - 2 for level (key + value) + // - 2 for caller (key + value) // - 2 for timestamp (key + value) // - 2 for message (key + value) - // - len(h.preformatted) exact items (pre-flattened, no expansion) - // - 2 * record.NumAttrs() for record attrs, +50% buffer for group expansion - capacity := 4 + len(h.preformatted) + (3 * record.NumAttrs()) + // - len(h.preformatted) exact items (pre-flattened at WithAttrs time) + // - 2 * record.NumAttrs() for record attrs + // + // Group attrs expand beyond 2 items per attr (a group with n items + // counts as one attr but flattens to 2n entries), so they'll need to + // be grown anyway. + numAttrs := record.NumAttrs() + capacity := 8 + len(h.preformatted) + (2 * numAttrs) pairs := make([]any, 0, capacity) + + // Append the level directly as the first pair. Matches how the log + // message is constructed through level.Info()/level.Debug()/etc + // wrappers, but without the extra allocation/copy per call. + pairs = append(pairs, levelKey, gokitLevelValue(record.Level)) + + // Resolve the log call site from the PC that slog captured when the + // record was created. Cheaper and more accurate to do it here since + // it's already captured, vs relying on setting `log.Caller()` depth + // and hoping it unwinds correctly. + if record.PC != 0 { + if caller, ok := callerCache.Load(record.PC); ok { + pairs = append(pairs, callerKey, caller) + } else { + fs := runtime.CallersFrames([]uintptr{record.PC}) + f, _ := fs.Next() + if f.File != "" { + // Trim to basename:line with the same logic as + // go-kit's log.Caller: + // https://github.com/go-kit/log/blob/v0.2.1/value.go#L84-L93 + // + // path.Base() would work, opting for direct compatibility. + idx := strings.LastIndexByte(f.File, '/') + caller := any(f.File[idx+1:] + ":" + strconv.Itoa(f.Line)) + callerCache.Store(record.PC, caller) + pairs = append(pairs, callerKey, caller) + } + } + } + if !record.Time.IsZero() { pairs = append(pairs, timeKey, record.Time) } @@ -87,17 +134,25 @@ func (h *GoKitHandler) Handle(_ context.Context, record slog.Record) error { // WithAttrs() call. pairs = append(pairs, h.preformatted...) - record.Attrs(func(a slog.Attr) bool { - pairs = appendPair(pairs, h.group, a) - return true - }) + // Skip the Attrs() call entirely when there are no attrs. + if numAttrs > 0 { + record.Attrs(func(a slog.Attr) bool { + pairs = appendPair(pairs, h.group, a) + return true + }) + } - return logger.Log(pairs...) + return h.logger.Log(pairs...) } // WithAttrs formats the provided attributes and caches them in the handler to // attach to all future log calls. It implements slog.Handler. func (h *GoKitHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + // No attrs, return it untouched. + if len(attrs) == 0 { + return h + } + // Make a defensive copy of preformatted attrs to avoid race conditions // when multiple goroutines call WithAttrs concurrently on the same handler. // Attrs are pre-flattened to []any key-value pairs here so that Handle() @@ -115,7 +170,6 @@ func (h *GoKitHandler) WithAttrs(attrs []slog.Attr) slog.Handler { return &GoKitHandler{ logger: h.logger, level: h.level, - levelLoggers: h.levelLoggers, preformatted: pairs, group: h.group, } @@ -136,13 +190,20 @@ func (h *GoKitHandler) WithGroup(name string) slog.Handler { return &GoKitHandler{ logger: h.logger, level: h.level, - levelLoggers: h.levelLoggers, preformatted: h.preformatted, group: g, } } func appendPair(pairs []any, groupPrefix string, attr slog.Attr) []any { + // Resolve LogValuers before the kind switch so value that resolves to + // a group is expanded into individual pairs. Aligns with how the + // stdlib handlers resolve before expanding, and also avoids the + // defer/recover that `Resolve()` incurs. + if attr.Value.Kind() == slog.KindLogValuer { + attr.Value = attr.Value.Resolve() + } + if attr.Equal(slog.Attr{}) { return pairs } @@ -175,7 +236,14 @@ func appendPair(pairs []any, groupPrefix string, attr slog.Attr) []any { key = groupPrefix + "." + key } - pairs = append(pairs, key, attr.Value.Resolve()) + // Append string values as raw strings rather than boxed + // slog.Values, lean on string path optimizations in slog and + // go-kit/log. + if attr.Value.Kind() == slog.KindString { + pairs = append(pairs, key, attr.Value.String()) + } else { + pairs = append(pairs, key, attr.Value) + } } return pairs diff --git a/vendor/github.com/tjhop/slog-gokit/level.go b/vendor/github.com/tjhop/slog-gokit/level.go index 58b0b58ade8..29c10d0d9f2 100644 --- a/vendor/github.com/tjhop/slog-gokit/level.go +++ b/vendor/github.com/tjhop/slog-gokit/level.go @@ -3,38 +3,34 @@ package sloggokit import ( "log/slog" - "github.com/go-kit/log" "github.com/go-kit/log/level" ) -// levelLoggerCache holds pre-built leveled loggers so that Handle() can -// retrieve an existing leveled logger rather than creating a new one each -// time. -type levelLoggerCache struct { - debugLogger log.Logger - infoLogger log.Logger - warnLogger log.Logger - errorLogger log.Logger -} - -func newLevelCache(logger log.Logger) *levelLoggerCache { - return &levelLoggerCache{ - debugLogger: level.Debug(logger), - infoLogger: level.Info(logger), - warnLogger: level.Warn(logger), - errorLogger: level.Error(logger), - } -} +// go-kit/log hoists these into package level variables to pre-pay boxing cost +// once, same that we do for slog keys in the handler: +// https://github.com/go-kit/log/blob/v0.2.1/level/level.go#L229-L239 +// +// Re-hoist them here for the same reasons so they can be appended right into +// the log's kv pairs. +var ( + levelKey any = level.Key() + debugLevelValue any = level.DebugValue() + infoLevelValue any = level.InfoValue() + warnLevelValue any = level.WarnValue() + errorLevelValue any = level.ErrorValue() +) -func (c *levelLoggerCache) get(lvl slog.Level) log.Logger { +// gokitLevelValue maps an slog.Level to the boxed go-kit level value. +// Unnamed levels bucket to the highest named level at or below them. +func gokitLevelValue(lvl slog.Level) any { switch { case lvl >= slog.LevelError: - return c.errorLogger + return errorLevelValue case lvl >= slog.LevelWarn: - return c.warnLogger + return warnLevelValue case lvl >= slog.LevelInfo: - return c.infoLogger + return infoLevelValue default: - return c.debugLogger + return debugLevelValue } } diff --git a/vendor/go.opentelemetry.io/collector/featuregate/flag.go b/vendor/go.opentelemetry.io/collector/featuregate/flag.go index 1c6f3a5e873..6f5a27070cf 100644 --- a/vendor/go.opentelemetry.io/collector/featuregate/flag.go +++ b/vendor/go.opentelemetry.io/collector/featuregate/flag.go @@ -5,6 +5,7 @@ package featuregate // import "go.opentelemetry.io/collector/featuregate" import ( "flag" + "fmt" "strings" "go.uber.org/multierr" @@ -57,6 +58,10 @@ func (f *flagValue) Set(s string) error { ids := strings.Split(s, ",") for i := range ids { id := ids[i] + if id == "" { + errs = multierr.Append(errs, fmt.Errorf("empty feature gate identifier at index %d", i)) + continue + } val := true switch id[0] { case '-': diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE index 261eeb9e9f8..f1aee0f1100 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE @@ -199,3 +199,33 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +-------------------------------------------------------------------------------- + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go index 296407f38e1..7ba1b654f8d 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go @@ -1,16 +1,19 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc import ( - "google.golang.org/grpc/stats" + "context" + "os" + "strings" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" + "google.golang.org/grpc/stats" ) // ScopeName is the instrumentation scope name. @@ -28,19 +31,33 @@ type InterceptorFilter func(*InterceptorInfo) bool // A Filter must return true if the request should be instrumented. type Filter func(*stats.RPCTagInfo) bool +type semconvMode int + +const ( + semconvModeNew semconvMode = iota // Default + semconvModeOld + semconvModeDup +) + // config is a group of options for this instrumentation. type config struct { - Filter Filter - InterceptorFilter InterceptorFilter - Propagators propagation.TextMapPropagator - TracerProvider trace.TracerProvider - MeterProvider metric.MeterProvider - SpanStartOptions []trace.SpanStartOption - SpanAttributes []attribute.KeyValue - MetricAttributes []attribute.KeyValue + Filter Filter + InterceptorFilter InterceptorFilter + Propagators propagation.TextMapPropagator + TracerProvider trace.TracerProvider + MeterProvider metric.MeterProvider + SpanKind trace.SpanKind + SpanAttributes []attribute.KeyValue + MetricAttributes []attribute.KeyValue + MetricAttributesFn func(ctx context.Context) []attribute.KeyValue + + PublicEndpoint bool + PublicEndpointFn func(ctx context.Context, info *stats.RPCTagInfo) bool ReceivedEvent bool SentEvent bool + + semconvMode semconvMode } // Option applies an option value for a config. @@ -48,91 +65,113 @@ type Option interface { apply(*config) } +type optionFunc func(*config) + +func (f optionFunc) apply(c *config) { + f(c) +} + // newConfig returns a config configured with all the passed Options. func newConfig(opts []Option) *config { c := &config{ Propagators: otel.GetTextMapPropagator(), TracerProvider: otel.GetTracerProvider(), MeterProvider: otel.GetMeterProvider(), + semconvMode: parseSemconvMode(), } for _, o := range opts { o.apply(c) } + return c } -type propagatorsOption struct{ p propagation.TextMapPropagator } - -func (o propagatorsOption) apply(c *config) { - if o.p != nil { - c.Propagators = o.p +func parseSemconvMode() semconvMode { + val := os.Getenv("OTEL_SEMCONV_STABILITY_OPT_IN") + if val == "" { + return semconvModeNew + } + parts := strings.SplitSeq(val, ",") + for p := range parts { + p = strings.TrimSpace(p) + if p == "rpc/dup" { + return semconvModeDup + } + if p == "rpc/old" { + return semconvModeOld + } } + return semconvModeNew } -// WithPropagators returns an Option to use the Propagators when extracting -// and injecting trace context from requests. -func WithPropagators(p propagation.TextMapPropagator) Option { - return propagatorsOption{p: p} +// WithPublicEndpoint configures the Handler to link the span with an incoming +// span context. If this option is not provided, then the association is a child +// association instead of a link. +func WithPublicEndpoint() Option { + return optionFunc(func(c *config) { + c.PublicEndpoint = true + }) } -type tracerProviderOption struct{ tp trace.TracerProvider } +// WithPublicEndpointFn runs with every request, and allows conditionally +// configuring the Handler to link the span with an incoming span context. If +// this option is not provided or returns false, then the association is a +// child association instead of a link. +// Note: WithPublicEndpoint takes precedence over WithPublicEndpointFn. +func WithPublicEndpointFn(fn func(context.Context, *stats.RPCTagInfo) bool) Option { + return optionFunc(func(c *config) { + c.PublicEndpointFn = fn + }) +} -func (o tracerProviderOption) apply(c *config) { - if o.tp != nil { - c.TracerProvider = o.tp - } +// WithPropagators returns an Option to use the Propagators when extracting +// and injecting trace context from requests. +func WithPropagators(p propagation.TextMapPropagator) Option { + return optionFunc(func(c *config) { + if p != nil { + c.Propagators = p + } + }) } // WithInterceptorFilter returns an Option to use the request filter. // // Deprecated: Use stats handlers instead. func WithInterceptorFilter(f InterceptorFilter) Option { - return interceptorFilterOption{f: f} -} - -type interceptorFilterOption struct { - f InterceptorFilter -} - -func (o interceptorFilterOption) apply(c *config) { - if o.f != nil { - c.InterceptorFilter = o.f - } + return optionFunc(func(c *config) { + if f != nil { + c.InterceptorFilter = f + } + }) } // WithFilter returns an Option to use the request filter. func WithFilter(f Filter) Option { - return filterOption{f: f} -} - -type filterOption struct { - f Filter -} - -func (o filterOption) apply(c *config) { - if o.f != nil { - c.Filter = o.f - } + return optionFunc(func(c *config) { + if f != nil { + c.Filter = f + } + }) } // WithTracerProvider returns an Option to use the TracerProvider when // creating a Tracer. func WithTracerProvider(tp trace.TracerProvider) Option { - return tracerProviderOption{tp: tp} -} - -type meterProviderOption struct{ mp metric.MeterProvider } - -func (o meterProviderOption) apply(c *config) { - if o.mp != nil { - c.MeterProvider = o.mp - } + return optionFunc(func(c *config) { + if tp != nil { + c.TracerProvider = tp + } + }) } // WithMeterProvider returns an Option to use the MeterProvider when // creating a Meter. If this option is not provide the global MeterProvider will be used. func WithMeterProvider(mp metric.MeterProvider) Option { - return meterProviderOption{mp: mp} + return optionFunc(func(c *config) { + if mp != nil { + c.MeterProvider = mp + } + }) } // Event type that can be recorded, see WithMessageEvents. @@ -144,21 +183,6 @@ const ( SentEvents ) -type messageEventsProviderOption struct { - events []Event -} - -func (m messageEventsProviderOption) apply(c *config) { - for _, e := range m.events { - switch e { - case ReceivedEvents: - c.ReceivedEvent = true - case SentEvents: - c.SentEvent = true - } - } -} - // WithMessageEvents configures the Handler to record the specified events // (span.AddEvent) on spans. By default only summary attributes are added at the // end of the request. @@ -167,43 +191,56 @@ func (m messageEventsProviderOption) apply(c *config) { // - ReceivedEvents: Record the number of bytes read after every gRPC read operation. // - SentEvents: Record the number of bytes written after every gRPC write operation. func WithMessageEvents(events ...Event) Option { - return messageEventsProviderOption{events: events} -} - -type spanStartOption struct{ opts []trace.SpanStartOption } - -func (o spanStartOption) apply(c *config) { - c.SpanStartOptions = append(c.SpanStartOptions, o.opts...) -} - -// WithSpanOptions configures an additional set of -// trace.SpanOptions, which are applied to each new span. -func WithSpanOptions(opts ...trace.SpanStartOption) Option { - return spanStartOption{opts} + return optionFunc(func(c *config) { + for _, e := range events { + switch e { + case ReceivedEvents: + c.ReceivedEvent = true + case SentEvents: + c.SentEvent = true + } + } + }) } -type spanAttributesOption struct{ a []attribute.KeyValue } - -func (o spanAttributesOption) apply(c *config) { - if o.a != nil { - c.SpanAttributes = o.a - } +// WithSpanKind returns an Option to set the span kind for spans created by +// the handler. +// +// By default, [NewServerHandler] creates spans with +// [trace.SpanKindServer] and [NewClientHandler] creates spans with +// [trace.SpanKindClient]. +func WithSpanKind(sk trace.SpanKind) Option { + return optionFunc(func(c *config) { + c.SpanKind = sk + }) } // WithSpanAttributes returns an Option to add custom attributes to the spans. func WithSpanAttributes(a ...attribute.KeyValue) Option { - return spanAttributesOption{a: a} -} - -type metricAttributesOption struct{ a []attribute.KeyValue } - -func (o metricAttributesOption) apply(c *config) { - if o.a != nil { - c.MetricAttributes = o.a - } + return optionFunc(func(c *config) { + if a != nil { + c.SpanAttributes = a + } + }) } // WithMetricAttributes returns an Option to add custom attributes to the metrics. func WithMetricAttributes(a ...attribute.KeyValue) Option { - return metricAttributesOption{a: a} + return optionFunc(func(c *config) { + if a != nil { + c.MetricAttributes = append(c.MetricAttributes, a...) + } + }) +} + +// WithMetricAttributesFn returns an Option to add dynamic custom attributes to the handler's metrics. +// The function is called once per RPC and the returned attributes are applied to all metrics recorded by this handler. +// +// The context parameter is the standard gRPC request context and provides access to request-scoped data. +func WithMetricAttributesFn(fn func(ctx context.Context) []attribute.KeyValue) Option { + return optionFunc(func(c *config) { + if fn != nil { + c.MetricAttributesFn = fn + } + }) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/doc.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/doc.go index b8b836b00fb..353e288bb69 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/doc.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/doc.go @@ -8,4 +8,4 @@ Use [NewClientHandler] with [grpc.WithStatsHandler] to instrument a gRPC client. Use [NewServerHandler] with [grpc.StatsHandler] to instrument a gRPC server. */ -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go index f63513d456c..c8065028e9c 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go @@ -1,319 +1,60 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc // gRPC tracing middleware -// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/rpc.md +// https://opentelemetry.io/docs/specs/semconv/rpc/ import ( - "context" - "errors" - "io" "net" + "net/url" "strconv" + "strings" - "google.golang.org/grpc" - grpc_codes "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/peer" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" - - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.30.0" - "go.opentelemetry.io/otel/trace" -) - -type messageType attribute.KeyValue - -// Event adds an event of the messageType to the span associated with the -// passed context with a message id. -func (m messageType) Event(ctx context.Context, id int, _ interface{}) { - span := trace.SpanFromContext(ctx) - if !span.IsRecording() { - return - } - span.AddEvent("message", trace.WithAttributes( - attribute.KeyValue(m), - semconv.RPCMessageIDKey.Int(id), - )) -} - -var ( - messageSent = messageType(semconv.RPCMessageTypeSent) - messageReceived = messageType(semconv.RPCMessageTypeReceived) + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + grpc_codes "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) -// clientStream wraps around the embedded grpc.ClientStream, and intercepts the RecvMsg and -// SendMsg method call. -type clientStream struct { - grpc.ClientStream - desc *grpc.StreamDesc - - span trace.Span - - receivedEvent bool - sentEvent bool - - receivedMessageID int - sentMessageID int -} - -var _ = proto.Marshal - -func (w *clientStream) RecvMsg(m interface{}) error { - err := w.ClientStream.RecvMsg(m) - - if err == nil && !w.desc.ServerStreams { - w.endSpan(nil) - } else if errors.Is(err, io.EOF) { - w.endSpan(nil) - } else if err != nil { - w.endSpan(err) - } else { - w.receivedMessageID++ - - if w.receivedEvent { - messageReceived.Event(w.Context(), w.receivedMessageID, m) - } - } - - return err -} - -func (w *clientStream) SendMsg(m interface{}) error { - err := w.ClientStream.SendMsg(m) - - w.sentMessageID++ - - if w.sentEvent { - messageSent.Event(w.Context(), w.sentMessageID, m) - } - - if err != nil { - w.endSpan(err) - } - - return err -} - -func (w *clientStream) Header() (metadata.MD, error) { - md, err := w.ClientStream.Header() - if err != nil { - w.endSpan(err) - } - - return md, err -} - -func (w *clientStream) CloseSend() error { - err := w.ClientStream.CloseSend() - if err != nil { - w.endSpan(err) - } - - return err -} - -func wrapClientStream(s grpc.ClientStream, desc *grpc.StreamDesc, span trace.Span, cfg *config) *clientStream { - return &clientStream{ - ClientStream: s, - span: span, - desc: desc, - receivedEvent: cfg.ReceivedEvent, - sentEvent: cfg.SentEvent, - } -} - -func (w *clientStream) endSpan(err error) { - if err != nil { - s, _ := status.FromError(err) - w.span.SetStatus(codes.Error, s.Message()) - w.span.SetAttributes(statusCodeAttr(s.Code())) - } else { - w.span.SetAttributes(statusCodeAttr(grpc_codes.OK)) - } - - w.span.End() -} - -// StreamClientInterceptor returns a grpc.StreamClientInterceptor suitable -// for use in a grpc.NewClient call. +// serverAddrAttrsFromCanonicalTarget extracts server address attributes from a +// canonical gRPC target as returned by [google.golang.org/grpc.ClientConn.CanonicalTarget]. +// Canonical targets always have the form "scheme://[authority]/endpoint", e.g.: // -// Deprecated: Use [NewClientHandler] instead. -func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor { - cfg := newConfig(opts) - tracer := cfg.TracerProvider.Tracer( - ScopeName, - trace.WithInstrumentationVersion(Version()), - ) - - return func( - ctx context.Context, - desc *grpc.StreamDesc, - cc *grpc.ClientConn, - method string, - streamer grpc.Streamer, - callOpts ...grpc.CallOption, - ) (grpc.ClientStream, error) { - i := &InterceptorInfo{ - Method: method, - Type: StreamClient, - } - if cfg.InterceptorFilter != nil && !cfg.InterceptorFilter(i) { - return streamer(ctx, desc, cc, method, callOpts...) - } - - name, attr := telemetryAttributes(method, cc.Target()) - - startOpts := append([]trace.SpanStartOption{ - trace.WithSpanKind(trace.SpanKindClient), - trace.WithAttributes(attr...), - }, - cfg.SpanStartOptions..., - ) - - ctx, span := tracer.Start( - ctx, - name, - startOpts..., - ) - - ctx = inject(ctx, cfg.Propagators) - - s, err := streamer(ctx, desc, cc, method, callOpts...) - if err != nil { - grpcStatus, _ := status.FromError(err) - span.SetStatus(codes.Error, grpcStatus.Message()) - span.SetAttributes(statusCodeAttr(grpcStatus.Code())) - span.End() - return s, err +// passthrough:///127.0.0.1:7777 → ServerAddress("127.0.0.1"), ServerPort(7777) +// dns:///example.com:443 → ServerAddress("example.com"), ServerPort(443) +// dns://authority/example.com:443 → ServerAddress("example.com"), ServerPort(443) +// unix:///tmp/grpc.sock → ServerAddress("/tmp/grpc.sock") +func serverAddrAttrsFromCanonicalTarget(target string) []attribute.KeyValue { + // Fast path: confirmed host:port with numeric port, no scheme involved. + if h, pStr, err := net.SplitHostPort(target); err == nil { + if p, err := strconv.Atoi(pStr); err == nil { + return []attribute.KeyValue{ + semconv.ServerAddress(h), + semconv.ServerPort(p), + } } - stream := wrapClientStream(s, desc, span, cfg) - return stream, nil } -} - -// serverStream wraps around the embedded grpc.ServerStream, and intercepts the RecvMsg and -// SendMsg method call. -type serverStream struct { - grpc.ServerStream - ctx context.Context - - receivedMessageID int - sentMessageID int - - receivedEvent bool - sentEvent bool -} - -func (w *serverStream) Context() context.Context { - return w.ctx -} - -func (w *serverStream) RecvMsg(m interface{}) error { - err := w.ServerStream.RecvMsg(m) - - if err == nil { - w.receivedMessageID++ - if w.receivedEvent { - messageReceived.Event(w.Context(), w.receivedMessageID, m) - } + // gRPC URI: scheme://authority/endpoint → endpoint in Path + // scheme:endpoint → endpoint in Opaque + u, err := url.Parse(target) + if err != nil { + return []attribute.KeyValue{semconv.ServerAddress(target)} } - - return err -} - -func (w *serverStream) SendMsg(m interface{}) error { - err := w.ServerStream.SendMsg(m) - - w.sentMessageID++ - if w.sentEvent { - messageSent.Event(w.Context(), w.sentMessageID, m) + ep := u.Path + if u.Scheme != "unix" && u.Scheme != "unix-abstract" { + // Strip the leading "/" added by url.Parse for hierarchical URIs; + // preserve it for unix socket paths where the slash is meaningful. + ep = strings.TrimPrefix(ep, "/") } - - return err -} - -func wrapServerStream(ctx context.Context, ss grpc.ServerStream, cfg *config) *serverStream { - return &serverStream{ - ServerStream: ss, - ctx: ctx, - receivedEvent: cfg.ReceivedEvent, - sentEvent: cfg.SentEvent, + if ep == "" { + ep = u.Opaque } -} - -// StreamServerInterceptor returns a grpc.StreamServerInterceptor suitable -// for use in a grpc.NewServer call. -// -// Deprecated: Use [NewServerHandler] instead. -func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor { - cfg := newConfig(opts) - tracer := cfg.TracerProvider.Tracer( - ScopeName, - trace.WithInstrumentationVersion(Version()), - ) - - return func( - srv interface{}, - ss grpc.ServerStream, - info *grpc.StreamServerInfo, - handler grpc.StreamHandler, - ) error { - ctx := ss.Context() - i := &InterceptorInfo{ - StreamServerInfo: info, - Type: StreamServer, - } - if cfg.InterceptorFilter != nil && !cfg.InterceptorFilter(i) { - return handler(srv, wrapServerStream(ctx, ss, cfg)) - } - - ctx = extract(ctx, cfg.Propagators) - name, attr := telemetryAttributes(info.FullMethod, peerFromCtx(ctx)) - - startOpts := append([]trace.SpanStartOption{ - trace.WithSpanKind(trace.SpanKindServer), - trace.WithAttributes(attr...), - }, - cfg.SpanStartOptions..., - ) - - ctx, span := tracer.Start( - trace.ContextWithRemoteSpanContext(ctx, trace.SpanContextFromContext(ctx)), - name, - startOpts..., - ) - defer span.End() - - err := handler(srv, wrapServerStream(ctx, ss, cfg)) - if err != nil { - s, _ := status.FromError(err) - statusCode, msg := serverStatus(s) - span.SetStatus(statusCode, msg) - span.SetAttributes(statusCodeAttr(s.Code())) - } else { - span.SetAttributes(statusCodeAttr(grpc_codes.OK)) - } - - return err + if ep != "" { + return serverAddrAttrs(ep) } -} - -// telemetryAttributes returns a span name and span and metric attributes from -// the gRPC method and peer address. -func telemetryAttributes(fullMethod, sererAddr string) (string, []attribute.KeyValue) { - name, methodAttrs := internal.ParseFullMethod(fullMethod) - srvAttrs := serverAddrAttrs(sererAddr) - - attrs := make([]attribute.KeyValue, 0, 1+len(methodAttrs)+len(srvAttrs)) - attrs = append(attrs, semconv.RPCSystemGRPC) - attrs = append(attrs, methodAttrs...) - attrs = append(attrs, srvAttrs...) - return name, attrs + return []attribute.KeyValue{semconv.ServerAddress(target)} } // serverAddrAttrs returns the server address attributes for the hostport. @@ -333,20 +74,6 @@ func serverAddrAttrs(hostport string) []attribute.KeyValue { } } -// peerFromCtx returns a peer address from a context, if one exists. -func peerFromCtx(ctx context.Context) string { - p, ok := peer.FromContext(ctx) - if !ok { - return "" - } - return p.Addr.String() -} - -// statusCodeAttr returns status code attribute based on given gRPC code. -func statusCodeAttr(c grpc_codes.Code) attribute.KeyValue { - return semconv.RPCGRPCStatusCodeKey.Int64(int64(c)) -} - // serverStatus returns a span status code and message for a given gRPC // status code. It maps specific gRPC status codes to a corresponding span // status code and message. This function is intended for use on the server diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptorinfo.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptorinfo.go index b62f7cd7c46..7a3083f3cad 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptorinfo.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptorinfo.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc import ( "google.golang.org/grpc" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go index 1fa73c2f943..aa4bbfa4ac7 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go @@ -2,13 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal functionality for the otelgrpc package. -package internal // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal" +package internal import ( "strings" "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.30.0" + oldsemconv "go.opentelemetry.io/otel/semconv/v1.37.0" //nolint:depguard // Use of v1.37.0 is required for backward compatibility stability opt-in. + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) // ParseFullMethod returns a span name following the OpenTelemetry semantic @@ -23,19 +24,30 @@ func ParseFullMethod(fullMethod string) (string, []attribute.KeyValue) { return fullMethod, nil } name := fullMethod[1:] - pos := strings.LastIndex(name, "/") - if pos < 0 { - // Invalid format, does not follow `/package.service/method`. - return name, nil - } - service, method := name[:pos], name[pos+1:] + return name, []attribute.KeyValue{semconv.RPCMethod(name)} +} - var attrs []attribute.KeyValue - if service != "" { - attrs = append(attrs, semconv.RPCService(service)) +// ParseFullMethodOld returns a span name following the old OpenTelemetry semantic +// conventions as well as all applicable span attribute.KeyValue attributes based +// on a gRPC's FullMethod. +// Based on the implementation in: +// https://github.com/open-telemetry/opentelemetry-go-contrib/blob/072dcf8ad7e5e48b506e05720b29d8b078759606/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go#L20 +func ParseFullMethodOld(fullMethod string) (string, []attribute.KeyValue) { + if !strings.HasPrefix(fullMethod, "/") { + return fullMethod, nil + } + name := fullMethod[1:] + parts := strings.Split(name, "/") + if len(parts) < 2 { + return name, []attribute.KeyValue{ + attribute.String("rpc.system", "grpc"), + } } - if method != "" { - attrs = append(attrs, semconv.RPCMethod(method)) + service := parts[0] + method := parts[1] + return name, []attribute.KeyValue{ + oldsemconv.RPCSystemKey.String("grpc"), + oldsemconv.RPCServiceKey.String(service), + oldsemconv.RPCMethodKey.String(method), } - return name, attrs } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go index 6e67f0216b0..6651e8bd804 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go @@ -1,26 +1,23 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc import ( "context" - "google.golang.org/grpc/metadata" - - "go.opentelemetry.io/otel/baggage" "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/trace" + "google.golang.org/grpc/metadata" ) type metadataSupplier struct { - metadata *metadata.MD + metadata metadata.MD } // assert that metadataSupplier implements the TextMapCarrier interface. -var _ propagation.TextMapCarrier = &metadataSupplier{} +var _ propagation.TextMapCarrier = metadataSupplier{} -func (s *metadataSupplier) Get(key string) string { +func (s metadataSupplier) Get(key string) string { values := s.metadata.Get(key) if len(values) == 0 { return "" @@ -28,51 +25,27 @@ func (s *metadataSupplier) Get(key string) string { return values[0] } -func (s *metadataSupplier) Set(key string, value string) { +func (s metadataSupplier) Set(key, value string) { s.metadata.Set(key, value) } -func (s *metadataSupplier) Keys() []string { - out := make([]string, 0, len(*s.metadata)) - for key := range *s.metadata { +func (s metadataSupplier) Keys() []string { + out := make([]string, 0, len(s.metadata)) + for key := range s.metadata { out = append(out, key) } return out } -// Inject injects correlation context and span context into the gRPC -// metadata object. This function is meant to be used on outgoing -// requests. -// Deprecated: Unnecessary public func. -func Inject(ctx context.Context, md *metadata.MD, opts ...Option) { - c := newConfig(opts) - c.Propagators.Inject(ctx, &metadataSupplier{ - metadata: md, - }) -} - func inject(ctx context.Context, propagators propagation.TextMapPropagator) context.Context { md, ok := metadata.FromOutgoingContext(ctx) if !ok { md = metadata.MD{} } - propagators.Inject(ctx, &metadataSupplier{ - metadata: &md, - }) - return metadata.NewOutgoingContext(ctx, md) -} - -// Extract returns the correlation context and span context that -// another service encoded in the gRPC metadata object with Inject. -// This function is meant to be used on incoming requests. -// Deprecated: Unnecessary public func. -func Extract(ctx context.Context, md *metadata.MD, opts ...Option) (baggage.Baggage, trace.SpanContext) { - c := newConfig(opts) - ctx = c.Propagators.Extract(ctx, &metadataSupplier{ + propagators.Inject(ctx, metadataSupplier{ metadata: md, }) - - return baggage.FromContext(ctx), trace.SpanContextFromContext(ctx) + return metadata.NewOutgoingContext(ctx, md) } func extract(ctx context.Context, propagators propagation.TextMapPropagator) context.Context { @@ -81,7 +54,7 @@ func extract(ctx context.Context, propagators propagation.TextMapPropagator) con md = metadata.MD{} } - return propagators.Extract(ctx, &metadataSupplier{ - metadata: &md, + return propagators.Extract(ctx, metadataSupplier{ + metadata: md, }) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go index 9bec51df339..1d0fc062262 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go @@ -1,34 +1,37 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc import ( "context" - "sync/atomic" + "strconv" "time" - grpc_codes "google.golang.org/grpc/codes" - "google.golang.org/grpc/peer" - "google.golang.org/grpc/stats" - "google.golang.org/grpc/status" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" - semconv "go.opentelemetry.io/otel/semconv/v1.30.0" + oldrpcconv "go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv" //nolint:depguard // Use of v1.37.0 is required for backward compatibility stability opt-in. + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv" "go.opentelemetry.io/otel/trace" + grpc_codes "google.golang.org/grpc/codes" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal" ) type gRPCContextKey struct{} +// dialTargetContextKey carries the dial target seeded by client interceptors +// so the stats handler can use the hostname for server.address instead of the +// post-DNS IP from RemoteAddr. +type dialTargetContextKey struct{} + type gRPCContext struct { - inMessages int64 - outMessages int64 metricAttrs []attribute.KeyValue record bool } @@ -38,87 +41,50 @@ type serverHandler struct { tracer trace.Tracer - duration metric.Float64Histogram - inSize metric.Int64Histogram - outSize metric.Int64Histogram - inMsg metric.Int64Histogram - outMsg metric.Int64Histogram + duration rpcconv.ServerCallDuration + oldDuration oldrpcconv.ServerDuration } // NewServerHandler creates a stats.Handler for a gRPC server. func NewServerHandler(opts ...Option) stats.Handler { c := newConfig(opts) + if c.SpanKind == trace.SpanKindUnspecified { + c.SpanKind = trace.SpanKindServer + } + h := &serverHandler{config: c} h.tracer = c.TracerProvider.Tracer( ScopeName, - trace.WithInstrumentationVersion(Version()), + trace.WithInstrumentationVersion(Version), ) meter := c.MeterProvider.Meter( ScopeName, - metric.WithInstrumentationVersion(Version()), + metric.WithInstrumentationVersion(Version), metric.WithSchemaURL(semconv.SchemaURL), ) var err error - h.duration, err = meter.Float64Histogram( - semconv.RPCServerDurationName, - metric.WithDescription(semconv.RPCServerDurationDescription), - metric.WithUnit(semconv.RPCServerDurationUnit), - ) - if err != nil { - otel.Handle(err) - if h.duration == nil { - h.duration = noop.Float64Histogram{} - } - } - - h.inSize, err = meter.Int64Histogram( - semconv.RPCServerRequestSizeName, - metric.WithDescription(semconv.RPCServerRequestSizeDescription), - metric.WithUnit(semconv.RPCServerRequestSizeUnit), - ) - if err != nil { - otel.Handle(err) - if h.inSize == nil { - h.inSize = noop.Int64Histogram{} - } - } - - h.outSize, err = meter.Int64Histogram( - semconv.RPCServerResponseSizeName, - metric.WithDescription(semconv.RPCServerResponseSizeDescription), - metric.WithUnit(semconv.RPCServerResponseSizeUnit), - ) - if err != nil { - otel.Handle(err) - if h.outSize == nil { - h.outSize = noop.Int64Histogram{} - } - } - - h.inMsg, err = meter.Int64Histogram( - semconv.RPCServerRequestsPerRPCName, - metric.WithDescription(semconv.RPCServerRequestsPerRPCDescription), - metric.WithUnit(semconv.RPCServerRequestsPerRPCUnit), - ) - if err != nil { - otel.Handle(err) - if h.inMsg == nil { - h.inMsg = noop.Int64Histogram{} + if c.semconvMode == semconvModeOld || c.semconvMode == semconvModeDup { + oldDur, err := oldrpcconv.NewServerDuration(meter) + if err != nil { + otel.Handle(err) + } else { + h.oldDuration = oldDur } } - h.outMsg, err = meter.Int64Histogram( - semconv.RPCServerResponsesPerRPCName, - metric.WithDescription(semconv.RPCServerResponsesPerRPCDescription), - metric.WithUnit(semconv.RPCServerResponsesPerRPCUnit), - ) - if err != nil { - otel.Handle(err) - if h.outMsg == nil { - h.outMsg = noop.Int64Histogram{} + if c.semconvMode == semconvModeNew || c.semconvMode == semconvModeDup { + h.duration, err = rpcconv.NewServerCallDuration( + meter, + metric.WithExplicitBucketBoundaries( + 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, + 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10, + ), + ) + if err != nil { + otel.Handle(err) } } @@ -126,20 +92,35 @@ func NewServerHandler(opts ...Option) stats.Handler { } // TagConn can attach some information to the given context. -func (h *serverHandler) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context { +func (*serverHandler) TagConn(ctx context.Context, _ *stats.ConnTagInfo) context.Context { return ctx } // HandleConn processes the Conn stats. -func (h *serverHandler) HandleConn(ctx context.Context, info stats.ConnStats) { +func (*serverHandler) HandleConn(context.Context, stats.ConnStats) { } // TagRPC can attach some information to the given context. func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { ctx = extract(ctx, h.Propagators) - name, attrs := internal.ParseFullMethod(info.FullMethodName) - attrs = append(attrs, semconv.RPCSystemGRPC) + var name string + var attrs []attribute.KeyValue + + switch h.semconvMode { + case semconvModeOld: + name, attrs = internal.ParseFullMethodOld(info.FullMethodName) + case semconvModeDup: + var attrsNew, attrsOld []attribute.KeyValue + name, attrsNew = internal.ParseFullMethod(info.FullMethodName) + _, attrsOld = internal.ParseFullMethodOld(info.FullMethodName) + // Combine both. We append New last so its rpc.method (fully qualified) wins when deduplicated. + attrs = append(append([]attribute.KeyValue{}, attrsOld...), attrsNew...) + attrs = append(attrs, semconv.RPCSystemNameGRPC) // New convention + default: // semconvModeNew + name, attrs = internal.ParseFullMethod(info.FullMethodName) + attrs = append(attrs, semconv.RPCSystemNameGRPC) + } record := true if h.Filter != nil { @@ -147,11 +128,24 @@ func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont } if record { + // Make a new slice to avoid aliasing into the same attrs slice used by metrics. + spanAttributes := make([]attribute.KeyValue, 0, len(attrs)+len(h.SpanAttributes)) + spanAttributes = append(append(spanAttributes, attrs...), h.SpanAttributes...) + opts := []trace.SpanStartOption{ + trace.WithSpanKind(h.SpanKind), + trace.WithAttributes(spanAttributes...), + } + if h.PublicEndpoint || (h.PublicEndpointFn != nil && h.PublicEndpointFn(ctx, info)) { + opts = append(opts, trace.WithNewRoot()) + // Linking incoming span context if any for public endpoint. + if s := trace.SpanContextFromContext(ctx); s.IsValid() && s.IsRemote() { + opts = append(opts, trace.WithLinks(trace.Link{SpanContext: s})) + } + } ctx, _ = h.tracer.Start( trace.ContextWithRemoteSpanContext(ctx, trace.SpanContextFromContext(ctx)), name, - trace.WithSpanKind(trace.SpanKindServer), - trace.WithAttributes(append(attrs, h.SpanAttributes...)...), + opts..., ) } @@ -160,12 +154,31 @@ func (h *serverHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont record: record, } + if h.MetricAttributesFn != nil { + extraAttrs := h.MetricAttributesFn(ctx) + gctx.metricAttrs = append(gctx.metricAttrs, extraAttrs...) + } + return context.WithValue(ctx, gRPCContextKey{}, &gctx) } // HandleRPC processes the RPC stats. func (h *serverHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { - h.handleRPC(ctx, rs, h.duration, h.inSize, h.outSize, h.inMsg, h.outMsg, serverStatus) + var dur metric.Float64Histogram + if h.semconvMode == semconvModeNew || h.semconvMode == semconvModeDup { + dur = h.duration.Inst() + } + var oldDur metric.Float64Histogram + if h.semconvMode == semconvModeOld || h.semconvMode == semconvModeDup { + oldDur = h.oldDuration.Inst() + } + h.handleRPC( + ctx, + rs, + dur, + oldDur, + serverStatus, + ) } type clientHandler struct { @@ -173,87 +186,50 @@ type clientHandler struct { tracer trace.Tracer - duration metric.Float64Histogram - inSize metric.Int64Histogram - outSize metric.Int64Histogram - inMsg metric.Int64Histogram - outMsg metric.Int64Histogram + duration rpcconv.ClientCallDuration + oldDuration oldrpcconv.ClientDuration } // NewClientHandler creates a stats.Handler for a gRPC client. func NewClientHandler(opts ...Option) stats.Handler { c := newConfig(opts) + if c.SpanKind == trace.SpanKindUnspecified { + c.SpanKind = trace.SpanKindClient + } + h := &clientHandler{config: c} h.tracer = c.TracerProvider.Tracer( ScopeName, - trace.WithInstrumentationVersion(Version()), + trace.WithInstrumentationVersion(Version), ) meter := c.MeterProvider.Meter( ScopeName, - metric.WithInstrumentationVersion(Version()), + metric.WithInstrumentationVersion(Version), metric.WithSchemaURL(semconv.SchemaURL), ) var err error - h.duration, err = meter.Float64Histogram( - semconv.RPCClientDurationName, - metric.WithDescription(semconv.RPCClientDurationDescription), - metric.WithUnit(semconv.RPCClientDurationUnit), - ) - if err != nil { - otel.Handle(err) - if h.duration == nil { - h.duration = noop.Float64Histogram{} - } - } - - h.outSize, err = meter.Int64Histogram( - semconv.RPCClientRequestSizeName, - metric.WithDescription(semconv.RPCClientRequestSizeDescription), - metric.WithUnit(semconv.RPCClientRequestSizeUnit), - ) - if err != nil { - otel.Handle(err) - if h.outSize == nil { - h.outSize = noop.Int64Histogram{} - } - } - - h.inSize, err = meter.Int64Histogram( - semconv.RPCClientResponseSizeName, - metric.WithDescription(semconv.RPCClientResponseSizeDescription), - metric.WithUnit(semconv.RPCClientResponseSizeUnit), - ) - if err != nil { - otel.Handle(err) - if h.inSize == nil { - h.inSize = noop.Int64Histogram{} - } - } - - h.outMsg, err = meter.Int64Histogram( - semconv.RPCClientRequestsPerRPCName, - metric.WithDescription(semconv.RPCClientRequestsPerRPCDescription), - metric.WithUnit(semconv.RPCClientRequestsPerRPCUnit), - ) - if err != nil { - otel.Handle(err) - if h.outMsg == nil { - h.outMsg = noop.Int64Histogram{} + if c.semconvMode == semconvModeOld || c.semconvMode == semconvModeDup { + oldDur, err := oldrpcconv.NewClientDuration(meter) + if err != nil { + otel.Handle(err) + } else { + h.oldDuration = oldDur } } - h.inMsg, err = meter.Int64Histogram( - semconv.RPCClientResponsesPerRPCName, - metric.WithDescription(semconv.RPCClientResponsesPerRPCDescription), - metric.WithUnit(semconv.RPCClientResponsesPerRPCUnit), - ) - if err != nil { - otel.Handle(err) - if h.inMsg == nil { - h.inMsg = noop.Int64Histogram{} + if c.semconvMode == semconvModeNew || c.semconvMode == semconvModeDup { + h.duration, err = rpcconv.NewClientCallDuration( + meter, + metric.WithExplicitBucketBoundaries( + 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, + 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10, + ), + ) + if err != nil { + otel.Handle(err) } } @@ -262,8 +238,23 @@ func NewClientHandler(opts ...Option) stats.Handler { // TagRPC can attach some information to the given context. func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { - name, attrs := internal.ParseFullMethod(info.FullMethodName) - attrs = append(attrs, semconv.RPCSystemGRPC) + var name string + var attrs []attribute.KeyValue + + switch h.semconvMode { + case semconvModeOld: + name, attrs = internal.ParseFullMethodOld(info.FullMethodName) + case semconvModeDup: + var attrsNew, attrsOld []attribute.KeyValue + name, attrsNew = internal.ParseFullMethod(info.FullMethodName) + _, attrsOld = internal.ParseFullMethodOld(info.FullMethodName) + // Combine both. We append New last so its rpc.method (fully qualified) wins when deduplicated. + attrs = append(append([]attribute.KeyValue{}, attrsOld...), attrsNew...) + attrs = append(attrs, semconv.RPCSystemNameGRPC) // New convention + default: // semconvModeNew + name, attrs = internal.ParseFullMethod(info.FullMethodName) + attrs = append(attrs, semconv.RPCSystemNameGRPC) + } record := true if h.Filter != nil { @@ -271,11 +262,14 @@ func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont } if record { + // Make a new slice to avoid aliasing into the same attrs slice used by metrics. + spanAttributes := make([]attribute.KeyValue, 0, len(attrs)+len(h.SpanAttributes)) + spanAttributes = append(append(spanAttributes, attrs...), h.SpanAttributes...) ctx, _ = h.tracer.Start( ctx, name, - trace.WithSpanKind(trace.SpanKindClient), - trace.WithAttributes(append(attrs, h.SpanAttributes...)...), + trace.WithSpanKind(h.SpanKind), + trace.WithAttributes(spanAttributes...), ) } @@ -284,13 +278,29 @@ func (h *clientHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) cont record: record, } + if h.MetricAttributesFn != nil { + extraAttrs := h.MetricAttributesFn(ctx) + gctx.metricAttrs = append(gctx.metricAttrs, extraAttrs...) + } + return inject(context.WithValue(ctx, gRPCContextKey{}, &gctx), h.Propagators) } // HandleRPC processes the RPC stats. func (h *clientHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { + var dur metric.Float64Histogram + if h.semconvMode == semconvModeNew || h.semconvMode == semconvModeDup { + dur = h.duration.Inst() + } + var oldDur metric.Float64Histogram + if h.semconvMode == semconvModeOld || h.semconvMode == semconvModeDup { + oldDur = h.oldDuration.Inst() + } h.handleRPC( - ctx, rs, h.duration, h.inSize, h.outSize, h.inMsg, h.outMsg, + ctx, + rs, + dur, + oldDur, func(s *status.Status) (codes.Code, string) { return codes.Error, s.Message() }, @@ -298,20 +308,20 @@ func (h *clientHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { } // TagConn can attach some information to the given context. -func (h *clientHandler) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context { +func (*clientHandler) TagConn(ctx context.Context, _ *stats.ConnTagInfo) context.Context { return ctx } // HandleConn processes the Conn stats. -func (h *clientHandler) HandleConn(context.Context, stats.ConnStats) { +func (*clientHandler) HandleConn(context.Context, stats.ConnStats) { // no-op } -func (c *config) handleRPC( +func (*config) handleRPC( ctx context.Context, rs stats.RPCStats, duration metric.Float64Histogram, - inSize, outSize, inMsg, outMsg metric.Int64Histogram, + oldDuration metric.Float64Histogram, recordStatus func(*status.Status) (codes.Code, string), ) { gctx, _ := ctx.Value(gRPCContextKey{}).(*gRPCContext) @@ -320,47 +330,46 @@ func (c *config) handleRPC( } span := trace.SpanFromContext(ctx) - var messageId int64 switch rs := rs.(type) { case *stats.Begin: - case *stats.InPayload: - if gctx != nil { - messageId = atomic.AddInt64(&gctx.inMessages, 1) - inSize.Record(ctx, int64(rs.Length), metric.WithAttributes(gctx.metricAttrs...)) + // Set server.address early from the dial target when available (upcoming + // interceptors will seed this). Covers both success and failure paths since Begin + // fires on every RPC regardless of outcome. + if rs.Client { + if target, ok := ctx.Value(dialTargetContextKey{}).(string); ok && target != "" { + attrs := serverAddrAttrsFromCanonicalTarget(target) + if span.IsRecording() { + span.SetAttributes(attrs...) + } + if gctx != nil { + gctx.metricAttrs = append(gctx.metricAttrs, attrs...) + } + } } - - if c.ReceivedEvent && span.IsRecording() { - span.AddEvent("message", - trace.WithAttributes( - semconv.RPCMessageTypeReceived, - semconv.RPCMessageIDKey.Int64(messageId), - semconv.RPCMessageCompressedSizeKey.Int(rs.CompressedLength), - semconv.RPCMessageUncompressedSizeKey.Int(rs.Length), - ), - ) + case *stats.InPayload: + case *stats.InHeader: + if !rs.Client && rs.LocalAddr != nil { + if span.IsRecording() { + span.SetAttributes(serverAddrAttrs(rs.LocalAddr.String())...) + } + // TODO: add server.address and server.port to metrics once the API supports opt-in attributes. } case *stats.OutPayload: - if gctx != nil { - messageId = atomic.AddInt64(&gctx.outMessages, 1) - outSize.Record(ctx, int64(rs.Length), metric.WithAttributes(gctx.metricAttrs...)) - } - - if c.SentEvent && span.IsRecording() { - span.AddEvent("message", - trace.WithAttributes( - semconv.RPCMessageTypeSent, - semconv.RPCMessageIDKey.Int64(messageId), - semconv.RPCMessageCompressedSizeKey.Int(rs.CompressedLength), - semconv.RPCMessageUncompressedSizeKey.Int(rs.Length), - ), - ) - } case *stats.OutTrailer: case *stats.OutHeader: - if span.IsRecording() { - if p, ok := peer.FromContext(ctx); ok { - span.SetAttributes(serverAddrAttrs(p.Addr.String())...) + // Only use the resolved IP from RemoteAddr when no dial target was seeded + // (i.e. NewClientHandler callers without interceptors). When dialTargetContextKey + // is present, Begin already set server.address to the hostname. + if rs.Client && rs.RemoteAddr != nil && (span.IsRecording() || gctx != nil) { + if target, ok := ctx.Value(dialTargetContextKey{}).(string); !ok || target == "" { + attrs := serverAddrAttrs(rs.RemoteAddr.String()) + if span.IsRecording() { + span.SetAttributes(attrs...) + } + if gctx != nil { + gctx.metricAttrs = append(gctx.metricAttrs, attrs...) + } } } case *stats.End: @@ -369,9 +378,9 @@ func (c *config) handleRPC( var s *status.Status if rs.Error != nil { s, _ = status.FromError(rs.Error) - rpcStatusAttr = semconv.RPCGRPCStatusCodeKey.Int(int(s.Code())) + rpcStatusAttr = semconv.RPCResponseStatusCode(canonicalString(s.Code())) } else { - rpcStatusAttr = semconv.RPCGRPCStatusCodeKey.Int(int(grpc_codes.OK)) + rpcStatusAttr = semconv.RPCResponseStatusCode(canonicalString(grpc_codes.OK)) } if span.IsRecording() { if s != nil { @@ -382,25 +391,83 @@ func (c *config) handleRPC( span.End() } - var metricAttrs []attribute.KeyValue - if gctx != nil { - metricAttrs = make([]attribute.KeyValue, 0, len(gctx.metricAttrs)+1) - metricAttrs = append(metricAttrs, gctx.metricAttrs...) + var durationEnabled bool + var oldDurationEnabled bool + + if duration != nil { + durationEnabled = duration.Enabled(ctx) } - metricAttrs = append(metricAttrs, rpcStatusAttr) - // Allocate vararg slice once. - recordOpts := []metric.RecordOption{metric.WithAttributeSet(attribute.NewSet(metricAttrs...))} - - // Use floating point division here for higher precision (instead of Millisecond method). - // Measure right before calling Record() to capture as much elapsed time as possible. - elapsedTime := float64(rs.EndTime.Sub(rs.BeginTime)) / float64(time.Millisecond) - - duration.Record(ctx, elapsedTime, recordOpts...) - if gctx != nil { - inMsg.Record(ctx, atomic.LoadInt64(&gctx.inMessages), recordOpts...) - outMsg.Record(ctx, atomic.LoadInt64(&gctx.outMessages), recordOpts...) + if oldDuration != nil { + oldDurationEnabled = oldDuration.Enabled(ctx) + } + + if durationEnabled || oldDurationEnabled { + var metricAttrs []attribute.KeyValue + if gctx != nil { + // Don't use gctx.metricAttrSet here, because it requires passing + // multiple RecordOptions, which would call metric.mergeSets and + // allocate a new set for each Record call. + metricAttrs = make([]attribute.KeyValue, 0, len(gctx.metricAttrs)+1) + metricAttrs = append(metricAttrs, gctx.metricAttrs...) + } + metricAttrs = append(metricAttrs, rpcStatusAttr) + // Allocate vararg slice once. + recordOpts := []metric.RecordOption{metric.WithAttributeSet(attribute.NewSet(metricAttrs...))} + + // Use floating point division here for higher precision (instead of Millisecond method). + // Measure right before calling Record() to capture as much elapsed time as possible. + elapsedTime := float64(rs.EndTime.Sub(rs.BeginTime)) / float64(time.Second) + + if durationEnabled { + duration.Record(ctx, elapsedTime, recordOpts...) + } + if oldDurationEnabled { + oldDuration.Record(ctx, elapsedTime*1000.0, recordOpts...) + } } + default: return } } + +func canonicalString(code grpc_codes.Code) string { + switch code { + case grpc_codes.OK: + return "OK" + case grpc_codes.Canceled: + return "CANCELLED" + case grpc_codes.Unknown: + return "UNKNOWN" + case grpc_codes.InvalidArgument: + return "INVALID_ARGUMENT" + case grpc_codes.DeadlineExceeded: + return "DEADLINE_EXCEEDED" + case grpc_codes.NotFound: + return "NOT_FOUND" + case grpc_codes.AlreadyExists: + return "ALREADY_EXISTS" + case grpc_codes.PermissionDenied: + return "PERMISSION_DENIED" + case grpc_codes.ResourceExhausted: + return "RESOURCE_EXHAUSTED" + case grpc_codes.FailedPrecondition: + return "FAILED_PRECONDITION" + case grpc_codes.Aborted: + return "ABORTED" + case grpc_codes.OutOfRange: + return "OUT_OF_RANGE" + case grpc_codes.Unimplemented: + return "UNIMPLEMENTED" + case grpc_codes.Internal: + return "INTERNAL" + case grpc_codes.Unavailable: + return "UNAVAILABLE" + case grpc_codes.DataLoss: + return "DATA_LOSS" + case grpc_codes.Unauthenticated: + return "UNAUTHENTICATED" + default: + return "CODE(" + strconv.FormatInt(int64(code), 10) + ")" + } +} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go index b1feeca494f..23fda6f503b 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelgrpc // import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +package otelgrpc // Version is the current release version of the gRPC instrumentation. -func Version() string { - return "0.61.0" - // This string is updated by the pre_release.sh script during release -} +const Version = "0.70.0" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go index 3ae08243441..733b75dca75 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp import ( "net/http" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go index a7d4b2a815c..08ba0778f6d 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp import ( "context" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go index 1c9aa3ff425..09a2103fe46 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go @@ -3,4 +3,4 @@ // Package otelhttp provides an http.Handler and functions that are intended // to be used to add tracing by wrapping existing handlers. -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go index a269fce0f7a..844363a0908 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp import ( "net/http" @@ -35,10 +35,6 @@ type middleware struct { semconv semconv.HTTPServer } -func defaultHandlerFormatter(operation string, _ *http.Request) string { - return operation -} - // NewHandler wraps the passed handler in a span named after the operation and // enriches it with metrics. func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler { @@ -55,12 +51,17 @@ func NewMiddleware(operation string, opts ...Option) func(http.Handler) http.Han defaultOpts := []Option{ WithSpanOptions(trace.WithSpanKind(trace.SpanKindServer)), - WithSpanNameFormatter(defaultHandlerFormatter), } c := newConfig(append(defaultOpts, opts...)...) h.configure(c) + if h.spanNameFormatter == nil { + h.spanNameFormatter = func(_ string, r *http.Request) string { + return h.semconv.SpanName(r) + } + } + return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { h.serveHTTP(w, r, next) @@ -138,7 +139,13 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http // ReadCloser fulfills a certain interface and it is indeed nil or NoBody. bw := request.NewBodyWrapper(r.Body, readRecordFunc) if r.Body != nil && r.Body != http.NoBody { + origReq := r + prevBody := r.Body r.Body = bw + + // Restore the original body after the request is processed to avoid issues + // with extra wrapper since `http/server.go` later checks type of `r.Body`. + defer func() { origReq.Body = prevBody }() } writeRecordFunc := func(int64) {} diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go index d032aa841b3..aeff4160467 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go @@ -1,12 +1,12 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/request/body_wrapper.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/request/body_wrapper.go.tmpl + // Package request provides types and functionality to handle HTTP request // handling. -package request // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" +package request import ( "io" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go index 9e00dd2fcef..98f7bdbfcfd 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package request // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" +package request // Generate request package: //go:generate gotmpl --body=../../../../../../internal/shared/request/body_wrapper.go.tmpl "--data={}" --out=body_wrapper.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go index f29f9b7c962..6b523cb74fe 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/request/resp_writer_wrapper.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package request // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/request/resp_writer_wrapper.go.tmpl + +package request import ( "net/http" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go index 1398d85c2e9..c275b5f0514 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go @@ -1,17 +1,18 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconv/client.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/semconv/client.go.tmpl + // Package semconv provides OpenTelemetry semantic convention types and // functionality. -package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" +package semconv import ( "context" "fmt" "net/http" + "reflect" "slices" "strconv" "strings" @@ -19,8 +20,8 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/semconv/v1.40.0" - "go.opentelemetry.io/otel/semconv/v1.40.0/httpconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/httpconv" ) type HTTPClient struct { @@ -44,7 +45,7 @@ func NewHTTPClient(meter metric.Meter) HTTPClient { return client } -func (n HTTPClient) Status(code int) (codes.Code, string) { +func (HTTPClient) Status(code int) (codes.Code, string) { if code < 100 || code >= 600 { return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) } @@ -119,9 +120,7 @@ func (n HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { // Restore any username/password info that was removed. req.URL.User = userinfo } - attrs = append(attrs, semconv.URLFull(u)) - - attrs = append(attrs, semconv.ServerAddress(requestHost)) + attrs = append(attrs, semconv.URLFull(u), semconv.ServerAddress(requestHost)) if eligiblePort > 0 { attrs = append(attrs, semconv.ServerPort(eligiblePort)) } @@ -137,11 +136,13 @@ func (n HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue { } // ResponseTraceAttrs returns trace attributes for an HTTP response made by a client. -func (n HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { +func (HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue { /* below attributes are returned: - http.response.status_code - error.type + - network.protocol.name (only when it is not "http") + - network.protocol.version */ var count int if resp.StatusCode > 0 { @@ -152,6 +153,21 @@ func (n HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue count++ } + // The protocol version is only known for certain once the response + // arrives: req.Proto reflects what the caller asked for, but the + // transport may negotiate a different version (for example HTTP/2 via + // ALPN). Report resp.Proto here so it overrides the request-time value + // on the span. As in RequestTraceAttrs, network.protocol.name is omitted + // when it is "http": the spec only requires it when the name differs from + // the protocol implied by http.request.method. + protoName, protoVersion := netProtocol(resp.Proto) + if protoName != "" && protoName != "http" { + count++ + } + if protoVersion != "" { + count++ + } + attrs := make([]attribute.KeyValue, 0, count) if resp.StatusCode > 0 { attrs = append(attrs, semconv.HTTPResponseStatusCode(resp.StatusCode)) @@ -161,12 +177,19 @@ func (n HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue errorType := strconv.Itoa(resp.StatusCode) attrs = append(attrs, semconv.ErrorTypeKey.String(errorType)) } + + if protoName != "" && protoName != "http" { + attrs = append(attrs, semconv.NetworkProtocolName(protoName)) + } + if protoVersion != "" { + attrs = append(attrs, semconv.NetworkProtocolVersion(protoVersion)) + } return attrs } -func (n HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) { +func (HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) { if method == "" { - return semconv.HTTPRequestMethodGet, attribute.KeyValue{} + return semconv.HTTPRequestMethodOther, attribute.KeyValue{} } if attr, ok := methodLookup[method]; ok { return attr, attribute.KeyValue{} @@ -176,10 +199,10 @@ func (n HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValu if attr, ok := methodLookup[strings.ToUpper(method)]; ok { return attr, orig } - return semconv.HTTPRequestMethodGet, orig + return semconv.HTTPRequestMethodOther, orig } -func (n HTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { +func (n HTTPClient) MetricAttributes(req *http.Request, resp *http.Response, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue { num := len(additionalAttributes) + 2 var h string if req.URL != nil { @@ -199,7 +222,14 @@ func (n HTTPClient) MetricAttributes(req *http.Request, statusCode int, addition num++ } - protoName, protoVersion := netProtocol(req.Proto) + // Prefer the negotiated protocol reported on the response: req.Proto is + // only what the caller asked for, and the transport may have upgraded + // the connection (for example HTTP/2 via ALPN). + proto := req.Proto + if resp != nil && resp.Proto != "" { + proto = resp.Proto + } + protoName, protoVersion := netProtocol(proto) if protoName != "" { num++ } @@ -212,7 +242,8 @@ func (n HTTPClient) MetricAttributes(req *http.Request, statusCode int, addition } attributes := slices.Grow(additionalAttributes, num) - attributes = append(attributes, + attributes = append( + attributes, semconv.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)), semconv.ServerAddress(requestHost), n.scheme(req), @@ -248,7 +279,10 @@ func (o MetricOpts) AddOptions() metric.AddOption { } func (n HTTPClient) MetricOptions(ma MetricAttributes) MetricOpts { - attributes := n.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes) + attributes := n.MetricAttributes(ma.Req, ma.Resp, ma.StatusCode, ma.AdditionalAttributes) + if ma.StatusCode == 0 && ma.Err != nil { + attributes = append(attributes, n.ErrorType(ma.Err)) + } set := metric.WithAttributeSet(attribute.NewSet(attributes...)) return MetricOpts{ @@ -257,6 +291,39 @@ func (n HTTPClient) MetricOptions(ma MetricAttributes) MetricOpts { } } +// ErrorType returns an error.type attribute for the given error. The otelhttp +// Transport calls the underlying RoundTripper directly, so transport failures +// arrive as *net.OpError (connection refused, timeout, etc.) rather than +// *url.Error (which http.Client.Do adds above the Transport layer). This +// function intentionally does not unwrap further: reporting a single concrete +// type per failure keeps attribute cardinality bounded, as required by the +// OTel spec (error.type SHOULD have low cardinality). Callers that need +// finer-grained error distinctions should inspect the error themselves. +func (HTTPClient) ErrorType(err error) attribute.KeyValue { + t := reflect.TypeOf(err) + if t == nil { + return semconv.ErrorTypeOther + } + if t.Kind() == reflect.Pointer { + t = t.Elem() + } + var value string + if t.PkgPath() == "" || t.Name() == "" { + // t.PkgPath() == "" covers builtin and unnamed types. + // t.Name() == "" covers anonymous struct types that implement error, + // which are uncommon but possible. Fall back to t.String() for both. + value = t.String() + } else { + value = fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()) + } + + if value == "" { + return semconv.ErrorTypeOther + } + + return semconv.ErrorTypeKey.String(value) +} + func (n HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts MetricOpts) { recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption) defer func() { @@ -270,13 +337,13 @@ func (n HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts Metri } // TraceAttributes returns attributes for httptrace. -func (n HTTPClient) TraceAttributes(host string) []attribute.KeyValue { +func (HTTPClient) TraceAttributes(host string) []attribute.KeyValue { return []attribute.KeyValue{ semconv.ServerAddress(host), } } -func (n HTTPClient) scheme(req *http.Request) attribute.KeyValue { +func (HTTPClient) scheme(req *http.Request) attribute.KeyValue { if req.URL != nil && req.URL.Scheme != "" { return semconv.URLScheme(req.URL.Scheme) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go index a8a0d58df35..fbcd4f6b230 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" +package semconv // Generate semconv package: //go:generate gotmpl --body=../../../../../../internal/shared/semconv/bench_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=bench_test.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go index 83c6ae24653..35e744e41d2 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go @@ -1,12 +1,12 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconv/server.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/semconv/server.go.tmpl + // Package semconv provides OpenTelemetry semantic convention types and // functionality. -package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" +package semconv import ( "context" @@ -20,8 +20,8 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/semconv/v1.40.0" - "go.opentelemetry.io/otel/semconv/v1.40.0/httpconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/httpconv" ) type RequestTraceAttrsOpts struct { @@ -67,7 +67,7 @@ func NewHTTPServer(meter metric.Meter) HTTPServer { // Status returns a span status code and message for an HTTP status code // value returned by a server. Status codes in the 400-499 range are not // returned as errors. -func (n HTTPServer) Status(code int) (codes.Code, string) { +func (HTTPServer) Status(code int) (codes.Code, string) { if code < 100 || code >= 600 { return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code) } @@ -168,7 +168,8 @@ func (n HTTPServer) RequestTraceAttrs(server string, req *http.Request, opts Req } attrs := make([]attribute.KeyValue, 0, count) - attrs = append(attrs, + attrs = append( + attrs, semconv.ServerAddress(host), method, scheme, @@ -216,7 +217,7 @@ func (n HTTPServer) RequestTraceAttrs(server string, req *http.Request, opts Req return attrs } -func (s HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue { +func (HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue { attr := semconv.NetworkTransportPipe switch network { case "tcp", "tcp4", "tcp6": @@ -239,10 +240,15 @@ type ServerMetricData struct { } type MetricAttributes struct { - Req *http.Request + Req *http.Request + // Resp is the client response, if any. It is only consulted by + // HTTPClient.MetricAttributes to source the negotiated protocol version; + // server-side metric recording ignores it. + Resp *http.Response StatusCode int Route string AdditionalAttributes []attribute.KeyValue + Err error } type MetricData struct { @@ -250,13 +256,11 @@ type MetricData struct { RequestDuration time.Duration } -var ( - metricRecordOptionPool = &sync.Pool{ - New: func() any { - return &[]metric.RecordOption{} - }, - } -) +var metricRecordOptionPool = &sync.Pool{ + New: func() any { + return &[]metric.RecordOption{} + }, +} func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { attributes := n.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.Route, md.AdditionalAttributes) @@ -270,9 +274,27 @@ func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { metricRecordOptionPool.Put(recordOpts) } -func (n HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { +// SpanName returns the span name for an HTTP request following the +// OpenTelemetry HTTP semantic conventions. +// It returns "{method} {route}" when the request has a pattern, +// or just "{method}" when no route is available. +// Non-standard HTTP methods are replaced by "HTTP". +func (HTTPServer) SpanName(r *http.Request) string { + method := strings.ToUpper(r.Method) + if _, ok := methodLookup[method]; !ok { + method = "HTTP" + } + + route := httpRoute(r.Pattern) + if route != "" { + return method + " " + route + } + return method +} + +func (HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { if method == "" { - return semconv.HTTPRequestMethodGet, attribute.KeyValue{} + return semconv.HTTPRequestMethodOther, attribute.KeyValue{} } if attr, ok := methodLookup[method]; ok { return attr, attribute.KeyValue{} @@ -282,7 +304,7 @@ func (n HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValu if attr, ok := methodLookup[strings.ToUpper(method)]; ok { return attr, orig } - return semconv.HTTPRequestMethodGet, orig + return semconv.HTTPRequestMethodOther, orig } func (n HTTPServer) scheme(https bool) attribute.KeyValue { //nolint:revive // ignore linter @@ -297,7 +319,7 @@ func (n HTTPServer) scheme(https bool) attribute.KeyValue { //nolint:revive // i // // If any of the fields in the ResponseTelemetry are not set the attribute will // be omitted. -func (n HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { +func (HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue { var count int if resp.ReadBytes > 0 { @@ -313,17 +335,20 @@ func (n HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyVa attributes := make([]attribute.KeyValue, 0, count) if resp.ReadBytes > 0 { - attributes = append(attributes, + attributes = append( + attributes, semconv.HTTPRequestBodySize(int(resp.ReadBytes)), ) } if resp.WriteBytes > 0 { - attributes = append(attributes, + attributes = append( + attributes, semconv.HTTPResponseBodySize(int(resp.WriteBytes)), ) } if resp.StatusCode > 0 { - attributes = append(attributes, + attributes = append( + attributes, semconv.HTTPResponseStatusCode(resp.StatusCode), ) } @@ -332,7 +357,7 @@ func (n HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyVa } // Route returns the attribute for the route. -func (n HTTPServer) Route(route string) attribute.KeyValue { +func (HTTPServer) Route(route string) attribute.KeyValue { return semconv.HTTPRoute(route) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go index 2eab2ecabde..0de0bd83c45 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/semconv/util.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/semconv/util.go.tmpl + +package semconv import ( "net" @@ -15,7 +15,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - semconvNew "go.opentelemetry.io/otel/semconv/v1.40.0" + semconvNew "go.opentelemetry.io/otel/semconv/v1.43.0" ) // SplitHostPort splits a network address hostport of the form "host", @@ -32,29 +32,29 @@ func SplitHostPort(hostport string) (host string, port int) { addrEnd := strings.LastIndexByte(hostport, ']') if addrEnd < 0 { // Invalid hostport. - return + return host, port } if i := strings.LastIndexByte(hostport[addrEnd:], ':'); i < 0 { host = hostport[1:addrEnd] - return + return host, port } } else { if i := strings.LastIndexByte(hostport, ':'); i < 0 { host = hostport - return + return host, port } } host, pStr, err := net.SplitHostPort(hostport) if err != nil { - return + return host, port } p, err := strconv.ParseUint(pStr, 10, 16) if err != nil { - return + return host, port } - return host, int(p) //nolint:gosec // Byte size checked 16 above. + return host, int(p) } func requiredHTTPPort(https bool, port int) int { //nolint:revive // ignore linter @@ -84,7 +84,7 @@ func httpRoute(pattern string) string { return "" } -func netProtocol(proto string) (name string, version string) { +func netProtocol(proto string) (name, version string) { name, version, _ = strings.Cut(proto, "/") switch name { case "HTTP": diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go index d62ce44b002..8362b824687 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp import ( "context" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go index 9476ef01b01..9b6c0a889ba 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp import ( "context" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go index d8d204d1f8a..82501eab325 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go @@ -1,10 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp import ( "context" + "fmt" "io" "net/http" "net/http/httptrace" @@ -15,7 +16,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/propagation" - otelsemconv "go.opentelemetry.io/otel/semconv/v1.40.0" + otelsemconv "go.opentelemetry.io/otel/semconv/v1.43.0" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request" @@ -142,6 +143,9 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { t.propagators.Inject(ctx, propagation.HeaderCarrier(r.Header)) res, err := t.rt.RoundTrip(r) + if err == nil { + res, err = ensureResponseBody(t.rt, r, res) + } // Record the metrics on error or no error. statusCode := 0 @@ -160,7 +164,9 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { }, t.semconv.MetricOptions(semconv.MetricAttributes{ Req: r, + Resp: res, StatusCode: statusCode, + Err: err, AdditionalAttributes: append(labeler.Get(), t.metricAttributesFromRequest(r)...), }), ) @@ -182,6 +188,20 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { return res, nil } +func ensureResponseBody(rt http.RoundTripper, r *http.Request, res *http.Response) (*http.Response, error) { + switch { + case res == nil: + return nil, fmt.Errorf("http: RoundTripper implementation (%T) returned a nil *Response with a nil error", rt) + case res.Body != nil: + return res, nil + case res.ContentLength > 0 && r.Method != http.MethodHead: + return nil, fmt.Errorf("http: RoundTripper implementation (%T) returned a *Response with content length %d but a nil Body", rt, res.ContentLength) + default: + res.Body = http.NoBody + return res, nil + } +} + func (t *Transport) metricAttributesFromRequest(r *http.Request) []attribute.KeyValue { var attributeForRequest []attribute.KeyValue if t.metricAttributesFn != nil { diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go index 835ec5aa7e8..b757d6e9d03 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +package otelhttp // Version is the current release version of the otelhttp instrumentation. -const Version = "0.68.0" +const Version = "0.70.0" diff --git a/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/idgenerator.go b/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/idgenerator.go index df439448b57..7058ff45bfc 100644 --- a/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/idgenerator.go +++ b/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/idgenerator.go @@ -1,14 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package xray // import "go.opentelemetry.io/contrib/propagators/aws/xray" +package xray import ( "context" - crand "crypto/rand" "encoding/binary" "encoding/hex" - "math/rand" + "math/rand/v2" "strconv" "sync" "time" @@ -18,19 +17,27 @@ import ( ) // IDGenerator is used for generating a new traceID and spanID. +// +// math/rand/v2's top-level generator is used instead of a per-instance +// math/rand.Rand seeded from crypto/rand: the former is safe for concurrent +// use without a mutex and, unlike a locally seeded math/rand.Rand, has no +// seed-read step that can silently fail and leave it deterministic. type IDGenerator struct { + // Mutex is embedded for backward compatibility but is not used internally. sync.Mutex - randSource *rand.Rand } var _ sdktrace.IDGenerator = &IDGenerator{} // NewSpanID returns a non-zero span ID from a randomly-chosen sequence. -func (gen *IDGenerator) NewSpanID(context.Context, trace.TraceID) trace.SpanID { - gen.Lock() - defer gen.Unlock() +func (gen *IDGenerator) NewSpanID(context.Context, trace.TraceID) trace.SpanID { //nolint:revive // ignore linter sid := trace.SpanID{} - _, _ = gen.randSource.Read(sid[:]) + for { + binary.NativeEndian.PutUint64(sid[:], rand.Uint64()) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand) is ignored as this is not security-sensitive. + if sid.IsValid() { + break + } + } return sid } @@ -39,27 +46,26 @@ func (gen *IDGenerator) NewSpanID(context.Context, trace.TraceID) trace.SpanID { // - https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids // // span ID is from a randomly-chosen sequence. -func (gen *IDGenerator) NewIDs(context.Context) (trace.TraceID, trace.SpanID) { - gen.Lock() - defer gen.Unlock() - +func (gen *IDGenerator) NewIDs(context.Context) (trace.TraceID, trace.SpanID) { //nolint:revive // ignore linter tid := trace.TraceID{} currentTime := getCurrentTimeHex() copy(tid[:4], currentTime) - _, _ = gen.randSource.Read(tid[4:]) + binary.NativeEndian.PutUint64(tid[4:12], rand.Uint64()) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand) is ignored as this is not security-sensitive. + binary.NativeEndian.PutUint32(tid[12:16], rand.Uint32()) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand) is ignored as this is not security-sensitive. sid := trace.SpanID{} - _, _ = gen.randSource.Read(sid[:]) + for { + binary.NativeEndian.PutUint64(sid[:], rand.Uint64()) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand) is ignored as this is not security-sensitive. + if sid.IsValid() { + break + } + } return tid, sid } // NewIDGenerator returns an IDGenerator reference used for sending traces to AWS X-Ray. func NewIDGenerator() *IDGenerator { - gen := &IDGenerator{} - var rngSeed int64 - _ = binary.Read(crand.Reader, binary.LittleEndian, &rngSeed) - gen.randSource = rand.New(rand.NewSource(rngSeed)) //nolint:gosec // G404: Use of weak random number generator (math/rand instead of crypto/rand) is ignored as this is not security-sensitive. - return gen + return &IDGenerator{} } func getCurrentTimeHex() []uint8 { diff --git a/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/propagator.go b/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/propagator.go index 8929bf05ff3..59f17c5ec41 100644 --- a/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/propagator.go +++ b/vendor/go.opentelemetry.io/contrib/propagators/aws/xray/propagator.go @@ -3,7 +3,7 @@ // Package xray provides an OpenTelemetry propagator for the AWS XRAY // propagation format. -package xray // import "go.opentelemetry.io/contrib/propagators/aws/xray" +package xray import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index 8a7f1ec5d99..a0ba70805eb 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -143,8 +143,7 @@ linters: - name: constant-logical-expr - name: context-as-argument arguments: - - allow-types-before: '*testing.T' - disabled: true + - allow-types-before: '*testing.T,*testing.B' - name: context-keys-type - name: deep-exit - name: defer diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 2db588ea27d..4d473a1e85d 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -11,6 +11,34 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +## [1.46.0/0.68.0/0.22.0/0.0.19] - 2026-08-25 + +This release is the last to support [Go 1.25]. +The next release will require at least [Go 1.26]. + +### Added + +- Support testing of [Go 1.27]. (#8811) +- Support `http/json` protocol in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#8273, #8775, #8831) +- Add `Hasher` struct and methods in `go.opentelemetry.io/otel/attribute` to compute authoritative `Distinct` hashes incrementally for attribute filtering and deduplication. (#8598) + +### Changed + +- Lazily evaluate filtered and dropped attributes on measurement hot paths in `go.opentelemetry.io/otel/sdk/metric` to avoid unnecessary attribute set allocations. (#8598) +- Add `ErrExporterShutdown` to `go.opentelemetry.io/otel/sdk/log` and return it from the `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` exporters when `Export` is called after `Shutdown`. (#8773) +- Clarify in `go.opentelemetry.io/otel/log` that calling `Logger.Enabled` is optional and that cached results can become stale. (#8764) + +### Fixed + +- Export dropped attribute counts in OTLP log records from `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8829) +- Name span events created from OpenTracing logs after the `event` log field, falling back to `log`, instead of always using an empty name in `go.opentelemetry.io/otel/bridge/opentracing`. (#8648) +- Count exception attributes omitted due to the attribute count limit as dropped in `go.opentelemetry.io/otel/sdk/log`. (#8796) +- Prevent log record and instrumentation scope attributes with empty keys from reaching processors and exporters in `go.opentelemetry.io/otel/sdk/log`. (#8797) +- Fix a data race when span attributes are read concurrently in `go.opentelemetry.io/otel/sdk/trace`. (#8706) +- Prevent a panic in `(*Set).Filter` when called on a nil receiver in `go.opentelemetry.io/otel/attribute`. (#8792) +- The simple span and log processors record `otel.sdk.processor.{span,log}.processed` when the record is submitted to the exporter instead of after the export completes, and no longer set `error.type` from the export outcome, in `go.opentelemetry.io/otel/sdk/trace` and `go.opentelemetry.io/otel/sdk/log`. (#8705) +- Prevent `Resource.MarshalLog` from panicking on nil resources in `go.opentelemetry.io/otel/sdk/resource`. (#8758) + ## [1.45.0/0.67.0/0.21.0/0.0.18] - 2026-08-03 ### Added @@ -3782,7 +3810,8 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.45.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.46.0...HEAD +[1.46.0/0.68.0/0.22.0/0.0.19]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.46.0 [1.45.0/0.67.0/0.21.0/0.0.18]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.45.0 [1.44.0/0.66.0/0.20.0/0.0.17]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.44.0 [1.43.0/0.65.0/0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.43.0 @@ -3887,6 +3916,7 @@ It contains api and sdk for trace and meter. +[Go 1.27]: https://go.dev/doc/go1.27 [Go 1.26]: https://go.dev/doc/go1.26 [Go 1.25]: https://go.dev/doc/go1.25 [Go 1.24]: https://go.dev/doc/go1.24 diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index d4711257dff..c674ef8a177 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -69,8 +69,13 @@ $(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease GOVULNCHECK = $(TOOLS)/govulncheck $(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck +AFFECTEDMODS = $(TOOLS)/affectedmods +AFFECTEDMODS_FILES := $(sort $(shell find $(TOOLS_MOD_DIR)/affectedmods -type f)) +$(TOOLS)/affectedmods: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/affectedmods +$(TOOLS)/affectedmods: $(AFFECTEDMODS_FILES) + .PHONY: tools -tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) +tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) $(AFFECTEDMODS) # Virtualized python tools via docker @@ -125,9 +130,11 @@ go-work: $(CROSSLINK) # Build -.PHONY: build +.PHONY: build cross-build build: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%) +# Cross-platform builds cannot execute the binaries produced by build-tests (go test), so use a compile-only target. +cross-build: $(OTEL_GO_MOD_DIRS:%=build/%) build/%: DIR=$* build/%: @echo "$(GO) build $(DIR)/..." \ @@ -163,6 +170,9 @@ test/%: | grep -v third_party \ | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS) +.PHONY: test-tools +test-tools: test/$(TOOLS_MOD_DIR) + COVERAGE_MODE = atomic COVERAGE_PROFILE = coverage.out .PHONY: test-coverage @@ -187,15 +197,23 @@ benchmark/%: # sdk/metric is split into two shards to work around CodSpeed limitations. # See https://github.com/CodSpeedHQ/codspeed-go/issues/56 -BENCHMARK_SHARDS := $(filter-out ./sdk/metric,$(OTEL_GO_MOD_DIRS)) ./sdk/metric/root ./sdk/metric/internal -benchmark/./sdk/metric/root: +BENCHMARK_SHARDS := $(filter-out ./sdk/metric,$(OTEL_GO_MOD_DIRS)) ./sdk/metric/. ./sdk/metric/internal +benchmark/./sdk/metric/.: cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) . ./exemplar/... -benchmark/./sdk/metric/internal: - cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) ./internal/... print-sharded-benchmarks: @echo $(BENCHMARK_SHARDS) | jq -cR 'split(" ")' +# Print the JSON list of benchmark shards whose code changed since +# BASE_REF (default: main). Filters print-sharded-benchmarks +# down to shards whose underlying module contains a changed *.go file. +# Non-Go changes (docs, workflows, Makefile, go.mod/go.sum, tooling) emit []. +# Override the diff base via BASE_REF, or pass ARGS=-all to emit the full list. +BASE_REF ?= main +.PHONY: print-affected-benchmarks +print-affected-benchmarks: + @$(MAKE) -s print-sharded-benchmarks | $(GO) -C $(TOOLS_MOD_DIR) run ./affectedmods $(if $(strip $(BASE_REF)),-base=$(BASE_REF),) $(ARGS) + .PHONY: golangci-lint golangci-lint-fix golangci-lint-fix: ARGS=--fix golangci-lint-fix: golangci-lint diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index ce97e9a2510..9291d1470d9 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -53,18 +53,25 @@ Currently, this project supports the following environments. | OS | Go Version | Architecture | |----------|------------|--------------| +| Ubuntu | 1.27 | amd64 | | Ubuntu | 1.26 | amd64 | | Ubuntu | 1.25 | amd64 | +| Ubuntu | 1.27 | 386 | | Ubuntu | 1.26 | 386 | | Ubuntu | 1.25 | 386 | +| Ubuntu | 1.27 | arm64 | | Ubuntu | 1.26 | arm64 | | Ubuntu | 1.25 | arm64 | +| macOS | 1.27 | amd64 | | macOS | 1.26 | amd64 | | macOS | 1.25 | amd64 | +| macOS | 1.27 | arm64 | | macOS | 1.26 | arm64 | | macOS | 1.25 | arm64 | +| Windows | 1.27 | amd64 | | Windows | 1.26 | amd64 | | Windows | 1.25 | amd64 | +| Windows | 1.27 | 386 | | Windows | 1.26 | 386 | | Windows | 1.25 | 386 | diff --git a/vendor/go.opentelemetry.io/otel/VERSIONING.md b/vendor/go.opentelemetry.io/otel/VERSIONING.md index b27c9e84f51..56eaa7d2204 100644 --- a/vendor/go.opentelemetry.io/otel/VERSIONING.md +++ b/vendor/go.opentelemetry.io/otel/VERSIONING.md @@ -12,6 +12,12 @@ is designed so the following goals can be achieved. * [Semantic import versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning) will be used. + * Stable module compatibility is understood in terms of the [Go 1 + compatibility guidelines](https://go.dev/doc/go1compat). Code that + compiled against an older version of a package should continue to compile + against newer versions of that package, subject to the exceptions in the + Go 1 compatibility guidelines and any additional exceptions documented + below. * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions. * New methods may be added to exported API interfaces. All exported diff --git a/vendor/go.opentelemetry.io/otel/attribute/hash.go b/vendor/go.opentelemetry.io/otel/attribute/hash.go index f651eb13d90..54c26e67a05 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/hash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/hash.go @@ -33,19 +33,71 @@ const ( emptyID uint64 = 7305809155345288421 // "__empty_" (little endian) ) +// Hasher computes a Distinct value from KeyValue attributes supplied with +// Write. +// +// A Hasher must be obtained from [NewHasher]. The zero value is not usable and +// its methods will panic. +type Hasher struct { + h xxhash.Hash +} + +// NewHasher returns a new Hasher. +func NewHasher() *Hasher { + return &Hasher{h: xxhash.New()} +} + +// Reset resets h to its initial state so it can be reused. +func (h *Hasher) Reset() { + h.h.Reset() +} + +// Write adds kv to the hash. +// +// Write requires attributes to be supplied in ascending key order with no +// duplicate keys. To produce the same Distinct as Set.Equivalent, write +// attributes in ascending key order, with no more than one value for each key. +// If the source contains duplicate keys, retain the last value for each key +// before calling Write. +func (h *Hasher) Write(kv KeyValue) { + // hashKV mutates the digest h.h refers to in place and returns the same + // Hash value it was passed. Discarding the result keeps the digest pointer + // from flowing back into h, which would force the digest to be heap + // allocated for every Hasher. Keeping Write this small also keeps it within + // the inlining budget, which matters because hashKVs calls it per attribute. + _ = hashKV(h.h, kv) +} + +// Distinct returns the identifier for the attributes written to h. When Write +// is called as described above, it returns the same value as [Set.Equivalent]. +func (h *Hasher) Distinct() Distinct { + // No count of written attributes is needed to detect the empty case. The + // sum of a digest with nothing written to it is emptyHash, which is + // non-zero (0xef46db3751d8e999), so it passes through remapZeroHash + // unchanged and matches emptySet.Equivalent. + return Distinct{hash: remapZeroHash(h.h.Sum64())} +} + +// remapZeroHash remaps a 0 sum to a non-zero value, because hash == 0 is a +// reserved sentinel (treated as empty/invalid). +func remapZeroHash(sum uint64) uint64 { + if sum == 0 { + return 1 + } + return sum +} + // hashKVs returns a new xxHash64 hash of kvs. +// +// This routes through [Hasher] so that Set hashing and Hasher cannot disagree: +// there is exactly one implementation of how attributes are mixed and how the +// final sum is framed. func hashKVs(kvs []KeyValue) uint64 { - h := xxhash.New() + h := NewHasher() for _, kv := range kvs { - h = hashKV(h, kv) + h.Write(kv) } - sum := h.Sum64() - // Remap 0 to a non-zero value for non-empty input because hash == 0 is a reserved sentinel (treated as empty/invalid). - const remappedZeroHash uint64 = 1 - if sum == 0 && len(kvs) > 0 { - return remappedZeroHash - } - return sum + return h.Distinct().hash } // hashKV returns the xxHash64 hash of kv with h as the base. diff --git a/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go b/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go index c851179ccaa..4fcdd2dbea7 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go @@ -62,3 +62,8 @@ func (h Hash) String(val string) Hash { func (h Hash) Sum64() uint64 { return h.d.Sum64() } + +// Reset resets the hash to its initial state. +func (h Hash) Reset() { + h.d.Reset() +} diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go index 87d6f96200d..56a70a9f6d6 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/set.go +++ b/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -313,6 +313,9 @@ func filteredToFront(slice []KeyValue, keep Filter) int { // Filter returns a filtered copy of this Set. See the documentation for // NewSetWithSortableFiltered for more details. func (l *Set) Filter(re Filter) (Set, []KeyValue) { + if l == nil { + return emptySet, nil + } if re == nil { return *l, nil } diff --git a/vendor/go.opentelemetry.io/otel/bridge/opentracing/bridge.go b/vendor/go.opentelemetry.io/otel/bridge/opentracing/bridge.go index 3519223e052..ae23f2d1131 100644 --- a/vendor/go.opentelemetry.io/otel/bridge/opentracing/bridge.go +++ b/vendor/go.opentelemetry.io/otel/bridge/opentracing/bridge.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "maps" + "slices" "strconv" "strings" "sync" @@ -116,10 +117,11 @@ func (s *bridgeSpan) FinishWithOptions(opts ot.FinishOptions) { } func (s *bridgeSpan) logRecord(record ot.LogRecord) { + attrs := otLogFieldsToOTelAttrs(record.Fields) s.otelSpan.AddEvent( - "", + otelEventName(attrs), trace.WithTimestamp(record.Timestamp), - trace.WithAttributes(otLogFieldsToOTelAttrs(record.Fields)...), + trace.WithAttributes(attrs...), ) } @@ -156,9 +158,10 @@ func (s *bridgeSpan) SetTag(key string, value any) ot.Span { } func (s *bridgeSpan) LogFields(fields ...otlog.Field) { + attrs := otLogFieldsToOTelAttrs(fields) s.otelSpan.AddEvent( - "", - trace.WithAttributes(otLogFieldsToOTelAttrs(fields)...), + otelEventName(attrs), + trace.WithAttributes(attrs...), ) } @@ -224,6 +227,31 @@ func otLogFieldsToOTelAttrs(fields []otlog.Field) []attribute.KeyValue { return encoder.pairs } +// eventNameKey is the OpenTracing log field conventionally carrying the name +// of the logged event. +const eventNameKey = attribute.Key("event") + +// defaultEventName is used when a log field set carries no usable +// eventNameKey field. +const defaultEventName = "log" + +// otelEventName returns the OTel event name for a set of converted OpenTracing +// log fields: the value of the last eventNameKey attribute, falling back to +// defaultEventName. An event name is semantically required to be non-empty, so +// an empty value is treated as absent. +func otelEventName(attrs []attribute.KeyValue) string { + for _, attr := range slices.Backward(attrs) { + if attr.Key != eventNameKey { + continue + } + if name := attr.Value.String(); name != "" { + return name + } + return defaultEventName + } + return defaultEventName +} + func (s *bridgeSpan) LogKV(alternatingKeyValues ...any) { fields, err := otlog.InterleavedKVToFields(alternatingKeyValues...) if err != nil { diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go index 3c1a625c067..d97fada29fb 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" +package otlptrace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/doc.go index 09ad5eadb6f..5fd4bf5bb55 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/doc.go @@ -7,4 +7,4 @@ See the official OTLP span exporter implementations: - [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc], - [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp]. */ -package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" +package otlptrace diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go index 30446bd28b6..037d485d5e0 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" +package otlptrace import ( "context" @@ -97,9 +97,9 @@ func NewUnstarted(client Client) *Exporter { func (e *Exporter) MarshalLog() any { return struct { Type string - Client Client + Client string }{ Type: "otlptrace", - Client: e.client, + Client: fmt.Sprintf("%T", e.client), } } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go index 0d43a5dc5b7..86a34d3b9fb 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go @@ -3,7 +3,7 @@ // Package tracetransform provides conversion functionality for the otlptrace // exporters. -package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" +package tracetransform import ( commonpb "go.opentelemetry.io/proto/otlp/common/v1" @@ -97,6 +97,12 @@ func Value(v attribute.Value) *commonpb.AnyValue { Values: values(v.AsSlice()), }, } + case attribute.MAP: + av.Value = &commonpb.AnyValue_KvlistValue{ + KvlistValue: &commonpb.KeyValueList{ + Values: KeyValues(v.AsMap()), + }, + } case attribute.STRINGSLICE: av.Value = &commonpb.AnyValue_ArrayValue{ ArrayValue: &commonpb.ArrayValue{ diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go index 43359c89449..078a9db0ab9 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" +package tracetransform import ( commonpb "go.opentelemetry.io/proto/otlp/common/v1" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go index 526bb5e070b..14e5bdc5630 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" +package tracetransform import ( resourcepb "go.opentelemetry.io/proto/otlp/resource/v1" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go index d431fc4517d..3ab14b54fd1 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" +package tracetransform import ( "math" @@ -37,21 +37,22 @@ func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans { } rKey := sd.Resource().Equivalent() + scope := sd.InstrumentationScope() k := key{ r: rKey, - is: sd.InstrumentationScope(), + is: scope, } scopeSpan, iOk := ssm[k] if !iOk { // Either the resource or instrumentation scope were unknown. scopeSpan = &tracepb.ScopeSpans{ - Scope: InstrumentationScope(sd.InstrumentationScope()), + Scope: InstrumentationScope(scope), Spans: []*tracepb.Span{}, - SchemaUrl: sd.InstrumentationScope().SchemaURL, + SchemaUrl: scope.SchemaURL, } + ssm[k] = scopeSpan } scopeSpan.Spans = append(scopeSpan.Spans, span(sd)) - ssm[k] = scopeSpan rs, rOk := rsm[rKey] if !rOk { @@ -90,14 +91,16 @@ func span(sd tracesdk.ReadOnlySpan) *tracepb.Span { return nil } - tid := sd.SpanContext().TraceID() - sid := sd.SpanContext().SpanID() + spanContext := sd.SpanContext() + tid := spanContext.TraceID() + sid := spanContext.SpanID() + sdStatus := sd.Status() s := &tracepb.Span{ TraceId: tid[:], SpanId: sid[:], - TraceState: sd.SpanContext().TraceState().String(), - Status: status(sd.Status().Code, sd.Status().Description), + TraceState: spanContext.TraceState().String(), + Status: status(sdStatus.Code, sdStatus.Description), StartTimeUnixNano: uint64(max(0, sd.StartTime().UnixNano())), // nolint:gosec // Overflow checked. EndTimeUnixNano: uint64(max(0, sd.EndTime().UnixNano())), // nolint:gosec // Overflow checked. Links: links(sd.Links()), @@ -110,10 +113,11 @@ func span(sd tracesdk.ReadOnlySpan) *tracepb.Span { DroppedLinksCount: clampUint32(sd.DroppedLinks()), } - if psid := sd.Parent().SpanID(); psid.IsValid() { + sdParent := sd.Parent() + if psid := sdParent.SpanID(); psid.IsValid() { s.ParentSpanId = psid[:] } - s.Flags = buildSpanFlagsWith(sd.SpanContext().TraceFlags(), sd.Parent()) + s.Flags = buildSpanFlagsWith(spanContext.TraceFlags(), sdParent) return s } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go index e8b33d3fa55..494bece44ea 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" +package otlptracegrpc import ( "context" @@ -328,12 +328,10 @@ func throttleDelay(s *status.Status) (bool, time.Duration) { } // MarshalLog is the marshaling function used by the logging system to represent this Client. -func (c *client) MarshalLog() any { +func (*client) MarshalLog() any { return struct { - Type string - Endpoint string + Type string }{ - Type: "otlptracegrpc", - Endpoint: c.endpoint, + Type: "otlptracegrpc", } } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/doc.go index b7bd429ffdf..b01358fc83c 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/doc.go @@ -62,4 +62,4 @@ The configuration can be overridden by [WithTLSCredentials], [WithGRPCConn] opti [W3C Baggage HTTP Header Content Format]: https://www.w3.org/TR/baggage/#header-content */ -package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" +package otlptracegrpc diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go index b826b84247e..d75b18443d3 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" +package otlptracegrpc import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter/counter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter/counter.go index 323b2a2c9a6..57c6acb781d 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter/counter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter/counter.go @@ -1,14 +1,14 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/counter/counter.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/counter/counter.go.tmpl + // Package counter provides a simple counter for generating unique IDs. // // This package is used to generate unique IDs while allowing testing packages // to reset the counter. -package counter // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter" +package counter import "sync/atomic" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go index 6eacdf311d2..87764a6952d 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig/envconfig.go @@ -1,12 +1,12 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/envconfig/envconfig.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/envconfig/envconfig.go.tmpl + // Package envconfig provides functionality to parse configuration from // environment variables. -package envconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig" +package envconfig import ( "crypto/tls" @@ -60,7 +60,7 @@ func WithString(n string, fn func(string)) func(e *EnvOptionsReader) { func WithBool(n string, fn func(bool)) ConfigFn { return func(e *EnvOptionsReader) { if v, ok := e.GetEnvValue(n); ok { - b := strings.ToLower(v) == "true" + b := strings.EqualFold(v, "true") fn(b) } } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go index 7fe9c9f3a33..ec16d01457f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/gen.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal functionally for the otlptracegrpc package. -package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal" +package internal //go:generate gotmpl --body=../../../../../internal/shared/otlp/partialsuccess.go.tmpl "--data={}" --out=partialsuccess.go //go:generate gotmpl --body=../../../../../internal/shared/otlp/partialsuccess_test.go.tmpl "--data={}" --out=partialsuccess_test.go @@ -27,8 +27,8 @@ package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/ot //go:generate gotmpl --body=../../../../../internal/shared/x/x.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\" }" --out=x/x.go //go:generate gotmpl --body=../../../../../internal/shared/x/x_test.go.tmpl "--data={}" --out=x/x_test.go -//go:generate gotmpl --body=../../../../../internal/shared/otlp/observ/target.go.tmpl "--data={ \"pkg\": \"observ\", \"pkg_path\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ\" }" --out=observ/target.go +//go:generate gotmpl --body=../../../../../internal/shared/otlp/observ/target.go.tmpl "--data={ \"pkg\": \"observ\" }" --out=observ/target.go //go:generate gotmpl --body=../../../../../internal/shared/otlp/observ/target_test.go.tmpl "--data={ \"pkg\": \"observ\" }" --out=observ/target_test.go -//go:generate gotmpl --body=../../../../../internal/shared/counter/counter.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/counter\" }" --out=counter/counter.go +//go:generate gotmpl --body=../../../../../internal/shared/counter/counter.go.tmpl "--data={}" --out=counter/counter.go //go:generate gotmpl --body=../../../../../internal/shared/counter/counter_test.go.tmpl "--data={}" --out=counter/counter_test.go diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/doc.go index 0dd54e4b969..32188bf72be 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/doc.go @@ -3,4 +3,4 @@ // Package observ provides experimental observability instrumentation for the // otlptracegrpc exporter. -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ" +package observ diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/instrumentation.go index 676a93514bd..d6730bc1ecd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/instrumentation.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ" +package observ import ( "context" @@ -18,8 +18,8 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x" "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/metric" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/otelconv" ) const ( diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/target.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/target.go index 34eee27db0d..3bd37988298 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/target.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/target.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/observ/target.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/observ/target.go.tmpl + +package observ import ( "errors" @@ -21,13 +21,13 @@ const ( ) // ParseCanonicalTarget parses a target string and returns the extracted host -// (domain address or IP), the target port, or an error. +// (domain name or IP address), the target port, or an error. // // If no port is specified, -1 is returned. // // If no host is specified, an empty string is returned. // -// The target string is expected to always have the form +// The target string must have the form // "://[authority]/". For example: // - "dns:///example.com:42" // - "dns://8.8.8.8/example.com:42" @@ -35,17 +35,16 @@ const ( // - "unix-abstract:///socket-name" // - "passthrough:///192.34.2.1:42" // -// The target is expected to come from the CanonicalTarget method of a gRPC -// Client. +// The target is expected to be returned by gRPC's ClientConn.CanonicalTarget +// method. func ParseCanonicalTarget(target string) (string, int, error) { const sep = "://" // Find scheme. Do not allocate the string by using url.Parse. - idx := strings.Index(target, sep) - if idx == -1 { + scheme, endpoint, found := strings.Cut(target, sep) + if !found { return "", -1, fmt.Errorf("invalid target %q: missing scheme", target) } - scheme, endpoint := target[:idx], target[idx+len(sep):] // Check for unix schemes. if scheme == schemeUnix || scheme == schemeUnixAbstract { @@ -61,7 +60,7 @@ func ParseCanonicalTarget(target string) (string, int, error) { return parseEndpoint(endpoint) } -// parseUnix parses unix socket targets. +// parseUnix parses Unix socket targets. func parseUnix(endpoint string) (string, int, error) { // Format: unix[-abstract]://path // @@ -71,8 +70,8 @@ func parseUnix(endpoint string) (string, int, error) { return endpoint, -1, nil } - // If there's no leading slash, it means there might be an authority - // Check for authority case (should error): "authority/path" + // If there is no leading slash, an authority might be present, which is + // invalid. Check for this case: "authority/path". if slashIdx := strings.Index(endpoint, "/"); slashIdx > 0 { return "", -1, fmt.Errorf("invalid (non-empty) authority: %s", endpoint[:slashIdx]) } @@ -98,8 +97,8 @@ func parseUnix(endpoint string) (string, int, error) { // - "[ipv6]:port" // - "[ipv6%zone]:port" // -// It returns the host or host%zone (domain address or IP), the port (or -1 if -// not specified), or an error if the input is not a valid. +// It returns the host or host%zone (domain name or IP address), the port (or +// -1 if not specified), or an error if the input is invalid. func parseEndpoint(endpoint string) (string, int, error) { // First check if the endpoint is just an IP address. if ip := parseIP(endpoint); ip != "" { diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go index 1d840be205b..3bfc2a6f3fc 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/envconfig.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlptrace/otlpconfig/envconfig.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlptrace/otlpconfig/envconfig.go.tmpl + +package otlpconfig import ( "crypto/tls" @@ -49,31 +49,37 @@ func getOptionsFromEnv() []GenericOption { tlsConf := &tls.Config{} DefaultEnvOptionsReader.Apply( envconfig.WithURL("ENDPOINT", func(u *url.URL) { - opts = append(opts, withEndpointScheme(u)) - opts = append(opts, newSplitOption(func(cfg Config) Config { - cfg.Traces.Endpoint = u.Host - // For OTLP/HTTP endpoint URLs without a per-signal - // configuration, the passed endpoint is used as a base URL - // and the signals are sent to these paths relative to that. - cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath) - return cfg - }, withEndpointForGRPC(u))) + opts = append( + opts, + withEndpointScheme(u), + newSplitOption(func(cfg Config) Config { + cfg.Traces.Endpoint = u.Host + // For OTLP/HTTP endpoint URLs without a per-signal + // configuration, the passed endpoint is used as a base URL + // and the signals are sent to these paths relative to that. + cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath) + return cfg + }, withEndpointForGRPC(u)), + ) }), envconfig.WithURL("TRACES_ENDPOINT", func(u *url.URL) { - opts = append(opts, withEndpointScheme(u)) - opts = append(opts, newSplitOption(func(cfg Config) Config { - cfg.Traces.Endpoint = u.Host - // For endpoint URLs for OTLP/HTTP per-signal variables, the - // URL MUST be used as-is without any modification. The only - // exception is that if an URL contains no path part, the root - // path / MUST be used. - path := u.Path - if path == "" { - path = "/" - } - cfg.Traces.URLPath = path - return cfg - }, withEndpointForGRPC(u))) + opts = append( + opts, + withEndpointScheme(u), + newSplitOption(func(cfg Config) Config { + cfg.Traces.Endpoint = u.Host + // For endpoint URLs for OTLP/HTTP per-signal variables, the + // URL MUST be used as-is without any modification. The only + // exception is that if an URL contains no path part, the root + // path / MUST be used. + path := u.Path + if path == "" { + path = "/" + } + cfg.Traces.URLPath = path + return cfg + }, withEndpointForGRPC(u)), + ) }), envconfig.WithCertPool("CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), envconfig.WithCertPool("TRACES_CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), @@ -94,6 +100,8 @@ func getOptionsFromEnv() []GenericOption { envconfig.WithHeaders("TRACES_HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }), WithEnvCompression("COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), WithEnvCompression("TRACES_COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }), + WithEnvProtocol("PROTOCOL", func(p Protocol) { opts = append(opts, WithProtocol(p)) }), + WithEnvProtocol("TRACES_PROTOCOL", func(p Protocol) { opts = append(opts, WithProtocol(p)) }), envconfig.WithDuration("TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), envconfig.WithDuration("TRACES_TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }), ) @@ -133,6 +141,25 @@ func WithEnvCompression(n string, fn func(Compression)) func(e *envconfig.EnvOpt } } +// WithEnvProtocol retrieves the specified config and passes it to ConfigFn as a Protocol. +func WithEnvProtocol(n string, fn func(Protocol)) func(e *envconfig.EnvOptionsReader) { + return func(e *envconfig.EnvOptionsReader) { + if v, ok := e.GetEnvValue(n); ok { + protocol := ProtocolHTTPProtobuf + switch v { + case "grpc": + protocol = ProtocolGRPC + case "http/protobuf": + protocol = ProtocolHTTPProtobuf + case "http/json": + protocol = ProtocolHTTPJSON + } + + fn(protocol) + } + } +} + // revive:disable-next-line:flag-parameter func withInsecure(b bool) GenericOption { if b { @@ -142,7 +169,7 @@ func withInsecure(b bool) GenericOption { } func withTLSConfig(c *tls.Config, fn func(*tls.Config)) func(e *envconfig.EnvOptionsReader) { - return func(e *envconfig.EnvOptionsReader) { + return func(*envconfig.EnvOptionsReader) { if c.RootCAs != nil || len(c.Certificates) > 0 { fn(c) } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go index d940b67625f..a56847a3b4f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options.go @@ -1,11 +1,11 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlptrace/otlpconfig/options.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlptrace/otlpconfig/options.go.tmpl + // Package otlpconfig provides configuration for the otlptrace exporters. -package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" +package otlpconfig import ( "crypto/tls" @@ -50,6 +50,7 @@ type ( TLSCfg *tls.Config Headers map[string]string Compression Compression + Protocol Protocol MaxRequestSize int Timeout time.Duration URLPath string @@ -84,6 +85,7 @@ func NewHTTPConfig(opts ...HTTPOption) Config { Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorHTTPPort), URLPath: DefaultTracesPath, Compression: NoCompression, + Protocol: ProtocolHTTPProtobuf, MaxRequestSize: DefaultMaxRequestSize, Timeout: DefaultTimeout, }, @@ -99,7 +101,7 @@ func NewHTTPConfig(opts ...HTTPOption) Config { // cleanPath returns a path with all spaces trimmed. If urlPath is empty, // defaultPath is returned instead. -func cleanPath(urlPath string, defaultPath string) string { +func cleanPath(urlPath, defaultPath string) string { tmp := strings.TrimSpace(urlPath) if tmp == "" || tmp == "." { return defaultPath @@ -119,6 +121,7 @@ func NewGRPCConfig(opts ...GRPCOption) Config { Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort), URLPath: DefaultTracesPath, Compression: NoCompression, + Protocol: ProtocolGRPC, MaxRequestSize: DefaultMaxRequestSize, Timeout: DefaultTimeout, }, @@ -134,7 +137,7 @@ func NewGRPCConfig(opts ...GRPCOption) Config { cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultServiceConfig(cfg.ServiceConfig)) } // Prioritize GRPCCredentials over Insecure (passing both is an error). - if cfg.Traces.GRPCCredentials != nil { + if cfg.Traces.GRPCCredentials != nil { //nolint:gocritic // if-else is clearer than switch cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(cfg.Traces.GRPCCredentials)) } else if cfg.Traces.Insecure { cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(insecure.NewCredentials())) @@ -228,7 +231,7 @@ func (g *splitOption) ApplyHTTPOption(cfg Config) Config { func (splitOption) private() {} -func newSplitOption(httpFn func(cfg Config) Config, grpcFn func(cfg Config) Config) GenericOption { +func newSplitOption(httpFn, grpcFn func(cfg Config) Config) GenericOption { return &splitOption{httpFn: httpFn, grpcFn: grpcFn} } @@ -286,6 +289,11 @@ func WithEndpointURL(v string) GenericOption { cfg.Traces.Endpoint = u.Host cfg.Traces.URLPath = u.Path + if cfg.Traces.URLPath == "" { + // For HTTP exporters, a URL without a path targets the root path. Set it explicitly so the default signal + // path is not appended by cleanPath. (URLPath is ignored by gRPC exporters.) + cfg.Traces.URLPath = "/" + } cfg.Traces.Insecure = u.Scheme != "https" return cfg @@ -371,3 +379,25 @@ func WithHTTPClient(c *http.Client) GenericOption { return cfg }) } + +func WithProtocol(protocol Protocol) GenericOption { + return newSplitOption( + // For OTLP/HTTP endpoints, this is the encoding format of the payloads sent to the collector. + func(cfg Config) Config { + if protocol == ProtocolGRPC { + global.Warn("grpc is not a valid protocol for OTLP/HTTP, defaulting to http/protobuf") + protocol = ProtocolHTTPProtobuf + } + cfg.Traces.Protocol = protocol + return cfg + }, + // For OTLP/gRPC endpoints, it's always "grpc". + func(cfg Config) Config { + if protocol != ProtocolGRPC { + global.Debug("protocol option is ignored for OTLP/gRPC and is set to grpc") + } + cfg.Traces.Protocol = ProtocolGRPC + return cfg + }, + ) +} diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go index 91849038722..4f2da74275b 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/optiontypes.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlptrace/otlpconfig/optiontypes.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlptrace/otlpconfig/optiontypes.go.tmpl + +package otlpconfig const ( // DefaultCollectorGRPCPort is the default gRPC port of the collector. @@ -38,3 +38,15 @@ const ( // MarshalJSON tells the driver to send using json format. MarshalJSON ) + +// Protocol describes the transport protocol used to send data to the collector. +type Protocol int + +const ( + // ProtocolGRPC describes the "grpc" protocol. + ProtocolGRPC Protocol = iota + // ProtocolHTTPProtobuf describes the "http/protobuf" protocol. + ProtocolHTTPProtobuf + // ProtocolHTTPJSON describes the "http/json" protocol. + ProtocolHTTPJSON +) diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go index ba6e411835f..a14d5e6ecfe 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/tls.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlptrace/otlpconfig/tls.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlptrace/otlpconfig/tls.go.tmpl + +package otlpconfig import ( "crypto/tls" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go index a811a07b352..1138f2e718b 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/partialsuccess.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/partialsuccess.go - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/partialsuccess.go + +package internal import "fmt" @@ -41,7 +41,7 @@ func (ps PartialSuccess) As(target any) bool { } // Is supports the errors.Is() interface. -func (ps PartialSuccess) Is(err error) bool { +func (PartialSuccess) Is(err error) bool { _, ok := err.(PartialSuccess) return ok } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go index a7b8e81a786..468c7c8eb9f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry/retry.go @@ -1,13 +1,13 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/retry/retry.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/retry/retry.go.tmpl + // Package retry provides request retry functionality that can perform // configurable exponential backoff for transient errors and honor any // explicit throttle responses received. -package retry // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry" +package retry import ( "context" @@ -17,7 +17,7 @@ import ( "github.com/cenkalti/backoff/v5" ) -// DefaultConfig are the recommended defaults to use. +// DefaultConfig is the recommended default configuration. var DefaultConfig = Config{ Enabled: true, InitialInterval: 5 * time.Second, @@ -25,42 +25,40 @@ var DefaultConfig = Config{ MaxElapsedTime: time.Minute, } -// Config defines configuration for retrying batches in case of export failure -// using an exponential backoff. +// Config defines configuration for retrying batches after an export failure +// using exponential backoff. type Config struct { - // Enabled indicates whether to not retry sending batches in case of - // export failure. + // Enabled indicates whether to retry sending batches after an export + // failure. Enabled bool - // InitialInterval the time to wait after the first failure before + // InitialInterval is the time to wait after the first failure before // retrying. InitialInterval time.Duration - // MaxInterval is the upper bound on backoff interval. Once this value is - // reached the delay between consecutive retries will always be - // `MaxInterval`. + // MaxInterval is the upper bound on the backoff interval before + // randomization. Once this value is reached, the base interval remains at + // MaxInterval. MaxInterval time.Duration // MaxElapsedTime is the maximum amount of time (including retries) spent - // trying to send a request/batch. Once this value is reached, the data - // is discarded. + // trying to send a request/batch. Once this value is reached, retrying stops. MaxElapsedTime time.Duration } // RequestFunc wraps a request with retry logic. type RequestFunc func(context.Context, func(context.Context) error) error -// EvaluateFunc returns if an error is retry-able and if an explicit throttle -// duration should be honored that was included in the error. +// EvaluateFunc reports whether an error is retryable and returns any explicit +// throttle duration to honor. // -// The function must return true if the error argument is retry-able, -// otherwise it must return false for the first return parameter. +// The function must return true as its first return value if the error +// argument is retryable; otherwise, it must return false. // -// The function must return a non-zero time.Duration if the error contains -// explicit throttle duration that should be honored, otherwise it must return -// a zero valued time.Duration. +// The function must return a nonzero time.Duration if the error contains an +// explicit throttle duration that should be honored; otherwise, it must return +// the zero value for time.Duration. type EvaluateFunc func(error) (bool, time.Duration) -// RequestFunc returns a RequestFunc using the evaluate function to determine -// if requests can be retried and based on the exponential backoff -// configuration of c. +// RequestFunc returns a RequestFunc that uses evaluate to determine whether +// requests can be retried and uses c to configure exponential backoff. func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { if !c.Enabled { return func(ctx context.Context, fn func(context.Context) error) error { @@ -96,7 +94,7 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { // Check if context is canceled before attempting to wait and retry. if ctx.Err() != nil { - return fmt.Errorf("%w: %w", ctx.Err(), err) + return fmt.Errorf("%w: %w", context.Cause(ctx), err) } if maxElapsedTime != 0 && time.Since(startTime) > maxElapsedTime { @@ -119,12 +117,12 @@ func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc { } } -// Allow override for testing. +// waitFunc can be overridden for testing. var waitFunc = wait -// wait takes the caller's context, and the amount of time to wait. It will -// return nil if the timer fires before or at the same time as the context's -// deadline. This indicates that the call can be retried. +// wait blocks until delay elapses or ctx is done. If both happen +// simultaneously, wait favors the elapsed delay and returns nil to indicate +// that the call can be retried. func wait(ctx context.Context, delay time.Duration) error { timer := time.NewTimer(delay) defer timer.Stop() diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/version.go index 28e51e443fc..d26674e57e7 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/version.go @@ -1,8 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal" +package internal // Version is the current release version of the OpenTelemetry OTLP gRPC trace // exporter in use. -const Version = "1.44.0" +const Version = "1.46.0" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/observ.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/observ.go index 4e89c6524f0..76b6fdebdb0 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/observ.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/observ.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package x // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x" +package x import "strings" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/x.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/x.go index 741ba62c97f..71011358c2f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x/x.go @@ -1,11 +1,11 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/x/x.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/x/x.go.tmpl + // Package x documents experimental features for [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc]. -package x // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x" +package x import ( "os" @@ -34,9 +34,9 @@ func newFeature[T any](suffix []string, parse func(string) (T, bool)) Feature[T] // feature. func (f Feature[T]) Keys() []string { return f.keys } -// Lookup returns the user configured value for the feature and true if the +// Lookup returns the user-configured value for the feature and true if the // user has enabled the feature. Otherwise, if the feature is not enabled, a -// zero-value and false are returned. +// zero value and false are returned. func (f Feature[T]) Lookup() (v T, ok bool) { // https://github.com/open-telemetry/opentelemetry-specification/blob/62effed618589a0bec416a87e559c0a9d96289bb/specification/configuration/sdk-environment-variables.md#parsing-empty-value // diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go index b320060525e..ea20363c05f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" +package otlptracegrpc import ( "fmt" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go index d847210dbaf..fd8ee8102e9 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go @@ -1,9 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" +package otlptrace // Version is the current release version of the OpenTelemetry OTLP trace exporter in use. func Version() string { - return "1.44.0" + return "1.46.0" } diff --git a/vendor/go.opentelemetry.io/otel/renovate.json b/vendor/go.opentelemetry.io/otel/renovate.json index fa5acf2d3bd..5008ab2bf16 100644 --- a/vendor/go.opentelemetry.io/otel/renovate.json +++ b/vendor/go.opentelemetry.io/otel/renovate.json @@ -15,6 +15,13 @@ "matchDepTypes": ["indirect"], "enabled": true }, + { + "description": "Disable Go module major updates to v2+", + "matchManagers": ["gomod"], + "matchUpdateTypes": ["major"], + "matchNewValue": "/^v?([2-9]|[1-9][0-9]+)\\./", + "enabled": false + }, { "matchPackageNames": ["go.opentelemetry.io/build-tools/**"], "groupName": "build-tools" diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go index a4faa6a03d5..39b34eabeae 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go @@ -10,4 +10,4 @@ // and // https://github.com/open-telemetry/oteps/blob/d226b677d73a785523fe9b9701be13225ebc528d/text/0201-scope-attributes.md // for more information. -package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation" +package instrumentation diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go index f2cdf3c6518..8baf8dbb359 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go +++ b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation" +package instrumentation // Library represents the instrumentation library. // diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go index 34852a47b21..1fd06db75b7 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go +++ b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation" +package instrumentation import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/dedup.go b/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/dedup.go new file mode 100644 index 00000000000..fe9ddc96db7 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/dedup.go @@ -0,0 +1,300 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/attrnorm/dedup.go.tmpl + +// Package attrnorm normalizes attribute values. +package attrnorm + +import ( + "reflect" + "unsafe" + + "go.opentelemetry.io/otel/attribute" +) + +var ( + keyValueType = reflect.TypeFor[attribute.KeyValue]() + valueType = reflect.TypeFor[attribute.Value]() +) + +// rawValue mirrors attribute.Value. It is used only to read immutable slice +// storage without calling AsMap or AsSlice on no-op paths. +type rawValue struct { + vtype attribute.Type + numeric uint64 + stringly string + slice any +} + +// Value returns value with all map values deduplicated and whether it changed. +// +// Duplicate map keys are resolved using last-value-wins semantics. +func Value(value attribute.Value) (attribute.Value, bool) { + switch value.Type() { + case attribute.SLICE: + return deduplicateSliceValue(value) + case attribute.MAP: + return deduplicateMapValue(value) + default: + return value, false + } +} + +// KeyValue returns kv with all map values deduplicated and whether it changed. +func KeyValue(kv attribute.KeyValue) (attribute.KeyValue, bool) { + value, changed := Value(kv.Value) + if changed { + kv.Value = value + } + return kv, changed +} + +// KeyValues returns kvs with all map values deduplicated and whether they changed. +// +// The returned slice is the original kvs slice if no value needs +// deduplication. Top-level keys in kvs are not deduplicated. +func KeyValues(kvs []attribute.KeyValue) ([]attribute.KeyValue, bool) { + // Preserve the caller's slice on the common no-op path. Once a changed + // value is found, copy the prior values exactly once and fill the rest in + // place as the scan continues. + var normalized []attribute.KeyValue + for i, kv := range kvs { + kv, changed := KeyValue(kv) + if normalized != nil { + normalized[i] = kv + continue + } + if !changed { + continue + } + + normalized = make([]attribute.KeyValue, len(kvs)) + copy(normalized, kvs[:i]) + normalized[i] = kv + } + if normalized == nil { + return kvs, false + } + return normalized, true +} + +// Set returns set with all map values deduplicated and whether it changed. +// +// The returned Set is the original set if no value needs deduplication. +// Top-level key uniqueness remains attribute.Set's responsibility; this only +// normalizes map attribute values. +func Set(set attribute.Set) (attribute.Set, bool) { + if set.Len() == 0 { + return set, false + } + + // Most attribute sets contain no duplicate map keys. Delay allocation until + // the first changed value so the no-op path returns the original Set. + var normalized []attribute.KeyValue + for i := range set.Len() { + kv, _ := set.Get(i) + kv, changed := KeyValue(kv) + if normalized != nil { + normalized = append(normalized, kv) + continue + } + if !changed { + continue + } + + normalized = make([]attribute.KeyValue, 0, set.Len()) + for j := range i { + prior, _ := set.Get(j) + normalized = append(normalized, prior) + } + normalized = append(normalized, kv) + } + if normalized == nil { + return set, false + } + + return attribute.NewSet(normalized...), true +} + +func deduplicateSliceValue(value attribute.Value) (attribute.Value, bool) { + storage := valueStorage(value) + length := valueLen(storage) + + // Slice values can contain map values, so recurse into each element while + // keeping the original attribute.Value when no element changes. + var normalized []attribute.Value + for i := range length { + elem := valueAt(storage, i) + elem, changed := Value(elem) + if normalized != nil { + normalized[i] = elem + continue + } + if !changed { + continue + } + + normalized = make([]attribute.Value, length) + for j := range i { + normalized[j] = valueAt(storage, j) + } + normalized[i] = elem + } + if normalized == nil { + return value, false + } + return attribute.SliceValue(normalized...), true +} + +func deduplicateMapValue(value attribute.Value) (attribute.Value, bool) { + storage := valueStorage(value) + length := keyValueLen(storage) + if length <= 1 { + // A single map entry cannot duplicate its own key, but its value might + // contain a map or slice that needs recursive normalization. + if length == 1 { + kv, changed := KeyValue(keyValueAt(storage, 0)) + if changed { + return attribute.MapValue(kv), true + } + } + return value, false + } + + var normalized []attribute.KeyValue + for i := 0; i < length; { + // attribute.MapValue stores key-values sorted by key using a stable + // sort. Equal keys therefore form a contiguous run, and the last + // element in that run is the last value provided by the caller. + first := keyValueAt(storage, i) + j := i + 1 + for j < length && keyValueAt(storage, j).Key == first.Key { + j++ + } + + kv, nestedChanged := KeyValue(keyValueAt(storage, j-1)) + // j-i > 1 means the current key run contained duplicates. + changed := nestedChanged || j-i > 1 + if normalized != nil { + normalized = append(normalized, kv) + } else if changed { + normalized = make([]attribute.KeyValue, 0, length) + for k := range i { + normalized = append(normalized, keyValueAt(storage, k)) + } + normalized = append(normalized, kv) + } + i = j + } + if normalized == nil { + return value, false + } + return attribute.MapValue(normalized...), true +} + +func valueStorage(value attribute.Value) any { + // attribute.Value does not expose allocation-free map/slice iteration. + // The raw mirror lets us read the immutable backing array directly and + // reserve AsMap/AsSlice-style allocation for paths that actually change. + return (*rawValue)( + unsafe.Pointer(&value), + ).slice //nolint:gosec // Read-only mirror of attribute.Value for allocation-free iteration. +} + +func valueLen(storage any) int { + // attribute.Value stores small slices in fixed-size array values. Handle + // the common sizes directly and fall back to reflection for larger arrays. + switch storage.(type) { + case [0]attribute.Value: + return 0 + case [1]attribute.Value: + return 1 + case [2]attribute.Value: + return 2 + case [3]attribute.Value: + return 3 + case [4]attribute.Value: + return 4 + case [5]attribute.Value: + return 5 + default: + return arrayLen(storage, valueType) + } +} + +func valueAt(storage any, i int) attribute.Value { + switch values := storage.(type) { + case [1]attribute.Value: + return values[i] + case [2]attribute.Value: + return values[i] + case [3]attribute.Value: + return values[i] + case [4]attribute.Value: + return values[i] + case [5]attribute.Value: + return values[i] + default: + return arrayAt[attribute.Value](storage, valueType, i) + } +} + +func keyValueLen(storage any) int { + // attribute.Value stores small maps in fixed-size key-value arrays. Handle + // the common sizes directly and fall back to reflection for larger arrays. + switch storage.(type) { + case [0]attribute.KeyValue: + return 0 + case [1]attribute.KeyValue: + return 1 + case [2]attribute.KeyValue: + return 2 + case [3]attribute.KeyValue: + return 3 + case [4]attribute.KeyValue: + return 4 + case [5]attribute.KeyValue: + return 5 + default: + return arrayLen(storage, keyValueType) + } +} + +func keyValueAt(storage any, i int) attribute.KeyValue { + switch kvs := storage.(type) { + case [1]attribute.KeyValue: + return kvs[i] + case [2]attribute.KeyValue: + return kvs[i] + case [3]attribute.KeyValue: + return kvs[i] + case [4]attribute.KeyValue: + return kvs[i] + case [5]attribute.KeyValue: + return kvs[i] + default: + return arrayAt[attribute.KeyValue](storage, keyValueType, i) + } +} + +func arrayLen(storage any, elem reflect.Type) int { + // Be defensive around invalid or unexpected Value storage. Returning zero + // makes malformed storage a no-op instead of panicking in telemetry paths. + array := reflect.ValueOf(storage) + if array.Kind() != reflect.Array || array.Type().Elem() != elem { + return 0 + } + return array.Len() +} + +func arrayAt[T any](storage any, elem reflect.Type, i int) T { + // Match arrayLen's fail-closed behavior for unexpected storage. + array := reflect.ValueOf(storage) + if array.Kind() != reflect.Array || array.Type().Elem() != elem || i < 0 || i >= array.Len() { + var zero T + return zero + } + return array.Index(i).Interface().(T) +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/truncate.go b/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/truncate.go new file mode 100644 index 00000000000..c8341599b38 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/truncate.go @@ -0,0 +1,230 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/attrnorm/truncate.go.tmpl + +package attrnorm + +import ( + "slices" + "strings" + "unicode/utf8" + + "go.opentelemetry.io/otel/attribute" +) + +// Truncate returns a truncated version of attr. Only string, string slice, +// byte slice, slice, and map attribute values are truncated. String values are +// truncated according to limit. Each string slice value is truncated in this +// fashion (the slice length itself is unaffected), and byte slice values are +// truncated to at most limit bytes. For slice and map attribute values, the +// limit is applied recursively to contained values. +// +// No truncation is performed for a negative limit. +func Truncate(limit int, attr attribute.KeyValue) attribute.KeyValue { + if limit < 0 { + return attr + } + switch attr.Value.Type() { + case attribute.STRING: + v := attr.Value.AsString() + return attr.Key.String(truncate(limit, v)) + case attribute.STRINGSLICE: + v := attr.Value.AsStringSlice() + for i := range v { + v[i] = truncate(limit, v[i]) + } + return attr.Key.StringSlice(v) + case attribute.BYTESLICE: + v := attr.Value.AsString() + if len(v) > limit { + return attr.Key.ByteSlice([]byte(v[:limit])) + } + return attr + case attribute.SLICE: + v := attr.Value.AsSlice() + if !slices.ContainsFunc(v, func(e attribute.Value) bool { return needsTruncation(limit, e) }) { + return attr + } + newV := make([]attribute.Value, len(v)) + for i, elem := range v { + newV[i] = TruncateValue(limit, elem) + } + return attr.Key.Slice(newV...) + case attribute.MAP: + v := attr.Value.AsMap() + if !slices.ContainsFunc(v, func(kv attribute.KeyValue) bool { return needsTruncation(limit, kv.Value) }) { + return attr + } + newV := make([]attribute.KeyValue, len(v)) + for i, elem := range v { + elem.Value = TruncateValue(limit, elem.Value) + newV[i] = elem + } + return attr.Key.Map(newV...) + } + return attr +} + +// TruncateValue returns a truncated version of v. Only string, string +// slice, byte slice, and (recursively) slice and map values are modified. +// +// No truncation is performed for a negative limit. +func TruncateValue(limit int, v attribute.Value) attribute.Value { + if limit < 0 { + return v + } + + switch v.Type() { + case attribute.STRING: + return attribute.StringValue(truncate(limit, v.AsString())) + case attribute.STRINGSLICE: + ss := v.AsStringSlice() + for i := range ss { + ss[i] = truncate(limit, ss[i]) + } + return attribute.StringSliceValue(ss) + case attribute.BYTESLICE: + // len(v.AsString()) is identical to len(v.AsByteSlice()) but + // avoids allocating the full slice before truncation. + s := v.AsString() + if limit >= 0 && len(s) > limit { + return attribute.ByteSliceValue([]byte(s[:limit])) + } + case attribute.SLICE: + sl := v.AsSlice() + if !slices.ContainsFunc(sl, func(e attribute.Value) bool { return needsTruncation(limit, e) }) { + return v + } + newSl := make([]attribute.Value, len(sl)) + for i, elem := range sl { + newSl[i] = TruncateValue(limit, elem) + } + return attribute.SliceValue(newSl...) + case attribute.MAP: + m := v.AsMap() + if !slices.ContainsFunc(m, func(kv attribute.KeyValue) bool { return needsTruncation(limit, kv.Value) }) { + return v + } + newM := make([]attribute.KeyValue, len(m)) + for i, elem := range m { + elem.Value = TruncateValue(limit, elem.Value) + newM[i] = elem + } + return attribute.MapValue(newM...) + } + return v +} + +// stringNeedsTruncation reports whether s would be modified by truncate for the +// given limit. +func stringNeedsTruncation(limit int, s string) bool { + if limit < 0 || len(s) <= limit { + return false + } + return utf8.RuneCountInString(s) > limit || !utf8.ValidString(s) +} + +// needsTruncation reports whether v would be modified by TruncateValue for the +// given limit. +func needsTruncation(limit int, v attribute.Value) bool { + switch v.Type() { + case attribute.STRING: + return stringNeedsTruncation(limit, v.AsString()) + case attribute.BYTESLICE: + // len(v.AsString()) is identical to len(v.AsByteSlice()) but + // avoids memory allocation. + if limit >= 0 && len(v.AsString()) > limit { + return true + } + case attribute.STRINGSLICE: + for _, s := range v.AsStringSlice() { + if stringNeedsTruncation(limit, s) { + return true + } + } + case attribute.SLICE: + return slices.ContainsFunc(v.AsSlice(), func(e attribute.Value) bool { return needsTruncation(limit, e) }) + case attribute.MAP: + return slices.ContainsFunc( + v.AsMap(), + func(kv attribute.KeyValue) bool { return needsTruncation(limit, kv.Value) }, + ) + } + return false +} + +// truncate returns a version of s truncated according to limit. +// +// If limit is negative, it returns the original string. +// +// UTF-8 is supported. When truncating, all invalid UTF-8 bytes are dropped +// before applying truncation. +// +// If s already contains at most limit bytes, it is returned unchanged. No +// invalid characters are removed. +func truncate(limit int, s string) string { + // This prioritizes performance in the following order based on the most + // common expected use cases. + // + // - Values shorter than the default limit (128). + // - Strings with valid encodings that exceed the limit. + // - No limit. + // - Strings with invalid encodings that exceed the limit. + if limit < 0 || len(s) <= limit { + return s + } + + // Optimistically, assume all valid UTF-8. + var b strings.Builder + count := 0 + for i, c := range s { + if c != utf8.RuneError { + count++ + if count > limit { + return s[:i] + } + continue + } + + _, size := utf8.DecodeRuneInString(s[i:]) + if size == 1 { + // Invalid encoding. + b.Grow(len(s) - 1) + _, _ = b.WriteString(s[:i]) + s = s[i:] + break + } + } + + // Fast-path, no invalid input. + if b.Cap() == 0 { + return s + } + + // Truncate while validating UTF-8. + for i := 0; i < len(s) && count < limit; { + c := s[i] + if c < utf8.RuneSelf { + // Optimization for single byte runes (common case). + _ = b.WriteByte(c) + i++ + count++ + continue + } + + _, size := utf8.DecodeRuneInString(s[i:]) + if size == 1 { + // We checked for all 1-byte runes above, this is a RuneError. + i++ + continue + } + + _, _ = b.WriteString(s[i : i+size]) + i += size + count++ + } + + return b.String() +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go b/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go index 694b64a3180..13ff34b276f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package x documents experimental features for [go.opentelemetry.io/otel/sdk]. -package x // import "go.opentelemetry.io/otel/sdk/internal/x" +package x import "strings" diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/x/x.go b/vendor/go.opentelemetry.io/otel/sdk/internal/x/x.go index 13347e56052..67eea20a746 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/x/x.go @@ -1,11 +1,11 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/x/x.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/x/x.go.tmpl + // Package x documents experimental features for [go.opentelemetry.io/otel/sdk]. -package x // import "go.opentelemetry.io/otel/sdk/internal/x" +package x import ( "os" @@ -34,9 +34,9 @@ func newFeature[T any](suffix []string, parse func(string) (T, bool)) Feature[T] // feature. func (f Feature[T]) Keys() []string { return f.keys } -// Lookup returns the user configured value for the feature and true if the +// Lookup returns the user-configured value for the feature and true if the // user has enabled the feature. Otherwise, if the feature is not enabled, a -// zero-value and false are returned. +// zero value and false are returned. func (f Feature[T]) Lookup() (v T, ok bool) { // https://github.com/open-telemetry/opentelemetry-specification/blob/62effed618589a0bec416a87e559c0a9d96289bb/specification/configuration/sdk-environment-variables.md#parsing-empty-value // diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go index e6f5cfb2ad9..f52e7ea5421 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/cache.go b/vendor/go.opentelemetry.io/otel/sdk/metric/cache.go index 63b88f08664..1d6f6a089aa 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/cache.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/cache.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "sync" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/config.go b/vendor/go.opentelemetry.io/otel/sdk/metric/config.go index dda4e086db8..444a8cfda91 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/config.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" @@ -157,6 +157,8 @@ func WithView(views ...View) Option { // exemplar reservoir, but the exemplar reservoir makes the final decision of // whether to store an exemplar. // +// The filter must not be nil. +// // By default, the [exemplar.TraceBasedFilter] // is used. Exemplars can be entirely disabled by providing the // [exemplar.AlwaysOffFilter]. diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go index 51e168c7504..61410b33091 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go @@ -86,4 +86,4 @@ // // See [go.opentelemetry.io/otel/sdk/metric/internal/x] for information about // the experimental features. -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/env.go b/vendor/go.opentelemetry.io/otel/sdk/metric/env.go index a6c403797f6..132664a7e61 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/env.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/env.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "os" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar.go index 993f001ae91..fb124052c63 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "reflect" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/doc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/doc.go index 9f238937688..f7e54761769 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/doc.go @@ -3,4 +3,4 @@ // Package exemplar provides an implementation of the OpenTelemetry exemplar // reservoir to be used in metric collection pipelines. -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/exemplar.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/exemplar.go index 1ab69467868..32913a6e5d4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/exemplar.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/exemplar.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import ( "time" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/filter.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/filter.go index b50f5c1531c..a9efd20d1ad 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/filter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/filter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/fixed_size_reservoir.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/fixed_size_reservoir.go index ce97ab1bf72..48f2b464cb8 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/fixed_size_reservoir.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/fixed_size_reservoir.go @@ -1,12 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import ( "context" - "math" - "math/rand/v2" "sync" "time" @@ -26,7 +24,12 @@ func FixedSizeReservoirProvider(k int) ReservoirProvider { // sample each one. If there are more than k, the Reservoir will then randomly // sample all additional measurement with a decreasing probability. func NewFixedSizeReservoir(k int) *FixedSizeReservoir { - return newFixedSizeReservoir(newStorage(k)) + r := &FixedSizeReservoir{ + storage: make([]measurement, k), + } + r.nt.k = k + r.nt.reset() + return r } var _ Reservoir = &FixedSizeReservoir{} @@ -37,43 +40,9 @@ var _ Reservoir = &FixedSizeReservoir{} // additional measurement with a decreasing probability. type FixedSizeReservoir struct { reservoir.ConcurrentSafe - *storage - mu sync.Mutex - - // count is the number of measurement seen. - count int64 - // next is the next count that will store a measurement at a random index - // once the reservoir has been filled. - next int64 - // w is the largest random number in a distribution that is used to compute - // the next next. - w float64 -} - -func newFixedSizeReservoir(s *storage) *FixedSizeReservoir { - r := &FixedSizeReservoir{ - storage: s, - } - if cap(r.measurements) > 0 { - r.reset() - } - return r -} - -// randomFloat64 returns, as a float64, a uniform pseudo-random number in the -// open interval (0.0,1.0). -func (*FixedSizeReservoir) randomFloat64() float64 { - // TODO: Use an algorithm that avoids rejection sampling. For example: - // - // const precision = 1 << 53 // 2^53 - // // Generate an integer in [1, 2^53 - 1] - // v := rand.Uint64() % (precision - 1) + 1 - // return float64(v) / float64(precision) - f := rand.Float64() - for f == 0 { - f = rand.Float64() - } - return f + mu sync.Mutex + storage []measurement + nt nextTracker } // Offer accepts the parameters associated with a measurement. The @@ -88,128 +57,39 @@ func (*FixedSizeReservoir) randomFloat64() float64 { // parameters are the value and dropped (filtered) attributes of the // measurement respectively. func (r *FixedSizeReservoir) Offer(ctx context.Context, t time.Time, n Value, a []attribute.KeyValue) { - if cap(r.measurements) == 0 { + if len(r.storage) == 0 { return } - // The following algorithm is "Algorithm L" from Li, Kim-Hung (4 December - // 1994). "Reservoir-Sampling Algorithms of Time Complexity - // O(n(1+log(N/n)))". ACM Transactions on Mathematical Software. 20 (4): - // 481–493 (https://dl.acm.org/doi/10.1145/198429.198435). - // - // A high-level overview of "Algorithm L": - // 0) Pre-calculate the random count greater than the storage size when - // an exemplar will be replaced. - // 1) Accept all measurements offered until the configured storage size is - // reached. - // 2) Loop: - // a) When the pre-calculate count is reached, replace a random - // existing exemplar with the offered measurement. - // b) Calculate the next random count greater than the existing one - // which will replace another exemplars - // - // The way a "replacement" count is computed is by looking at `n` number of - // independent random numbers each corresponding to an offered measurement. - // Of these numbers the smallest `k` (the same size as the storage - // capacity) of them are kept as a subset. The maximum value in this - // subset, called `w` is used to weight another random number generation - // for the next count that will be considered. - // - // By weighting the next count computation like described, it is able to - // perform a uniformly-weighted sampling algorithm based on the number of - // samples the reservoir has seen so far. The sampling will "slow down" as - // more and more samples are offered so as to reduce a bias towards those - // offered just prior to the end of the collection. - // - // This algorithm is preferred because of its balance of simplicity and - // performance. It will compute three random numbers (the bulk of - // computation time) for each item that becomes part of the reservoir, but - // it does not spend any time on items that do not. In particular it has an - // asymptotic runtime of O(k(1 + log(n/k)) where n is the number of - // measurements offered and k is the reservoir size. - // - // See https://en.wikipedia.org/wiki/Reservoir_sampling for an overview of - // this and other reservoir sampling algorithms. See - // https://github.com/MrAlias/reservoir-sampling for a performance - // comparison of reservoir sampling algorithms. - r.mu.Lock() defer r.mu.Unlock() - if int(r.count) < cap(r.measurements) { - r.store(ctx, int(r.count), t, n, a) - } else if r.count == r.next { - // Overwrite a random existing measurement with the one offered. - idx := int(rand.Int64N(int64(cap(r.measurements)))) - r.store(ctx, idx, t, n, a) - r.advance() + sampled, idx := r.nt.shouldSample() + if sampled { + r.storage[idx].store(ctx, t, n, a) } - r.count++ -} - -// reset resets r to the initial state. -func (r *FixedSizeReservoir) reset() { - // This resets the number of exemplars known. - r.count = 0 - // Random index inserts should only happen after the storage is full. - r.next = int64(cap(r.measurements)) - - // Initial random number in the series used to generate r.next. - // - // This is set before r.advance to reset or initialize the random number - // series. Without doing so it would always be 0 or never restart a new - // random number series. - // - // This maps the uniform random number in (0,1) to a geometric distribution - // over the same interval. The mean of the distribution is inversely - // proportional to the storage capacity. - r.w = math.Exp(math.Log(r.randomFloat64()) / float64(cap(r.measurements))) - - r.advance() -} - -// advance updates the count at which the offered measurement will overwrite an -// existing exemplar. -func (r *FixedSizeReservoir) advance() { - // Calculate the next value in the random number series. - // - // The current value of r.w is based on the max of a distribution of random - // numbers (i.e. `w = max(u_1,u_2,...,u_k)` for `k` equal to the capacity - // of the storage and each `u` in the interval (0,w)). To calculate the - // next r.w we use the fact that when the next exemplar is selected to be - // included in the storage an existing one will be dropped, and the - // corresponding random number in the set used to calculate r.w will also - // be replaced. The replacement random number will also be within (0,w), - // therefore the next r.w will be based on the same distribution (i.e. - // `max(u_1,u_2,...,u_k)`). Therefore, we can sample the next r.w by - // computing the next random number `u` and take r.w as `w * u^(1/k)`. - r.w *= math.Exp(math.Log(r.randomFloat64()) / float64(cap(r.measurements))) - // Use the new random number in the series to calculate the count of the - // next measurement that will be stored. - // - // Given 0 < r.w < 1, each iteration will result in subsequent r.w being - // smaller. This translates here into the next next being selected against - // a distribution with a higher mean (i.e. the expected value will increase - // and replacements become less likely) - // - // Important to note, the new r.next will always be at least 1 more than - // the last r.next. - r.next += int64(math.Log(r.randomFloat64())/math.Log(1-r.w)) + 1 } // Collect returns all the held exemplars. // -// The Reservoir state is preserved after this call. +// The stored exemplars are preserved after this call, but the sampling state is reset. func (r *FixedSizeReservoir) Collect(dest *[]Exemplar) { - if cap(r.measurements) == 0 { + if len(r.storage) == 0 { *dest = (*dest)[:0] return } r.mu.Lock() defer r.mu.Unlock() - r.storage.Collect(dest) + *dest = reset(*dest, len(r.storage), len(r.storage)) + var n int + for i := range r.storage { + if r.storage[i].exemplar(&(*dest)[n]) { + n++ + } + } + *dest = (*dest)[:n] // Call reset here even though it will reset r.count and restart the random // number series. This will persist any old exemplars as long as no new // measurements are offered, but it will also prioritize those new // measurements that are made over the older collection cycle ones. - r.reset() + r.nt.reset() } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/histogram_reservoir.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/histogram_reservoir.go index dacac3ebaec..e1001e4dc74 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/histogram_reservoir.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/histogram_reservoir.go @@ -1,12 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import ( "context" "slices" "sort" + "sync" "time" "go.opentelemetry.io/otel/attribute" @@ -22,29 +23,39 @@ func HistogramReservoirProvider(bounds []float64) ReservoirProvider { } } -// NewHistogramReservoir returns a [HistogramReservoir] that samples the last -// measurement that falls within a histogram bucket. The histogram bucket -// upper-boundaries are define by bounds. +type bucket struct { + mu sync.Mutex + nt nextTracker + measurement +} + +// NewHistogramReservoir returns a [HistogramReservoir] that samples +// measurements that fall within a histogram bucket using Algorithm L. The +// histogram bucket upper-boundaries are defined by bounds. // // The passed bounds must be sorted before calling this function. func NewHistogramReservoir(bounds []float64) *HistogramReservoir { + buckets := make([]bucket, len(bounds)+1) + for i := range buckets { + buckets[i].nt.k = 1 + buckets[i].nt.reset() + } return &HistogramReservoir{ bounds: bounds, - storage: newStorage(len(bounds) + 1), + buckets: buckets, } } var _ Reservoir = &HistogramReservoir{} -// HistogramReservoir is a [Reservoir] that samples the last measurement that -// falls within a histogram bucket. The histogram bucket upper-boundaries are -// define by bounds. +// HistogramReservoir is a [Reservoir] that samples +// measurements that fall within a histogram bucket using Algorithm L. The +// histogram bucket upper-boundaries are defined by bounds. type HistogramReservoir struct { reservoir.ConcurrentSafe - *storage - // bounds are bucket bounds in ascending order. - bounds []float64 + bounds []float64 + buckets []bucket } // Offer accepts the parameters associated with a measurement. The @@ -69,14 +80,31 @@ func (r *HistogramReservoir) Offer(ctx context.Context, t time.Time, v Value, a panic("unknown value type") } - idx := sort.SearchFloat64s(r.bounds, n) + b := &r.buckets[sort.SearchFloat64s(r.bounds, n)] - r.store(ctx, idx, t, v, a) + b.mu.Lock() + defer b.mu.Unlock() + + sampled, _ := b.nt.shouldSample() + if sampled { + b.store(ctx, t, v, a) + } } // Collect returns all the held exemplars. // -// The Reservoir state is preserved after this call. +// The stored exemplars are preserved after this call, but the sampling state is reset. func (r *HistogramReservoir) Collect(dest *[]Exemplar) { - r.storage.Collect(dest) + *dest = reset(*dest, len(r.buckets), len(r.buckets)) + var n int + for i := range r.buckets { + b := &r.buckets[i] + b.mu.Lock() + if b.exemplar(&(*dest)[n]) { + n++ + } + b.nt.reset() + b.mu.Unlock() + } + *dest = (*dest)[:n] } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/next_tracker.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/next_tracker.go new file mode 100644 index 00000000000..da5eb241c81 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/next_tracker.go @@ -0,0 +1,154 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package exemplar + +import ( + "math" + "math/rand/v2" +) + +// nextTracker tracks the next measurement that should be sampled using Algorithm L. +type nextTracker struct { + // count is the number of measurements seen. + count int64 + // next is the next count that will store a measurement at a random index + // once the reservoir has been filled. + next int64 + // w is the largest random number in a distribution that is used to compute + // the next next. + w float64 + // k is the size of the reservoir. + k int +} + +// reset resets the tracker to the initial state for a reservoir of size k. +func (t *nextTracker) reset() { + t.count = 0 + if t.k <= 0 { + return + } + // Random index inserts should only happen after the storage is full. + // -1 accounts for the fact that advance() will unconditionally add 1 to + // t.next below. + t.next = int64(t.k) - 1 + + // Initial random number in the series used to generate t.next. + // + // This is set before t.advance to reset or initialize the random number + // series. Without doing so it would always be 0 or never restart a new + // random number series. + // + // This maps the uniform random number in (0,1) to a geometric distribution + // over the same interval. The mean of the distribution is inversely + // proportional to the storage capacity. + t.w = math.Exp(math.Log(randomFloat64()) / float64(t.k)) + t.advance() +} + +// advance updates the count at which the offered measurement will overwrite an +// existing exemplar. +func (t *nextTracker) advance() { + // Use the current random number in the series to calculate the count of the + // next measurement that will be stored. + // + // Given 0 < t.w < 1, each iteration will result in subsequent t.w being + // smaller. This translates here into the next next being selected against + // a distribution with a higher mean (i.e. the expected value will increase + // and replacements become less likely) + // + // Important to note, the new t.next will always be at least 1 more than + // the last t.next. + t.next += int64(math.Log(randomFloat64())/math.Log(1-t.w)) + 1 + + // Calculate the next value in the random number series. + // + // The current value of t.w is based on the max of a distribution of random + // numbers (i.e. `w = max(u_1,u_2,...,u_k)` for `k` equal to the capacity + // of the storage and each `u` in the interval (0,w)). To calculate the + // next t.w we use the fact that when the next exemplar is selected to be + // included in the storage an existing one will be dropped, and the + // corresponding random number in the set used to calculate t.w will also + // be replaced. The replacement random number will also be within (0,w), + // therefore the next t.w will be based on the same distribution (i.e. + // `max(u_1,u_2,...,u_k)`). Therefore, we can sample the next t.w by + // computing the next random number `u` and take t.w as `w * u^(1/k)`. + t.w *= math.Exp(math.Log(randomFloat64()) / float64(t.k)) +} + +// shouldSample returns true if the measurement should be sampled. +// It also returns the index at which the measurement should be stored. +// +// The following algorithm is "Algorithm L" from Li, Kim-Hung (4 December +// 1994). "Reservoir-Sampling Algorithms of Time Complexity +// O(n(1+log(N/n)))". ACM Transactions on Mathematical Software. 20 (4): +// 481–493 (https://dl.acm.org/doi/10.1145/198429.198435). +// +// A high-level overview of "Algorithm L": +// 0. Pre-calculate the random count greater than the storage size when +// an exemplar will be replaced. +// 1. Accept all measurements offered until the configured storage size is +// reached. +// 2. Loop: +// a) When the pre-calculate count is reached, replace a random +// existing exemplar with the offered measurement. +// b) Calculate the next random count greater than the existing one +// which will replace another exemplars +// +// The way a "replacement" count is computed is by looking at `n` number of +// independent random numbers each corresponding to an offered measurement. +// Of these numbers the smallest `k` (the same size as the storage +// capacity) of them are kept as a subset. The maximum value in this +// subset, called `w` is used to weight another random number generation +// for the next count that will be considered. +// +// By weighting the next count computation like described, it is able to +// perform a uniformly-weighted sampling algorithm based on the number of +// samples the reservoir has seen so far. The sampling will "slow down" as +// more and more samples are offered so as to reduce a bias towards those +// offered just prior to the end of the collection. +// +// This algorithm is preferred because of its balance of simplicity and +// performance. It will compute three random numbers (the bulk of +// computation time) for each item that becomes part of the reservoir, but +// it does not spend any time on items that do not. In particular it has an +// asymptotic runtime of O(k(1 + log(n/k))) where n is the number of +// measurements offered and k is the reservoir size. +// +// See https://en.wikipedia.org/wiki/Reservoir_sampling for an overview of +// this and other reservoir sampling algorithms. See +// https://github.com/MrAlias/reservoir-sampling for a performance +// comparison of reservoir sampling algorithms. +func (t *nextTracker) shouldSample() (bool, int) { + if t.k <= 0 { + return false, 0 + } + if t.count < int64(t.k) { + idx := int(t.count) + t.count++ + return true, idx + } + if t.count == t.next { + idx := 0 + if t.k > 1 { + idx = int(rand.Int64N(int64(t.k))) + } + t.advance() + t.count++ + return true, idx + } + t.count++ + return false, 0 +} + +// randomFloat64 returns a pseudo-random value uniformly selected from +// {k / 2^53 | 1 <= k < 2^53}. +func randomFloat64() float64 { + // rand.Float64 returns a value in [0, 1). Retry in the extremely + // unlikely event that it returns zero to produce a value in (0, 1). + f := rand.Float64() + for f == 0 { + f = rand.Float64() + } + return f +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/reservoir.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/reservoir.go index ba5cd1a6b3d..a6cfdf44f99 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/reservoir.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/reservoir.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/storage.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/storage.go index 790496027da..9a0be05a24a 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/storage.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/storage.go @@ -1,74 +1,41 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import ( "context" - "sync" "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) -// storage is an exemplar storage for [Reservoir] implementations. -type storage struct { - // measurements are the measurements sampled. - // - // This does not use []metricdata.Exemplar because it potentially would - // require an allocation for trace and span IDs in the hot path of Offer. - measurements []measurement -} - -func newStorage(n int) *storage { - return &storage{measurements: make([]measurement, n)} -} - -func (r *storage) store(ctx context.Context, idx int, ts time.Time, v Value, droppedAttr []attribute.KeyValue) { - r.measurements[idx].mux.Lock() - defer r.measurements[idx].mux.Unlock() - r.measurements[idx].FilteredAttributes = droppedAttr - r.measurements[idx].Time = ts - r.measurements[idx].Value = v - r.measurements[idx].Ctx = ctx - r.measurements[idx].valid = true -} - -// Collect returns all the held exemplars. -// -// The Reservoir state is preserved after this call. -func (r *storage) Collect(dest *[]Exemplar) { - *dest = reset(*dest, len(r.measurements), len(r.measurements)) - var n int - for i := range r.measurements { - if r.measurements[i].exemplar(&(*dest)[n]) { - n++ - } - } - *dest = (*dest)[:n] -} - // measurement is a measurement made by a telemetry system. type measurement struct { - mux sync.Mutex // FilteredAttributes are the attributes dropped during the measurement. FilteredAttributes []attribute.KeyValue // Time is the time when the measurement was made. Time time.Time // Value is the value of the measurement. Value Value - // Ctx is the context active when a measurement was made. - Ctx context.Context + // SpanContext is the SpanContext active when a measurement was made. + SpanContext trace.SpanContext valid bool } +func (m *measurement) store(ctx context.Context, ts time.Time, v Value, droppedAttr []attribute.KeyValue) { + m.FilteredAttributes = droppedAttr + m.Time = ts + m.Value = v + m.SpanContext = trace.SpanContextFromContext(ctx) + m.valid = true +} + // exemplar returns m as an [Exemplar]. // returns true if it populated the exemplar. func (m *measurement) exemplar(dest *Exemplar) bool { - m.mux.Lock() - defer m.mux.Unlock() if !m.valid { return false } @@ -77,7 +44,7 @@ func (m *measurement) exemplar(dest *Exemplar) bool { dest.Time = m.Time dest.Value = m.Value - sc := trace.SpanContextFromContext(m.Ctx) + sc := m.SpanContext if sc.HasTraceID() { traceID := sc.TraceID() dest.TraceID = traceID[:] diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/value.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/value.go index 590b089a806..c7d1645b6e9 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/value.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/value.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar" +package exemplar import "math" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/exporter.go b/vendor/go.opentelemetry.io/otel/sdk/metric/exporter.go index 1969cb42cf4..7bec415296f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/exporter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/instrument.go b/vendor/go.opentelemetry.io/otel/sdk/metric/instrument.go index dfb4964d9f8..31f7afef903 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/instrument.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/instrument.go @@ -3,7 +3,7 @@ //go:generate stringer -type=InstrumentKind -trimprefix=InstrumentKind -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" @@ -16,6 +16,7 @@ import ( "go.opentelemetry.io/otel/metric/embedded" "go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" + "go.opentelemetry.io/otel/sdk/metric/internal/attrnorm" ) var zeroScope instrumentation.Scope @@ -180,6 +181,46 @@ func (i instID) normalize() instID { return i } +type rawAttributesOption interface { + RawAttributes() []attribute.KeyValue + Experimental() +} + +func extractRawKVs[T any](opts []T) []attribute.KeyValue { + var rawKVs []attribute.KeyValue + var count int + for _, opt := range opts { + if r, ok := any(opt).(rawAttributesOption); ok { + count++ + if count == 1 { + rawKVs = r.RawAttributes() + } else { + if count == 2 { + // Create a new slice to avoid modifying the original slice from the first option. + rawKVs = append([]attribute.KeyValue(nil), rawKVs...) + } + rawKVs = append(rawKVs, r.RawAttributes()...) + } + } + } + return rawKVs +} + +func resolveAttributes(configAttrs attribute.Set, rawKVs []attribute.KeyValue) attribute.Set { + configAttrs, _ = attrnorm.Set(configAttrs) + if len(rawKVs) == 0 { + return configAttrs + } + rawKVs, _ = attrnorm.KeyValues(rawKVs) + merged := make([]attribute.KeyValue, 0, configAttrs.Len()+len(rawKVs)) + merged = append(merged, configAttrs.ToSlice()...) + // rawKVs are appended after configAttrs, meaning they will override any duplicate keys in configAttrs. + // This behavior is documented in WithUnsafeAttributes. + merged = append(merged, rawKVs...) + // TODO(#7743): Defer computing the full attribute.NewSet. + return attribute.NewSet(merged...) +} + type int64Inst struct { measures []aggregate.Measure[int64] @@ -198,12 +239,14 @@ var ( func (i *int64Inst) Add(ctx context.Context, val int64, opts ...metric.AddOption) { c := metric.NewAddConfig(opts) - i.aggregate(ctx, val, c.Attributes()) + rawKVs := extractRawKVs(opts) + i.aggregate(ctx, val, resolveAttributes(c.Attributes(), rawKVs)) } func (i *int64Inst) Record(ctx context.Context, val int64, opts ...metric.RecordOption) { c := metric.NewRecordConfig(opts) - i.aggregate(ctx, val, c.Attributes()) + rawKVs := extractRawKVs(opts) + i.aggregate(ctx, val, resolveAttributes(c.Attributes(), rawKVs)) } func (i *int64Inst) Enabled(context.Context) bool { @@ -238,12 +281,14 @@ var ( func (i *float64Inst) Add(ctx context.Context, val float64, opts ...metric.AddOption) { c := metric.NewAddConfig(opts) - i.aggregate(ctx, val, c.Attributes()) + rawKVs := extractRawKVs(opts) + i.aggregate(ctx, val, resolveAttributes(c.Attributes(), rawKVs)) } func (i *float64Inst) Record(ctx context.Context, val float64, opts ...metric.RecordOption) { c := metric.NewRecordConfig(opts) - i.aggregate(ctx, val, c.Attributes()) + rawKVs := extractRawKVs(opts) + i.aggregate(ctx, val, resolveAttributes(c.Attributes(), rawKVs)) } func (i *float64Inst) Enabled(context.Context) bool { diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/aggregate.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/aggregate.go index a35f3bcc1bb..98916ae766e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/aggregate.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/aggregate.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" @@ -57,18 +57,17 @@ func (b Builder[N]) resFunc() func(attribute.Set) FilteredExemplarReservoir[N] { return DropReservoir } -type fltrMeasure[N int64 | float64] func(ctx context.Context, value N, fltrAttr attribute.Set, droppedAttr []attribute.KeyValue) +type fltrMeasure[N int64 | float64] func(ctx context.Context, value N, lazy lazyFilteredAttributes) func (b Builder[N]) filter(f fltrMeasure[N]) Measure[N] { if b.Filter != nil { fltr := b.Filter // Copy to make it immutable after assignment. return func(ctx context.Context, n N, a attribute.Set) { - fAttr, dropped := a.Filter(fltr) - f(ctx, n, fAttr, dropped) + f(ctx, n, newLazyFilteredAttributes(a, fltr)) } } return func(ctx context.Context, n N, a attribute.Set) { - f(ctx, n, a, nil) + f(ctx, n, newLazyFilteredAttributes(a, nil)) } } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/atomic.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/atomic.go index eb69e965079..604ee0d56a7 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/atomic.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/atomic.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "math" @@ -221,23 +221,28 @@ func (l *hotColdWaitGroup) swapHotAndWait() uint64 { // limitedSyncMap is a sync.Map which enforces the aggregation limit on // attribute sets and provides a Len() function. -type limitedSyncMap struct { +type limitedSyncMap[V any] struct { sync.Map aggLimit int len int lenMux sync.Mutex } -func (m *limitedSyncMap) LoadOrStoreAttr(fltrAttr attribute.Set, newValue func(attribute.Set) any) any { - actual, loaded := m.Load(fltrAttr.Equivalent()) +// LoadOrStoreAttr performs lookup using lazy.Distinct() on the hot path without +// constructing a Set. If the entry is not found and the aggregation limit has not +// been exceeded, lazy.Set() is called to construct the attribute.Set for storage. +// If the aggregation limit is exceeded, overflowSet is used instead without calling lazy.Set(). +func (m *limitedSyncMap[V]) LoadOrStoreAttr(lazy lazyFilteredAttributes, newValue func(attribute.Set) V) V { + distinct := lazy.Distinct() + actual, loaded := m.Load(distinct) if loaded { - return actual + return actual.(V) } // If the overflow set exists, assume we have already overflowed and don't // bother with the slow path below. actual, loaded = m.Load(overflowSet.Equivalent()) if loaded { - return actual + return actual.(V) } // Slow path: add a new attribute set. m.lenMux.Lock() @@ -246,29 +251,33 @@ func (m *limitedSyncMap) LoadOrStoreAttr(fltrAttr attribute.Set, newValue func(a // re-fetch now that we hold the lock to ensure we don't use the overflow // set unless we are sure the attribute set isn't being written // concurrently. - actual, loaded = m.Load(fltrAttr.Equivalent()) + actual, loaded = m.Load(distinct) if loaded { - return actual + return actual.(V) } + var fltrAttr attribute.Set if m.aggLimit > 0 && m.len >= m.aggLimit-1 { fltrAttr = overflowSet + distinct = overflowSet.Equivalent() + } else { + fltrAttr = lazy.Set() } - actual, loaded = m.LoadOrStore(fltrAttr.Equivalent(), newValue(fltrAttr)) + actual, loaded = m.LoadOrStore(distinct, newValue(fltrAttr)) if !loaded { m.len++ } - return actual + return actual.(V) } -func (m *limitedSyncMap) Clear() { +func (m *limitedSyncMap[V]) Clear() { m.lenMux.Lock() defer m.lenMux.Unlock() m.len = 0 m.Map.Clear() } -func (m *limitedSyncMap) Len() int { +func (m *limitedSyncMap[V]) Len() int { m.lenMux.Lock() defer m.lenMux.Unlock() return m.len diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/doc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/doc.go index 7b7225e6ef9..c0399c4087b 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/doc.go @@ -4,4 +4,4 @@ // Package aggregate provides aggregate types used compute aggregations and // cycle the state of metric measurements made by the SDK. These types and // functionality are meant only for internal SDK use. -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/drop.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/drop.go index 7adfcaf8531..c78bdc6713d 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/drop.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/drop.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" @@ -18,7 +18,7 @@ func DropReservoir[N int64 | float64](attribute.Set) FilteredExemplarReservoir[N type dropRes[N int64 | float64] struct{} // Offer does nothing, all measurements offered will be dropped. -func (*dropRes[N]) Offer(context.Context, N, []attribute.KeyValue) {} +func (*dropRes[N]) Offer(context.Context, N, lazyFilteredAttributes) {} // Collect resets dest. No exemplars will ever be returned. func (*dropRes[N]) Collect(dest *[]exemplar.Exemplar) { diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exemplar.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exemplar.go index 25d709948e9..45b62041925 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exemplar.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exemplar.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "sync" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exponential_histogram.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exponential_histogram.go index 767b1d6dc7d..f539be94228 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exponential_histogram.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exponential_histogram.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" @@ -331,8 +331,7 @@ type expoHistogram[N int64 | float64] struct { func (e *expoHistogram[N]) measure( ctx context.Context, value N, - fltrAttr attribute.Set, - droppedAttr []attribute.KeyValue, + lazy lazyFilteredAttributes, ) { // Ignore NaN and infinity. if math.IsInf(float64(value), 0) || math.IsNaN(float64(value)) { @@ -342,13 +341,17 @@ func (e *expoHistogram[N]) measure( e.valuesMu.Lock() defer e.valuesMu.Unlock() - v, ok := e.values[fltrAttr.Equivalent()] + distinct := lazy.Distinct() + v, ok := e.values[distinct] if !ok { - fltrAttr = e.limit.Attributes(fltrAttr, e.values) - // If we overflowed, make sure we add to the existing overflow series - // if it already exists. - v, ok = e.values[fltrAttr.Equivalent()] + v, ok = e.values[overflowSet.Equivalent()] if !ok { + var fltrAttr attribute.Set + if e.limit.aggLimit > 0 && len(e.values) >= e.limit.aggLimit-1 { + fltrAttr = overflowSet + } else { + fltrAttr = lazy.Set() + } v = newExpoHistogramDataPoint[N](fltrAttr, e.maxSize, e.maxScale, e.noMinMax, e.noSum) r := e.newRes(fltrAttr) _, isDrop := r.(*dropRes[N]) @@ -360,7 +363,7 @@ func (e *expoHistogram[N]) measure( } v.record(value) if !v.dropExemplars { - v.res.Offer(ctx, value, droppedAttr) + v.res.Offer(ctx, value, lazy) } } @@ -412,12 +415,15 @@ func (e *expoHistogram[N]) delta( if !e.noSum { hDPts[i].Sum = val.sum.load() + } else { + hDPts[i].Sum = 0 } - if !e.noMinMax { - if val.minMax.set.Load() { - hDPts[i].Min = metricdata.NewExtrema(val.minMax.minimum.Load()) - hDPts[i].Max = metricdata.NewExtrema(val.minMax.maximum.Load()) - } + if !e.noMinMax && val.minMax.set.Load() { + hDPts[i].Min = metricdata.NewExtrema(val.minMax.minimum.Load()) + hDPts[i].Max = metricdata.NewExtrema(val.minMax.maximum.Load()) + } else { + hDPts[i].Min = metricdata.Extrema[N]{} + hDPts[i].Max = metricdata.Extrema[N]{} } collectExemplars(&hDPts[i].Exemplars, val.res.Collect) @@ -488,12 +494,15 @@ func (e *expoHistogram[N]) cumulative( if !e.noSum { hDPts[i].Sum = val.sum.load() + } else { + hDPts[i].Sum = 0 } - if !e.noMinMax { - if val.minMax.set.Load() { - hDPts[i].Min = metricdata.NewExtrema(val.minMax.minimum.Load()) - hDPts[i].Max = metricdata.NewExtrema(val.minMax.maximum.Load()) - } + if !e.noMinMax && val.minMax.set.Load() { + hDPts[i].Min = metricdata.NewExtrema(val.minMax.minimum.Load()) + hDPts[i].Max = metricdata.NewExtrema(val.minMax.maximum.Load()) + } else { + hDPts[i].Min = metricdata.Extrema[N]{} + hDPts[i].Max = metricdata.Extrema[N]{} } collectExemplars(&hDPts[i].Exemplars, val.res.Collect) diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/filtered_reservoir.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/filtered_reservoir.go index e4f9409bc80..20e26c57d36 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/filtered_reservoir.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/filtered_reservoir.go @@ -1,14 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" "sync" "time" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/metric/exemplar" "go.opentelemetry.io/otel/sdk/metric/internal/reservoir" ) @@ -22,7 +21,10 @@ type FilteredExemplarReservoir[N int64 | float64] interface { // The passed ctx needs to contain any baggage or span that were active // when the measurement was made. This information may be used by the // Reservoir in making a sampling decision. - Offer(ctx context.Context, val N, attr []attribute.KeyValue) + // + // The lazy parameter provides filtered attribute details when sampled, + // allowing dropped attributes to be computed only if the measurement is sampled. + Offer(ctx context.Context, val N, lazy lazyFilteredAttributes) // Collect returns all the held exemplars in the reservoir. Collect(dest *[]exemplar.Exemplar) } @@ -52,10 +54,11 @@ func NewFilteredExemplarReservoir[N int64 | float64]( } } -func (f *filteredExemplarReservoir[N]) Offer(ctx context.Context, val N, attr []attribute.KeyValue) { +func (f *filteredExemplarReservoir[N]) Offer(ctx context.Context, val N, lazy lazyFilteredAttributes) { if f.filter(ctx) { // only record the current time if we are sampling this measurement. ts := time.Now() + attr := lazy.Dropped() if !f.concurrentSafe { f.reservoirMux.Lock() defer f.reservoirMux.Unlock() diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/histogram.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/histogram.go index 50c82ff32f9..89770dc20f5 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/histogram.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/histogram.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" @@ -44,8 +44,6 @@ type histogramPointCounters[N int64 | float64] struct { } func (b *histogramPointCounters[N]) loadCountsInto(into *[]uint64) uint64 { - // TODO (#3047): Making copies for counts incurs a large - // memory allocation footprint. Alternatives should be explored. counts := reset(*into, len(b.counts), len(b.counts)) count := uint64(0) for i := range b.counts { @@ -97,7 +95,7 @@ func (b *histogramPointCounters[N]) mergeIntoAndReset( // nolint:revive // Inten // unused attribute sets do not report in subsequent collect() calls. type deltaHistogram[N int64 | float64] struct { hcwg hotColdWaitGroup - hotColdValMap [2]limitedSyncMap + hotColdValMap [2]limitedSyncMap[*histogramPoint[N]] start time.Time noMinMax bool @@ -109,12 +107,11 @@ type deltaHistogram[N int64 | float64] struct { func (s *deltaHistogram[N]) measure( ctx context.Context, value N, - fltrAttr attribute.Set, - droppedAttr []attribute.KeyValue, + lazy lazyFilteredAttributes, ) { hotIdx := s.hcwg.start() defer s.hcwg.done(hotIdx) - h := s.hotColdValMap[hotIdx].LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + h := s.hotColdValMap[hotIdx].LoadOrStoreAttr(lazy, func(attr attribute.Set) *histogramPoint[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) hPt := &histogramPoint[N]{ @@ -131,7 +128,7 @@ func (s *deltaHistogram[N]) measure( histogramPointCounters: histogramPointCounters[N]{counts: make([]atomic.Uint64, len(s.bounds)+1)}, } return hPt - }).(*histogramPoint[N]) + }) // This search will return an index in the range [0, len(s.bounds)], where // it will return len(s.bounds) if value is greater than the last element @@ -147,7 +144,7 @@ func (s *deltaHistogram[N]) measure( h.total.add(value) } if !h.dropExemplars { - h.res.Offer(ctx, value, droppedAttr) + h.res.Offer(ctx, value, lazy) } } @@ -171,7 +168,7 @@ func newDeltaHistogram[N int64 | float64]( noSum: noSum, bounds: b, newRes: r, - hotColdValMap: [2]limitedSyncMap{ + hotColdValMap: [2]limitedSyncMap[*histogramPoint[N]]{ {aggLimit: limit}, {aggLimit: limit}, }, @@ -212,13 +209,16 @@ func (s *deltaHistogram[N]) collect( if !s.noSum { hDPts[i].Sum = val.total.load() + } else { + hDPts[i].Sum = 0 } - if !s.noMinMax { - if val.minMax.set.Load() { - hDPts[i].Min = metricdata.NewExtrema(val.minMax.minimum.Load()) - hDPts[i].Max = metricdata.NewExtrema(val.minMax.maximum.Load()) - } + if !s.noMinMax && val.minMax.set.Load() { + hDPts[i].Min = metricdata.NewExtrema(val.minMax.minimum.Load()) + hDPts[i].Max = metricdata.NewExtrema(val.minMax.maximum.Load()) + } else { + hDPts[i].Min = metricdata.Extrema[N]{} + hDPts[i].Max = metricdata.Extrema[N]{} } collectExemplars(&hDPts[i].Exemplars, val.res.Collect) @@ -249,7 +249,7 @@ func (s *deltaHistogram[N]) collect( // to reading. Unlike deltaHistogram, this maintains a single map so that the // preserved attribute sets do not change when collect() is called. type cumulativeHistogram[N int64 | float64] struct { - values limitedSyncMap + values limitedSyncMap[*hotColdHistogramPoint[N]] start time.Time noMinMax bool @@ -278,17 +278,16 @@ func newCumulativeHistogram[N int64 | float64]( noSum: noSum, bounds: b, newRes: r, - values: limitedSyncMap{aggLimit: limit}, + values: limitedSyncMap[*hotColdHistogramPoint[N]]{aggLimit: limit}, } } func (s *cumulativeHistogram[N]) measure( ctx context.Context, value N, - fltrAttr attribute.Set, - droppedAttr []attribute.KeyValue, + lazy lazyFilteredAttributes, ) { - h := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + h := s.values.LoadOrStoreAttr(lazy, func(attr attribute.Set) *hotColdHistogramPoint[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) hPt := &hotColdHistogramPoint[N]{ @@ -313,7 +312,7 @@ func (s *cumulativeHistogram[N]) measure( }, } return hPt - }).(*hotColdHistogramPoint[N]) + }) // This search will return an index in the range [0, len(s.bounds)], where // it will return len(s.bounds) if value is greater than the last element @@ -333,7 +332,7 @@ func (s *cumulativeHistogram[N]) measure( h.hotColdPoint[hotIdx].total.add(value) } if !h.dropExemplars { - h.res.Offer(ctx, value, droppedAttr) + h.res.Offer(ctx, value, lazy) } } @@ -350,9 +349,16 @@ func (s *cumulativeHistogram[N]) collect( // Do not allow modification of our copy of bounds. bounds := slices.Clone(s.bounds) - // Values are being concurrently written while we iterate, so only use the - // current length for capacity. - hDPts := reset(h.DataPoints, 0, s.values.Len()) + // Pre-size hDPts so per-series destination slots are addressable by index. + // This lets loadCountsInto and collectExemplars reuse each slot's existing + // BucketCounts/Exemplars slices from the previous cycle. s.values is + // append-only here during cumulative collect, and limitedSyncMap only + // increments its len after a successful underlying LoadOrStore, so Range + // will visit at least n entries. Concurrent measurers may add more between + // Len() and Range; those extra slots are appended on demand inside the + // loop. + n := s.values.Len() + hDPts := reset(h.DataPoints, n, n) perSeriesStartTimeEnabled := x.PerSeriesStartTimestamps.Enabled() @@ -366,35 +372,41 @@ func (s *cumulativeHistogram[N]) collect( } // swap, observe, and clear the point readIdx := val.hcwg.swapHotAndWait() - var bucketCounts []uint64 - count := val.hotColdPoint[readIdx].loadCountsInto(&bucketCounts) - newPt := metricdata.HistogramDataPoint[N]{ - Attributes: val.attrs, - StartTime: startTime, - Time: t, - Count: count, - Bounds: bounds, - // The HistogramDataPoint field values returned need to be copies of - // the histogramPoint value as we will keep updating them. - BucketCounts: bucketCounts, - } + // Concurrent writers can grow s.values between Len() and Range. + // Cold-path grow. + if i >= len(hDPts) { + hDPts = append(hDPts, metricdata.HistogramDataPoint[N]{}) + } + dp := &hDPts[i] + + count := val.hotColdPoint[readIdx].loadCountsInto(&dp.BucketCounts) + dp.Attributes = val.attrs + dp.StartTime = startTime + dp.Time = t + dp.Count = count + dp.Bounds = bounds if !s.noSum { - newPt.Sum = val.hotColdPoint[readIdx].total.load() + dp.Sum = val.hotColdPoint[readIdx].total.load() + } else { + // Slot may be reused; clear stale Sum from previous series. + var zero N + dp.Sum = zero } - if !s.noMinMax { - if val.hotColdPoint[readIdx].minMax.set.Load() { - newPt.Min = metricdata.NewExtrema(val.hotColdPoint[readIdx].minMax.minimum.Load()) - newPt.Max = metricdata.NewExtrema(val.hotColdPoint[readIdx].minMax.maximum.Load()) - } + if !s.noMinMax && val.hotColdPoint[readIdx].minMax.set.Load() { + dp.Min = metricdata.NewExtrema(val.hotColdPoint[readIdx].minMax.minimum.Load()) + dp.Max = metricdata.NewExtrema(val.hotColdPoint[readIdx].minMax.maximum.Load()) + } else { + // Slot may be reused; clear stale Min/Max from previous series. + dp.Min = metricdata.Extrema[N]{} + dp.Max = metricdata.Extrema[N]{} } // Once we've read the point, merge it back into the hot histogram // point since it is cumulative. hotIdx := (readIdx + 1) % 2 val.hotColdPoint[readIdx].mergeIntoAndReset(&val.hotColdPoint[hotIdx], s.noMinMax, s.noSum) - collectExemplars(&newPt.Exemplars, val.res.Collect) - hDPts = append(hDPts, newPt) + collectExemplars(&dp.Exemplars, val.res.Collect) i++ // TODO (#3006): This will use an unbounded amount of memory if there diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lastvalue.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lastvalue.go index 2af252ec5df..ad68fac8d41 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lastvalue.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lastvalue.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" @@ -24,16 +24,15 @@ type lastValuePoint[N int64 | float64] struct { // lastValueMap summarizes a set of measurements as the last one made. type lastValueMap[N int64 | float64] struct { newRes func(attribute.Set) FilteredExemplarReservoir[N] - values limitedSyncMap + values limitedSyncMap[*lastValuePoint[N]] } func (s *lastValueMap[N]) measure( ctx context.Context, value N, - fltrAttr attribute.Set, - droppedAttr []attribute.KeyValue, + lazy lazyFilteredAttributes, ) { - lv := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + lv := s.values.LoadOrStoreAttr(lazy, func(attr attribute.Set) *lastValuePoint[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) p := &lastValuePoint[N]{ @@ -44,11 +43,11 @@ func (s *lastValueMap[N]) measure( } p.value.Store(value) return p - }).(*lastValuePoint[N]) + }) lv.value.Store(value) if !lv.dropExemplars { - lv.res.Offer(ctx, value, droppedAttr) + lv.res.Offer(ctx, value, lazy) } } @@ -61,12 +60,12 @@ func newDeltaLastValue[N int64 | float64]( start: now(), hotColdValMap: [2]lastValueMap[N]{ { - values: limitedSyncMap{aggLimit: limit}, newRes: r, + values: limitedSyncMap[*lastValuePoint[N]]{aggLimit: limit}, }, { - values: limitedSyncMap{aggLimit: limit}, newRes: r, + values: limitedSyncMap[*lastValuePoint[N]]{aggLimit: limit}, }, }, } @@ -84,12 +83,11 @@ type deltaLastValue[N int64 | float64] struct { func (s *deltaLastValue[N]) measure( ctx context.Context, value N, - fltrAttr attribute.Set, - droppedAttr []attribute.KeyValue, + lazy lazyFilteredAttributes, ) { hotIdx := s.hcwg.start() defer s.hcwg.done(hotIdx) - s.hotColdValMap[hotIdx].measure(ctx, value, fltrAttr, droppedAttr) + s.hotColdValMap[hotIdx].measure(ctx, value, lazy) } func (s *deltaLastValue[N]) collect( @@ -148,8 +146,8 @@ func newCumulativeLastValue[N int64 | float64]( ) *cumulativeLastValue[N] { return &cumulativeLastValue[N]{ lastValueMap: lastValueMap[N]{ - values: limitedSyncMap{aggLimit: limit}, newRes: r, + values: limitedSyncMap[*lastValuePoint[N]]{aggLimit: limit}, }, start: now(), } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lazy_attributes.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lazy_attributes.go new file mode 100644 index 00000000000..2fe88624703 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lazy_attributes.go @@ -0,0 +1,146 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package aggregate + +import ( + "math/bits" + + "go.opentelemetry.io/otel/attribute" +) + +type lazyFilteredAttributes struct { + orig attribute.Set + distinct attribute.Distinct + mask uint64 // bitmask of kept attributes (bit i == 1 if kept) for len <= 64 + bigMask []bool // fallback decision slice for len > 64 + hasDropped bool +} + +// newLazyFilteredAttributes filters orig using filter and computes the distinct +// hash of the resulting attributes. The filter function is evaluated once per +// attribute during initialization, and kept attribute indices are recorded in a +// bitmask so subsequent Set and Dropped calls do not re-evaluate filter. +func newLazyFilteredAttributes(orig attribute.Set, filter attribute.Filter) lazyFilteredAttributes { + if filter == nil { + return lazyFilteredAttributes{ + orig: orig, + distinct: orig.Equivalent(), + } + } + l := lazyFilteredAttributes{orig: orig, hasDropped: true} + + n := orig.Len() + hasher := attribute.NewHasher() + keptCount := 0 + for i := range n { + kv, _ := orig.Get(i) + if filter(kv) { + hasher.Write(kv) + l.recordKept(i, keptCount, n) + keptCount++ + } + } + if keptCount == n { + l.hasDropped = false + l.mask = 0 + l.bigMask = nil + l.distinct = orig.Equivalent() + return l + } + keptBefore64 := bits.OnesCount64(l.mask) + if keptCount-keptBefore64 > 0 { + l.ensureBigMask(n, keptCount) + } + l.distinct = hasher.Distinct() + return l +} + +// recordKept marks index i as kept in the bitmask or fallback slice. +func (l *lazyFilteredAttributes) recordKept(i, keptCount, total int) { + if i < 64 { + l.mask |= uint64(1) << i + return + } + if l.bigMask == nil && keptCount < i { + l.ensureBigMask(total, keptCount) + } + if l.bigMask != nil { + l.bigMask[i] = true + } +} + +// ensureBigMask initializes the bigMask slice and backfills any attributes past +// index 63 that were kept before attributes were dropped. +func (l *lazyFilteredAttributes) ensureBigMask(total, keptCount int) { + if l.bigMask != nil { + return + } + l.bigMask = make([]bool, total) + keptBefore64 := bits.OnesCount64(l.mask) + for j := 64; j < 64+(keptCount-keptBefore64); j++ { + l.bigMask[j] = true + } +} + +// isKept reports whether the attribute at index i was kept by the filter. +func (l lazyFilteredAttributes) isKept(i int) bool { + if i < 64 { + return (l.mask & (uint64(1) << i)) != 0 + } + return i < len(l.bigMask) && l.bigMask[i] +} + +// Distinct returns the precomputed Distinct hash of the filtered attributes. +func (l lazyFilteredAttributes) Distinct() attribute.Distinct { + return l.distinct +} + +// HasDroppedAttributes reports whether the filter dropped any attributes. +func (l lazyFilteredAttributes) HasDroppedAttributes() bool { + return l.hasDropped +} + +// Set constructs the filtered attribute Set using the recorded bitmask. +func (l lazyFilteredAttributes) Set() attribute.Set { + if !l.hasDropped { + return l.orig + } + if l.mask == 0 && l.bigMask == nil { + return attribute.NewSet() + } + n := l.orig.Len() + var kept []attribute.KeyValue + for i := range n { + if l.isKept(i) { + if kept == nil { + kept = make([]attribute.KeyValue, 0, n) + } + kv, _ := l.orig.Get(i) + kept = append(kept, kv) + } + } + return attribute.NewSet(kept...) +} + +// Dropped constructs the dropped attribute slice using the recorded bitmask. +func (l lazyFilteredAttributes) Dropped() []attribute.KeyValue { + if !l.hasDropped { + return nil + } + if l.mask == 0 && l.bigMask == nil { + return l.orig.ToSlice() + } + n := l.orig.Len() + var dropped []attribute.KeyValue + for i := range n { + if !l.isKept(i) { + if dropped == nil { + dropped = make([]attribute.KeyValue, 0, n) + } + kv, _ := l.orig.Get(i) + dropped = append(dropped, kv) + } + } + return dropped +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go index c19a1aff68f..426a8b275ed 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/sum.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/sum.go index 0cd3c94575b..c9a67cad809 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/sum.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/sum.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package aggregate // import "go.opentelemetry.io/otel/sdk/metric/internal/aggregate" +package aggregate import ( "context" @@ -21,17 +21,16 @@ type sumValue[N int64 | float64] struct { } type sumValueMap[N int64 | float64] struct { - values limitedSyncMap newRes func(attribute.Set) FilteredExemplarReservoir[N] + values limitedSyncMap[*sumValue[N]] } func (s *sumValueMap[N]) measure( ctx context.Context, value N, - fltrAttr attribute.Set, - droppedAttr []attribute.KeyValue, + lazy lazyFilteredAttributes, ) { - sv := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + sv := s.values.LoadOrStoreAttr(lazy, func(attr attribute.Set) *sumValue[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) return &sumValue[N]{ @@ -40,13 +39,13 @@ func (s *sumValueMap[N]) measure( startTime: now(), dropExemplars: isDrop, } - }).(*sumValue[N]) + }) sv.n.add(value) // It is possible for collection to race with measurement and observe the // exemplar in the batch of metrics after the add() for cumulative sums. // This is an accepted tradeoff to avoid locking during measurement. if !sv.dropExemplars { - sv.res.Offer(ctx, value, droppedAttr) + sv.res.Offer(ctx, value, lazy) } } @@ -63,12 +62,12 @@ func newDeltaSum[N int64 | float64]( start: now(), hotColdValMap: [2]sumValueMap[N]{ { - values: limitedSyncMap{aggLimit: limit}, newRes: r, + values: limitedSyncMap[*sumValue[N]]{aggLimit: limit}, }, { - values: limitedSyncMap{aggLimit: limit}, newRes: r, + values: limitedSyncMap[*sumValue[N]]{aggLimit: limit}, }, }, } @@ -83,10 +82,10 @@ type deltaSum[N int64 | float64] struct { hotColdValMap [2]sumValueMap[N] } -func (s *deltaSum[N]) measure(ctx context.Context, value N, fltrAttr attribute.Set, droppedAttr []attribute.KeyValue) { +func (s *deltaSum[N]) measure(ctx context.Context, value N, lazy lazyFilteredAttributes) { hotIdx := s.hcwg.start() defer s.hcwg.done(hotIdx) - s.hotColdValMap[hotIdx].measure(ctx, value, fltrAttr, droppedAttr) + s.hotColdValMap[hotIdx].measure(ctx, value, lazy) } func (s *deltaSum[N]) collect( @@ -140,8 +139,8 @@ func newCumulativeSum[N int64 | float64]( monotonic: monotonic, start: now(), sumValueMap: sumValueMap[N]{ - values: limitedSyncMap{aggLimit: limit}, newRes: r, + values: limitedSyncMap[*sumValue[N]]{aggLimit: limit}, }, } } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/attrnorm/dedup.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/attrnorm/dedup.go new file mode 100644 index 00000000000..fe9ddc96db7 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/attrnorm/dedup.go @@ -0,0 +1,300 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/attrnorm/dedup.go.tmpl + +// Package attrnorm normalizes attribute values. +package attrnorm + +import ( + "reflect" + "unsafe" + + "go.opentelemetry.io/otel/attribute" +) + +var ( + keyValueType = reflect.TypeFor[attribute.KeyValue]() + valueType = reflect.TypeFor[attribute.Value]() +) + +// rawValue mirrors attribute.Value. It is used only to read immutable slice +// storage without calling AsMap or AsSlice on no-op paths. +type rawValue struct { + vtype attribute.Type + numeric uint64 + stringly string + slice any +} + +// Value returns value with all map values deduplicated and whether it changed. +// +// Duplicate map keys are resolved using last-value-wins semantics. +func Value(value attribute.Value) (attribute.Value, bool) { + switch value.Type() { + case attribute.SLICE: + return deduplicateSliceValue(value) + case attribute.MAP: + return deduplicateMapValue(value) + default: + return value, false + } +} + +// KeyValue returns kv with all map values deduplicated and whether it changed. +func KeyValue(kv attribute.KeyValue) (attribute.KeyValue, bool) { + value, changed := Value(kv.Value) + if changed { + kv.Value = value + } + return kv, changed +} + +// KeyValues returns kvs with all map values deduplicated and whether they changed. +// +// The returned slice is the original kvs slice if no value needs +// deduplication. Top-level keys in kvs are not deduplicated. +func KeyValues(kvs []attribute.KeyValue) ([]attribute.KeyValue, bool) { + // Preserve the caller's slice on the common no-op path. Once a changed + // value is found, copy the prior values exactly once and fill the rest in + // place as the scan continues. + var normalized []attribute.KeyValue + for i, kv := range kvs { + kv, changed := KeyValue(kv) + if normalized != nil { + normalized[i] = kv + continue + } + if !changed { + continue + } + + normalized = make([]attribute.KeyValue, len(kvs)) + copy(normalized, kvs[:i]) + normalized[i] = kv + } + if normalized == nil { + return kvs, false + } + return normalized, true +} + +// Set returns set with all map values deduplicated and whether it changed. +// +// The returned Set is the original set if no value needs deduplication. +// Top-level key uniqueness remains attribute.Set's responsibility; this only +// normalizes map attribute values. +func Set(set attribute.Set) (attribute.Set, bool) { + if set.Len() == 0 { + return set, false + } + + // Most attribute sets contain no duplicate map keys. Delay allocation until + // the first changed value so the no-op path returns the original Set. + var normalized []attribute.KeyValue + for i := range set.Len() { + kv, _ := set.Get(i) + kv, changed := KeyValue(kv) + if normalized != nil { + normalized = append(normalized, kv) + continue + } + if !changed { + continue + } + + normalized = make([]attribute.KeyValue, 0, set.Len()) + for j := range i { + prior, _ := set.Get(j) + normalized = append(normalized, prior) + } + normalized = append(normalized, kv) + } + if normalized == nil { + return set, false + } + + return attribute.NewSet(normalized...), true +} + +func deduplicateSliceValue(value attribute.Value) (attribute.Value, bool) { + storage := valueStorage(value) + length := valueLen(storage) + + // Slice values can contain map values, so recurse into each element while + // keeping the original attribute.Value when no element changes. + var normalized []attribute.Value + for i := range length { + elem := valueAt(storage, i) + elem, changed := Value(elem) + if normalized != nil { + normalized[i] = elem + continue + } + if !changed { + continue + } + + normalized = make([]attribute.Value, length) + for j := range i { + normalized[j] = valueAt(storage, j) + } + normalized[i] = elem + } + if normalized == nil { + return value, false + } + return attribute.SliceValue(normalized...), true +} + +func deduplicateMapValue(value attribute.Value) (attribute.Value, bool) { + storage := valueStorage(value) + length := keyValueLen(storage) + if length <= 1 { + // A single map entry cannot duplicate its own key, but its value might + // contain a map or slice that needs recursive normalization. + if length == 1 { + kv, changed := KeyValue(keyValueAt(storage, 0)) + if changed { + return attribute.MapValue(kv), true + } + } + return value, false + } + + var normalized []attribute.KeyValue + for i := 0; i < length; { + // attribute.MapValue stores key-values sorted by key using a stable + // sort. Equal keys therefore form a contiguous run, and the last + // element in that run is the last value provided by the caller. + first := keyValueAt(storage, i) + j := i + 1 + for j < length && keyValueAt(storage, j).Key == first.Key { + j++ + } + + kv, nestedChanged := KeyValue(keyValueAt(storage, j-1)) + // j-i > 1 means the current key run contained duplicates. + changed := nestedChanged || j-i > 1 + if normalized != nil { + normalized = append(normalized, kv) + } else if changed { + normalized = make([]attribute.KeyValue, 0, length) + for k := range i { + normalized = append(normalized, keyValueAt(storage, k)) + } + normalized = append(normalized, kv) + } + i = j + } + if normalized == nil { + return value, false + } + return attribute.MapValue(normalized...), true +} + +func valueStorage(value attribute.Value) any { + // attribute.Value does not expose allocation-free map/slice iteration. + // The raw mirror lets us read the immutable backing array directly and + // reserve AsMap/AsSlice-style allocation for paths that actually change. + return (*rawValue)( + unsafe.Pointer(&value), + ).slice //nolint:gosec // Read-only mirror of attribute.Value for allocation-free iteration. +} + +func valueLen(storage any) int { + // attribute.Value stores small slices in fixed-size array values. Handle + // the common sizes directly and fall back to reflection for larger arrays. + switch storage.(type) { + case [0]attribute.Value: + return 0 + case [1]attribute.Value: + return 1 + case [2]attribute.Value: + return 2 + case [3]attribute.Value: + return 3 + case [4]attribute.Value: + return 4 + case [5]attribute.Value: + return 5 + default: + return arrayLen(storage, valueType) + } +} + +func valueAt(storage any, i int) attribute.Value { + switch values := storage.(type) { + case [1]attribute.Value: + return values[i] + case [2]attribute.Value: + return values[i] + case [3]attribute.Value: + return values[i] + case [4]attribute.Value: + return values[i] + case [5]attribute.Value: + return values[i] + default: + return arrayAt[attribute.Value](storage, valueType, i) + } +} + +func keyValueLen(storage any) int { + // attribute.Value stores small maps in fixed-size key-value arrays. Handle + // the common sizes directly and fall back to reflection for larger arrays. + switch storage.(type) { + case [0]attribute.KeyValue: + return 0 + case [1]attribute.KeyValue: + return 1 + case [2]attribute.KeyValue: + return 2 + case [3]attribute.KeyValue: + return 3 + case [4]attribute.KeyValue: + return 4 + case [5]attribute.KeyValue: + return 5 + default: + return arrayLen(storage, keyValueType) + } +} + +func keyValueAt(storage any, i int) attribute.KeyValue { + switch kvs := storage.(type) { + case [1]attribute.KeyValue: + return kvs[i] + case [2]attribute.KeyValue: + return kvs[i] + case [3]attribute.KeyValue: + return kvs[i] + case [4]attribute.KeyValue: + return kvs[i] + case [5]attribute.KeyValue: + return kvs[i] + default: + return arrayAt[attribute.KeyValue](storage, keyValueType, i) + } +} + +func arrayLen(storage any, elem reflect.Type) int { + // Be defensive around invalid or unexpected Value storage. Returning zero + // makes malformed storage a no-op instead of panicking in telemetry paths. + array := reflect.ValueOf(storage) + if array.Kind() != reflect.Array || array.Type().Elem() != elem { + return 0 + } + return array.Len() +} + +func arrayAt[T any](storage any, elem reflect.Type, i int) T { + // Match arrayLen's fail-closed behavior for unexpected storage. + array := reflect.ValueOf(storage) + if array.Kind() != reflect.Array || array.Type().Elem() != elem || i < 0 || i >= array.Len() { + var zero T + return zero + } + return array.Index(i).Interface().(T) +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/gen.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/gen.go new file mode 100644 index 00000000000..5f077dfe93b --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/gen.go @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package internal provides internal functionality for the sdk/metric package. +package internal + +//go:generate gotmpl --body=../../../internal/shared/x/x.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/sdk/metric\" }" --out=x/x.go +//go:generate gotmpl --body=../../../internal/shared/x/x_test.go.tmpl "--data={}" --out=x/x_test.go +//go:generate gotmpl --body=../../../internal/shared/attrnorm/dedup.go.tmpl "--data={}" --out=attrnorm/dedup.go +//go:generate gotmpl --body=../../../internal/shared/attrnorm/dedup_test.go.tmpl "--data={}" --out=attrnorm/dedup_test.go diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/instrumentation.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/instrumentation.go index c580dcc30d2..b09748a79fa 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/instrumentation.go @@ -3,7 +3,7 @@ // Package observ provides experimental observability instrumentation for the // metric reader. -package observ // import "go.opentelemetry.io/otel/sdk/metric/internal/observ" +package observ import ( "context" @@ -16,8 +16,8 @@ import ( "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk" "go.opentelemetry.io/otel/sdk/internal/x" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/otelconv" ) const ( diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/concurrent_safe.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/concurrent_safe.go index 3be234a4108..8542fd94bd7 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/concurrent_safe.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/concurrent_safe.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package reservoir // import "go.opentelemetry.io/otel/sdk/metric/internal/reservoir" +package reservoir // ConcurrentSafe is an interface that can be embedded in an // exemplar.Reservoir to indicate to the SDK that it is safe to invoke its diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/doc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/doc.go index 6cd213b5f32..6dbf906c8ad 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/doc.go @@ -3,4 +3,4 @@ // Package reservoir contains experimental features used by built-in exemplar // reservoirs which require coordination with the metrics SDK. -package reservoir // import "go.opentelemetry.io/otel/sdk/metric/internal/reservoir" +package reservoir diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reuse_slice.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reuse_slice.go index ea452be6c2c..6ddf01473b4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reuse_slice.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reuse_slice.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal functionality for the metric package. -package internal // import "go.opentelemetry.io/otel/sdk/metric/internal" +package internal // ReuseSlice returns a zeroed view of slice if its capacity is greater than or // equal to n. Otherwise, it returns a new []T with capacity equal to n. diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/features.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/features.go new file mode 100644 index 00000000000..a8268702a6d --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/features.go @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package x + +import "strconv" + +// MetricExportBatchSize is an experimental feature flag that controls the +// max export batch size for metric data. +// +// To enable this feature set the OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE environment +// variable to a positive integer value. +var MetricExportBatchSize = newFeature( + []string{"METRIC_EXPORT_BATCH_SIZE"}, + func(v string) (int, bool) { + val, err := strconv.Atoi(v) + if err == nil && val > 0 { + return val, true + } + return 0, false + }, +) diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/x.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/x.go index 8e3c62a13d2..fdb75b81813 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/x.go @@ -1,50 +1,54 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// Package x contains support for OTel metric SDK experimental features. -// -// This package should only be used for features defined in the specification. -// It should not be used for experiments or new project ideas. -package x // import "go.opentelemetry.io/otel/sdk/metric/internal/x" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/x/x.go.tmpl + +// Package x documents experimental features for [go.opentelemetry.io/otel/sdk/metric]. +package x import ( "os" - "strconv" ) // Feature is an experimental feature control flag. It provides a uniform way // to interact with these feature flags and parse their values. type Feature[T any] struct { - key string + keys []string parse func(v string) (T, bool) } -//nolint:unused -func newFeature[T any](suffix string, parse func(string) (T, bool)) Feature[T] { +func newFeature[T any](suffix []string, parse func(string) (T, bool)) Feature[T] { const envKeyRoot = "OTEL_GO_X_" + keys := make([]string, 0, len(suffix)) + for _, s := range suffix { + keys = append(keys, envKeyRoot+s) + } return Feature[T]{ - key: envKeyRoot + suffix, + keys: keys, parse: parse, } } -// Key returns the environment variable key that needs to be set to enable the +// Keys returns the environment variable keys that can be set to enable the // feature. -func (f Feature[T]) Key() string { return f.key } +func (f Feature[T]) Keys() []string { return f.keys } -// Lookup returns the user configured value for the feature and true if the +// Lookup returns the user-configured value for the feature and true if the // user has enabled the feature. Otherwise, if the feature is not enabled, a -// zero-value and false are returned. +// zero value and false are returned. func (f Feature[T]) Lookup() (v T, ok bool) { // https://github.com/open-telemetry/opentelemetry-specification/blob/62effed618589a0bec416a87e559c0a9d96289bb/specification/configuration/sdk-environment-variables.md#parsing-empty-value // // > The SDK MUST interpret an empty value of an environment variable the // > same way as when the variable is unset. - vRaw := os.Getenv(f.key) - if vRaw == "" { - return v, ok + for _, key := range f.keys { + vRaw := os.Getenv(key) + if vRaw != "" { + return f.parse(vRaw) + } } - return f.parse(vRaw) + return v, ok } // Enabled reports whether the feature is enabled. @@ -52,19 +56,3 @@ func (f Feature[T]) Enabled() bool { _, ok := f.Lookup() return ok } - -// MetricExportBatchSize is an experimental feature flag that controls the -// max export batch size for metric data. -// -// To enable this feature set the OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE environment -// variable to a positive integer value. -var MetricExportBatchSize = newFeature( - "METRIC_EXPORT_BATCH_SIZE", - func(v string) (int, bool) { - val, err := strconv.Atoi(v) - if err == nil && val > 0 { - return val, true - } - return 0, false - }, -) diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/manual_reader.go b/vendor/go.opentelemetry.io/otel/sdk/metric/manual_reader.go index 7e0cccdff60..b98e255d8c4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/manual_reader.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/manual_reader.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/meter.go b/vendor/go.opentelemetry.io/otel/sdk/metric/meter.go index e9a2d59572e..8c54974e062 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/meter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/meter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" @@ -593,11 +593,13 @@ func (r observer) ObserveFloat64(o metric.Float64Observable, v float64, opts ... return } c := metric.NewObserveConfig(opts) + rawKVs := extractRawKVs(opts) + set := resolveAttributes(c.Attributes(), rawKVs) // Access to r.pipe.float64Measure is already guarded by a lock in pipeline.produce. // TODO (#5946): Refactor pipeline and observable measures. measures := r.pipe.float64Measures[oImpl.observableID] for _, m := range measures { - m(context.Background(), v, c.Attributes()) + m(context.Background(), v, set) } } @@ -624,11 +626,13 @@ func (r observer) ObserveInt64(o metric.Int64Observable, v int64, opts ...metric return } c := metric.NewObserveConfig(opts) + rawKVs := extractRawKVs(opts) + set := resolveAttributes(c.Attributes(), rawKVs) // Access to r.pipe.int64Measures is already guarded b a lock in pipeline.produce. // TODO (#5946): Refactor pipeline and observable measures. measures := r.pipe.int64Measures[oImpl.observableID] for _, m := range measures { - m(context.Background(), v, c.Attributes()) + m(context.Background(), v, set) } } @@ -793,7 +797,8 @@ type int64Observer struct { func (o int64Observer) Observe(val int64, opts ...metric.ObserveOption) { c := metric.NewObserveConfig(opts) - o.observe(val, c.Attributes()) + rawKVs := extractRawKVs(opts) + o.observe(val, resolveAttributes(c.Attributes(), rawKVs)) } type float64Observer struct { @@ -803,7 +808,8 @@ type float64Observer struct { func (o float64Observer) Observe(val float64, opts ...metric.ObserveOption) { c := metric.NewObserveConfig(opts) - o.observe(val, c.Attributes()) + rawKVs := extractRawKVs(opts) + o.observe(val, resolveAttributes(c.Attributes(), rawKVs)) } func defaultAttributes[T any](opts []T) []attribute.Key { diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/data.go b/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/data.go index af835e9d992..1caed336e95 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/data.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/data.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package metricdata provides types for the metric SDK data model. -package metricdata // import "go.opentelemetry.io/otel/sdk/metric/metricdata" +package metricdata import ( "encoding/json" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality.go b/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality.go index 2ac840ff356..8d7c89d857f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality.go @@ -3,7 +3,7 @@ //go:generate stringer -type=Temporality -package metricdata // import "go.opentelemetry.io/otel/sdk/metric/metricdata" +package metricdata // Temporality defines the window that an aggregation was calculated over. type Temporality uint8 diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/periodic_reader.go b/vendor/go.opentelemetry.io/otel/sdk/metric/periodic_reader.go index c1c2e3e2f0a..9f7712bd516 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/periodic_reader.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/periodic_reader.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" @@ -16,7 +16,7 @@ import ( "go.opentelemetry.io/otel/sdk/metric/internal/observ" "go.opentelemetry.io/otel/sdk/metric/internal/x" "go.opentelemetry.io/otel/sdk/metric/metricdata" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) // Default periodic reader timing. diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/pipeline.go b/vendor/go.opentelemetry.io/otel/sdk/metric/pipeline.go index 09d10eeb5f2..f04c2ddcecd 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/pipeline.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/pipeline.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "container/list" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/provider.go b/vendor/go.opentelemetry.io/otel/sdk/metric/provider.go index fd4cdccd0ff..9f9f01f4323 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/provider.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/provider.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" @@ -12,6 +12,7 @@ import ( "go.opentelemetry.io/otel/metric/embedded" "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/sdk/instrumentation" + "go.opentelemetry.io/otel/sdk/metric/internal/attrnorm" ) // MeterProvider handles the creation and coordination of Meters. All Meters @@ -76,11 +77,12 @@ func (mp *MeterProvider) Meter(name string, options ...metric.MeterOption) metri } c := metric.NewMeterConfig(options...) + attrs, _ := attrnorm.Set(c.InstrumentationAttributes()) s := instrumentation.Scope{ Name: name, Version: c.InstrumentationVersion(), SchemaURL: c.SchemaURL(), - Attributes: c.InstrumentationAttributes(), + Attributes: attrs, } global.Info( diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/reader.go b/vendor/go.opentelemetry.io/otel/sdk/metric/reader.go index 556afcea6bb..505c9ad9388 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/reader.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/reader.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/splitmetrics.go b/vendor/go.opentelemetry.io/otel/sdk/metric/splitmetrics.go index a7931412bb2..b183cf4863c 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/splitmetrics.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/splitmetrics.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "go.opentelemetry.io/otel/sdk/metric/metricdata" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/version.go b/vendor/go.opentelemetry.io/otel/sdk/metric/version.go index 3e1bea4b446..615db822538 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/version.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/version.go @@ -1,9 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric // version is the current release version of the metric SDK in use. func version() string { - return "1.44.0" + return "1.46.0" } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/view.go b/vendor/go.opentelemetry.io/otel/sdk/metric/view.go index 13fb7143ce0..3f98928f96a 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/metric/view.go +++ b/vendor/go.opentelemetry.io/otel/sdk/metric/view.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/sdk/metric" +package metric import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go b/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go index c02aeefdde5..8754313af99 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go index 28823edd53d..d5f6dc0a6d3 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" @@ -13,7 +13,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) type ( diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go index a3d647d92c2..c5ffa45d022 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" @@ -23,7 +23,9 @@ type Option interface { apply(config) config } -// WithAttributes adds attributes to the configured Resource. +// WithAttributes adds attributes to the configured Resource. Duplicate +// top-level attribute keys and duplicate keys inside map values are +// resolved using last-value-wins semantics. func WithAttributes(attributes ...attribute.KeyValue) Option { return WithDetectors(detectAttributes{attributes}) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/container.go b/vendor/go.opentelemetry.io/otel/sdk/resource/container.go index ce03e24c419..c81163bf85e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/container.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/container.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "bufio" @@ -11,7 +11,7 @@ import ( "os" "regexp" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) type containerIDProvider func() (string, error) diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go b/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go index 64939a27131..f5a79d3fe49 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/doc.go @@ -17,4 +17,4 @@ // // While this package provides a stable API, // the attributes added by resource detectors may change. -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/env.go b/vendor/go.opentelemetry.io/otel/sdk/resource/env.go index ac5691c08d9..0eeb1e2ae5e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/env.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/env.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" @@ -12,7 +12,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) const ( diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go index cb38fa1a8b0..47219be223a 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go @@ -1,14 +1,14 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" "errors" "strings" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) type hostIDProvider func() (string, error) diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go index 4c1c30f2560..bcd174342b2 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go @@ -3,7 +3,7 @@ //go:build dragonfly || freebsd || netbsd || openbsd || solaris -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource var platformHostIDReader hostIDReader = &hostIDReaderBSD{ execCommand: execCommand, diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go index b09fde3b735..81ece5b34d6 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource var platformHostIDReader hostIDReader = &hostIDReaderDarwin{ execCommand: execCommand, diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go index e239ead0287..c058f0d26b0 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go @@ -3,7 +3,7 @@ //go:build darwin || dragonfly || freebsd || netbsd || openbsd || solaris -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go index 4a26096c8d0..26cf6a5d1e2 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go @@ -3,7 +3,7 @@ //go:build linux -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource var platformHostIDReader hostIDReader = &hostIDReaderLinux{ readFile: readFile, diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go index c95d87685c9..d955c2c909f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go @@ -3,7 +3,7 @@ //go:build linux || dragonfly || freebsd || netbsd || openbsd || solaris -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import "os" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go index 63ad2fa4e05..9f6ca82118c 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go @@ -3,7 +3,7 @@ //go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource // hostIDReaderUnsupported is a placeholder implementation for operating systems // for which this project currently doesn't support host.id diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go index 2b8ca20b381..e9e4a038484 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go @@ -3,7 +3,7 @@ //go:build windows -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "golang.org/x/sys/windows/registry" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os.go index 4c0def41483..6af4915679f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os.go @@ -1,14 +1,14 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" "strings" "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) type osDescriptionProvider func() (string, error) diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go index 3d703c5d98e..f12876d17a5 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "encoding/xml" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go index a1763267c22..ad92858546e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go @@ -3,7 +3,7 @@ //go:build aix || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "bufio" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go index 1cd87c39834..ba5e48db244 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go @@ -3,7 +3,7 @@ //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "fmt" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go index 25f629532a3..e2c19c2b3aa 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go @@ -3,7 +3,7 @@ //go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource // platformOSDescription is a placeholder implementation for OSes // for which this project currently doesn't support os.description diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go index ebd50826d6e..9b76489577a 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "fmt" diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/process.go b/vendor/go.opentelemetry.io/otel/sdk/resource/process.go index b015f8233c6..a578fc3258e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/process.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/process.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" @@ -11,7 +11,7 @@ import ( "path/filepath" "runtime" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) type ( diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go index f715be53eda..dcd7280ac94 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package resource // import "go.opentelemetry.io/otel/sdk/resource" +package resource import ( "context" @@ -11,6 +11,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/internal/attrnorm" "go.opentelemetry.io/otel/sdk/internal/x" ) @@ -47,6 +48,8 @@ var ( var ErrSchemaURLConflict = errors.New("conflicting Schema URL") // New returns a [Resource] built using opts. +// Duplicate top-level attribute keys and duplicate keys inside map +// values are resolved using last-value-wins semantics. // // This may return a partial Resource along with an error containing // [ErrPartialResource] if options that provide a [Detector] are used and that @@ -66,25 +69,29 @@ func New(ctx context.Context, opts ...Option) (*Resource, error) { return r, detect(ctx, r, cfg.detectors) } -// NewWithAttributes creates a resource from attrs and associates the resource with a -// schema URL. If attrs contains duplicate keys, the last value will be used. If attrs -// contains any invalid items those items will be dropped. The attrs are assumed to be -// in a schema identified by schemaURL. +// NewWithAttributes creates a resource from attrs and associates the resource +// with a schema URL. If attrs contains duplicate top-level attribute keys or +// duplicate keys inside map values, the last value will be used. If attrs +// contains any invalid items those items will be dropped. The attrs are assumed +// to be in a schema identified by schemaURL. func NewWithAttributes(schemaURL string, attrs ...attribute.KeyValue) *Resource { resource := NewSchemaless(attrs...) resource.schemaURL = schemaURL return resource } -// NewSchemaless creates a resource from attrs. If attrs contains duplicate keys, -// the last value will be used. If attrs contains any invalid items those items will -// be dropped. The resource will not be associated with a schema URL. If the schema +// NewSchemaless creates a resource from attrs. If attrs contains duplicate +// top-level attribute keys or duplicate keys inside map values, the last +// value will be used. If attrs contains any invalid items those items will be +// dropped. The resource will not be associated with a schema URL. If the schema // of the attrs is known use NewWithAttributes instead. func NewSchemaless(attrs ...attribute.KeyValue) *Resource { if len(attrs) == 0 { return &Resource{} } + attrs, _ = attrnorm.KeyValues(attrs) + // Ensure attributes comply with the specification: // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/common/README.md#attribute s, _ := attribute.NewSetWithFiltered(attrs, func(kv attribute.KeyValue) bool { @@ -113,6 +120,9 @@ func (r *Resource) String() string { // MarshalLog is the marshaling function used by the logging system to represent this Resource. func (r *Resource) MarshalLog() any { + if r == nil { + r = Empty() + } return struct { Attributes attribute.Set SchemaURL string diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go index f9f2a6c2c85..2b9560ee7f9 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go @@ -1,11 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" "errors" + "fmt" "sync" "sync/atomic" "time" @@ -435,11 +436,11 @@ func (bsp *batchSpanProcessor) enqueueDrop(ctx context.Context, sd ReadOnlySpan) func (bsp *batchSpanProcessor) MarshalLog() any { return struct { Type string - SpanExporter SpanExporter + SpanExporter string Config BatchSpanProcessorOptions }{ Type: "BatchSpanProcessor", - SpanExporter: bsp.e, + SpanExporter: fmt.Sprintf("%T", bsp.e), Config: bsp.o, } } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go b/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go index b502c7d4798..b292fa3113e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/doc.go @@ -10,4 +10,4 @@ See https://opentelemetry.io. See [go.opentelemetry.io/otel/sdk/internal/x] for information about the experimental features. */ -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/event.go b/vendor/go.opentelemetry.io/otel/sdk/trace/event.go index 60a7ed1349b..49eac0459f4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/event.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/event.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "time" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go b/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go index 8c308dd60a9..1f62b528c3e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "slices" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go b/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go index 3649322a6e4..be22ac63228 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/env/env.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/env/env.go index 58f68df4417..1385ae6fc24 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/env/env.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/env/env.go @@ -3,7 +3,7 @@ // Package env provides types and functionality for environment variable support // in the OpenTelemetry SDK. -package env // import "go.opentelemetry.io/otel/sdk/trace/internal/env" +package env import ( "os" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go index c725ebf372d..896ed517f02 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package observ // import "go.opentelemetry.io/otel/sdk/trace/internal/observ" +package observ import ( "context" @@ -13,8 +13,8 @@ import ( "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk" "go.opentelemetry.io/otel/sdk/internal/x" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/otelconv" ) const ( diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/doc.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/doc.go index b542121e6a2..64fd5238d04 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/doc.go @@ -3,4 +3,4 @@ // Package observ provides observability instrumentation for the OTel trace SDK // package. -package observ // import "go.opentelemetry.io/otel/sdk/trace/internal/observ" +package observ diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go index cf4b5d481fc..e7ca1a6d973 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go @@ -1,38 +1,25 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package observ // import "go.opentelemetry.io/otel/sdk/trace/internal/observ" +package observ import ( "context" "fmt" - "sync" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk" "go.opentelemetry.io/otel/sdk/internal/x" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/otelconv" ) -var measureAttrsPool = sync.Pool{ - New: func() any { - // "component.name" + "component.type" + "error.type" - const n = 1 + 1 + 1 - s := make([]attribute.KeyValue, 0, n) - // Return a pointer to a slice instead of a slice itself - // to avoid allocations on every call. - return &s - }, -} - // SSP is the instrumentation for an OTel SDK SimpleSpanProcessor. type SSP struct { spansProcessedCounter metric.Int64Counter addOpts []metric.AddOption - attrs []attribute.KeyValue } // SSPComponentName returns the component name attribute for a @@ -70,29 +57,12 @@ func NewSSP(id int64) (*SSP, error) { return &SSP{ spansProcessedCounter: spansProcessedCounter.Inst(), addOpts: addOpts, - attrs: attrs, }, err } -// SpanProcessed records that a span has been processed by the SimpleSpanProcessor. -// If err is non-nil, it records the processing error as an attribute. -func (ssp *SSP) SpanProcessed(ctx context.Context, err error) { - ssp.spansProcessedCounter.Add(ctx, 1, ssp.addOption(err)...) -} - -func (ssp *SSP) addOption(err error) []metric.AddOption { - if err == nil { - return ssp.addOpts - } - attrs := measureAttrsPool.Get().(*[]attribute.KeyValue) - defer func() { - clear(*attrs) - *attrs = (*attrs)[:0] // reset the slice for reuse - measureAttrsPool.Put(attrs) - }() - *attrs = append(*attrs, ssp.attrs...) - *attrs = append(*attrs, semconv.ErrorType(err)) - // Do not inefficiently make a copy of attrs by using - // WithAttributes instead of WithAttributeSet. - return []metric.AddOption{metric.WithAttributeSet(attribute.NewSet(*attrs...))} +// SpanProcessed records that a span has been submitted to the exporter by the +// SimpleSpanProcessor. Per the semantic conventions, this count is recorded at +// submission time and MUST NOT be affected by the export outcome. +func (ssp *SSP) SpanProcessed(ctx context.Context) { + ssp.spansProcessedCounter.Add(ctx, 1, ssp.addOpts...) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go index 5aae89e883c..3428aa89497 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package observ // import "go.opentelemetry.io/otel/sdk/trace/internal/observ" +package observ import ( "context" @@ -13,7 +13,7 @@ import ( "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk" "go.opentelemetry.io/otel/sdk/internal/x" - "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv" + "go.opentelemetry.io/otel/semconv/v1.43.0/otelconv" "go.opentelemetry.io/otel/trace" ) diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/link.go b/vendor/go.opentelemetry.io/otel/sdk/trace/link.go index c03bdc90f68..d4a07a714be 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/link.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/link.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go index 9d90c2eda5a..6b2368413a1 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/sdk/instrumentation" + "go.opentelemetry.io/otel/sdk/internal/attrnorm" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace/internal/observ" "go.opentelemetry.io/otel/trace" @@ -42,22 +43,27 @@ type tracerProviderConfig struct { // resource contains attributes representing an entity that produces telemetry. resource *resource.Resource + + // panicRecordingDisabled disables recording exception events from panics. + panicRecordingDisabled bool } // MarshalLog is the marshaling function used by the logging system to represent this Provider. func (cfg tracerProviderConfig) MarshalLog() any { return struct { - SpanProcessors []SpanProcessor - SamplerType string - IDGeneratorType string - SpanLimits SpanLimits - Resource *resource.Resource + SpanProcessors []SpanProcessor + SamplerType string + IDGeneratorType string + SpanLimits SpanLimits + Resource *resource.Resource + PanicRecordingDisabled bool }{ - SpanProcessors: cfg.processors, - SamplerType: fmt.Sprintf("%T", cfg.sampler), - IDGeneratorType: fmt.Sprintf("%T", cfg.idGenerator), - SpanLimits: cfg.spanLimits, - Resource: cfg.resource, + SpanProcessors: cfg.processors, + SamplerType: fmt.Sprintf("%T", cfg.sampler), + IDGeneratorType: fmt.Sprintf("%T", cfg.idGenerator), + SpanLimits: cfg.spanLimits, + Resource: cfg.resource, + PanicRecordingDisabled: cfg.panicRecordingDisabled, } } @@ -74,10 +80,11 @@ type TracerProvider struct { // These fields are not protected by the lock mu. They are assumed to be // immutable after creation of the TracerProvider. - sampler Sampler - idGenerator IDGenerator - spanLimits SpanLimits - resource *resource.Resource + sampler Sampler + idGenerator IDGenerator + spanLimits SpanLimits + resource *resource.Resource + panicRecordingDisabled bool } var _ trace.TracerProvider = &TracerProvider{} @@ -112,11 +119,12 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { o = ensureValidTracerProviderConfig(o) tp := &TracerProvider{ - namedTracer: make(map[instrumentation.Scope]*tracer), - sampler: o.sampler, - idGenerator: o.idGenerator, - spanLimits: o.spanLimits, - resource: o.resource, + namedTracer: make(map[instrumentation.Scope]*tracer), + sampler: o.sampler, + idGenerator: o.idGenerator, + spanLimits: o.spanLimits, + resource: o.resource, + panicRecordingDisabled: o.panicRecordingDisabled, } global.Info("TracerProvider created", "config", o) @@ -142,6 +150,7 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T return noop.NewTracerProvider().Tracer(name, opts...) } c := trace.NewTracerConfig(opts...) + attrs, _ := attrnorm.Set(c.InstrumentationAttributes()) if name == "" { name = defaultTracerName } @@ -149,7 +158,7 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T Name: name, Version: c.InstrumentationVersion(), SchemaURL: c.SchemaURL(), - Attributes: c.InstrumentationAttributes(), + Attributes: attrs, } t, ok := func() (trace.Tracer, bool) { @@ -357,6 +366,16 @@ func WithSpanProcessor(sp SpanProcessor) TracerProviderOption { }) } +// WithoutPanicRecording configures the TracerProvider to not record exception +// events when a Span is ended while panicking. The panic continues to +// propagate, and the span is ended without adding the event. +func WithoutPanicRecording() TracerProviderOption { + return traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig { + cfg.panicRecordingDisabled = true + return cfg + }) +} + // WithResource returns a TracerProviderOption that will configure the // Resource r as a TracerProvider's Resource. The configured Resource is // referenced by all the Tracers the TracerProvider creates. It represents the diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go b/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go index 9b672a1d70d..b0fa94ed2d6 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go b/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go index 5a4c74318b8..c79177ae8d5 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go index 771e427a4c5..97985c4988a 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go @@ -1,10 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" + "fmt" "sync" "sync/atomic" @@ -66,19 +67,19 @@ func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) { ssp.exporterMu.Lock() defer ssp.exporterMu.Unlock() - var err error - if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() { - err = ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}) - if err != nil { - otel.Handle(err) - } - } - if ssp.inst != nil { // Add the span to the context to ensure the metric is recorded - // with the correct span context. + // with the correct span context. Record the span as processed before + // invoking the exporter so the count is unaffected by the export + // outcome. ctx := trace.ContextWithSpanContext(context.Background(), s.SpanContext()) - ssp.inst.SpanProcessed(ctx, err) + ssp.inst.SpanProcessed(ctx) + } + + if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() { + if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil { + otel.Handle(err) + } } } @@ -140,11 +141,18 @@ func (*simpleSpanProcessor) ForceFlush(context.Context) error { // MarshalLog is the marshaling function used by the logging system to represent // this Span Processor. func (ssp *simpleSpanProcessor) MarshalLog() any { + // Shutdown clears exporter under exporterMu. + // Copy it while holding the same lock so MarshalLog + // can run concurrently without racing with Shutdown. + ssp.exporterMu.Lock() + exp := ssp.exporter + ssp.exporterMu.Unlock() + return struct { Type string - Exporter SpanExporter + Exporter string }{ Type: "SimpleSpanProcessor", - Exporter: ssp.exporter, + Exporter: fmt.Sprintf("%T", exp), } } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go b/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go index 63aa337800c..8893dc39f13 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "time" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go index d1d9af29d79..aae97731457 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" @@ -10,17 +10,16 @@ import ( "runtime" rt "runtime/trace" "slices" - "strings" "sync" "time" - "unicode/utf8" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/sdk/instrumentation" + "go.opentelemetry.io/otel/sdk/internal/attrnorm" "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace/embedded" ) @@ -139,6 +138,11 @@ type recordingSpan struct { attributes []attribute.KeyValue droppedAttributes int logDropAttrsOnce sync.Once + // attributesDirty indicates attributes may contain duplicate keys. + attributesDirty bool + // attributesShared indicates the attributes backing array has been exposed + // to a reader and must not be modified. + attributesShared bool // events are stored in FIFO queue capped by configured limit. events evictedQueue[Event] @@ -252,6 +256,11 @@ func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) { s.addDroppedAttr(len(attributes)) return } + maxCap := len(s.attributes) + len(attributes) + if limit > 0 { + maxCap = min(maxCap, limit) + } + s.ensureAttrsWritable(maxCap) // If adding these attributes could exceed the capacity of s perform a // de-duplication and truncation while adding to avoid over allocation. @@ -269,9 +278,24 @@ func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) { s.addDroppedAttr(1) continue } - a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) + a = dedupAttr(a) + a = attrnorm.Truncate(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) s.attributes = append(s.attributes, a) + s.attributesDirty = true + } +} + +// ensureAttrsWritable copies shared attributes into a backing array with at +// least capacity. This method assumes s.mu.Lock is held by the caller. +func (s *recordingSpan) ensureAttrsWritable(capacity int) { + if !s.attributesShared { + return } + capacity = max(capacity, len(s.attributes)) + attrs := make([]attribute.KeyValue, len(s.attributes), capacity) + copy(attrs, s.attributes) + s.attributes = attrs + s.attributesShared = false } // Declared as a var so tests can override. @@ -329,7 +353,8 @@ func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) { if idx, ok := exists[a.Key]; ok { // Perform all updates before dropping, even when at capacity. - a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) + a = dedupAttr(a) + a = attrnorm.Truncate(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) s.attributes[idx] = a continue } @@ -339,208 +364,31 @@ func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) { // updates are checked and performed. s.addDroppedAttr(1) } else { - a = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) + a = dedupAttr(a) + a = attrnorm.Truncate(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a) s.attributes = append(s.attributes, a) exists[a.Key] = len(s.attributes) - 1 } } } -// truncateAttr returns a truncated version of attr. Only string, string -// slice, byte slice, and slice attribute values are truncated. String values are truncated -// to at most a length of limit. Each string slice value is truncated in this -// fashion (the slice length itself is unaffected), and byte slice values are truncated to at most -// limit bytes. For slice attribute values, the limit is applied to each -// element recursively. -// -// No truncation is performed for a negative limit. -func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue { - if limit < 0 { - return attr - } +func dedupAttr(attr attribute.KeyValue) attribute.KeyValue { switch attr.Value.Type() { - case attribute.STRING: - v := attr.Value.AsString() - return attr.Key.String(truncate(limit, v)) - case attribute.STRINGSLICE: - v := attr.Value.AsStringSlice() - for i := range v { - v[i] = truncate(limit, v[i]) - } - return attr.Key.StringSlice(v) - case attribute.BYTESLICE: - v := attr.Value.AsString() - if len(v) > limit { - return attr.Key.ByteSlice([]byte(v[:limit])) - } + case attribute.SLICE, attribute.MAP: + attr, _ = attrnorm.KeyValue(attr) + return attr + default: return attr - case attribute.SLICE: - v := attr.Value.AsSlice() - if !slices.ContainsFunc(v, func(e attribute.Value) bool { return needsTruncation(limit, e) }) { - return attr - } - newV := make([]attribute.Value, len(v)) - for i, elem := range v { - newV[i] = truncateValue(limit, elem) - } - return attr.Key.Slice(newV...) - } - return attr -} - -// truncateValue returns a truncated version of v. Only string, string slice, -// byte slice, and (recursively) slice values are modified. -// -// No truncation is performed for a negative limit. -func truncateValue(limit int, v attribute.Value) attribute.Value { - switch v.Type() { - case attribute.STRING: - return attribute.StringValue(truncate(limit, v.AsString())) - case attribute.STRINGSLICE: - ss := v.AsStringSlice() - for i := range ss { - ss[i] = truncate(limit, ss[i]) - } - return attribute.StringSliceValue(ss) - - case attribute.BYTESLICE: - // len(v.AsString()) is identical to len(v.AsByteSlice()) but - // avoids allocating the full slice before truncation. - s := v.AsString() - if limit >= 0 && len(s) > limit { - return attribute.ByteSliceValue([]byte(s[:limit])) - } - case attribute.SLICE: - sl := v.AsSlice() - if !slices.ContainsFunc(sl, func(e attribute.Value) bool { return needsTruncation(limit, e) }) { - return v - } - newSl := make([]attribute.Value, len(sl)) - for i, elem := range sl { - newSl[i] = truncateValue(limit, elem) - } - return attribute.SliceValue(newSl...) - } - return v -} - -// stringNeedsTruncation reports whether s would be modified by truncate for the -// given limit. -func stringNeedsTruncation(limit int, s string) bool { - if limit < 0 || len(s) <= limit { - return false - } - return utf8.RuneCountInString(s) > limit || !utf8.ValidString(s) -} - -// needsTruncation reports whether v would be modified by truncateValue for the -// given limit. -func needsTruncation(limit int, v attribute.Value) bool { - switch v.Type() { - case attribute.STRING: - return stringNeedsTruncation(limit, v.AsString()) - case attribute.BYTESLICE: - // len(v.AsString()) is identical to len(v.AsByteSlice()) but - // avoids memory allocation. - if limit >= 0 && len(v.AsString()) > limit { - return true - } - case attribute.STRINGSLICE: - for _, s := range v.AsStringSlice() { - if stringNeedsTruncation(limit, s) { - return true - } - } - case attribute.SLICE: - return slices.ContainsFunc(v.AsSlice(), func(e attribute.Value) bool { return needsTruncation(limit, e) }) - } - return false -} - -// truncate returns a truncated version of s such that it contains less than -// the limit number of characters. Truncation is applied by returning the limit -// number of valid characters contained in s. -// -// If limit is negative, it returns the original string. -// -// UTF-8 is supported. When truncating, all invalid characters are dropped -// before applying truncation. -// -// If s already contains less than the limit number of bytes, it is returned -// unchanged. No invalid characters are removed. -func truncate(limit int, s string) string { - // This prioritize performance in the following order based on the most - // common expected use-cases. - // - // - Short values less than the default limit (128). - // - Strings with valid encodings that exceed the limit. - // - No limit. - // - Strings with invalid encodings that exceed the limit. - if limit < 0 || len(s) <= limit { - return s - } - - // Optimistically, assume all valid UTF-8. - var b strings.Builder - count := 0 - for i, c := range s { - if c != utf8.RuneError { - count++ - if count > limit { - return s[:i] - } - continue - } - - _, size := utf8.DecodeRuneInString(s[i:]) - if size == 1 { - // Invalid encoding. - b.Grow(len(s) - 1) - _, _ = b.WriteString(s[:i]) - s = s[i:] - break - } - } - - // Fast-path, no invalid input. - if b.Cap() == 0 { - return s - } - - // Truncate while validating UTF-8. - for i := 0; i < len(s) && count < limit; { - c := s[i] - if c < utf8.RuneSelf { - // Optimization for single byte runes (common case). - _ = b.WriteByte(c) - i++ - count++ - continue - } - - _, size := utf8.DecodeRuneInString(s[i:]) - if size == 1 { - // We checked for all 1-byte runes above, this is a RuneError. - i++ - continue - } - - _, _ = b.WriteString(s[i : i+size]) - i += size - count++ } - - return b.String() } // End ends the span. This method does nothing if the span is already ended or // is not being recorded. // -// The only SpanEndOption currently supported are [trace.WithTimestamp], and -// [trace.WithStackTrace]. -// -// If this method is called while panicking an error event is added to the -// Span before ending it and the panic is continued. +// The only supported SpanEndOptions are [trace.WithTimestamp] and [trace.WithStackTrace]. +// If this method is called while panicking and panic recording is not disabled +// on the TracerProvider, an error event is added to the Span before ending it +// and the panic is continued. func (s *recordingSpan) End(options ...trace.SpanEndOption) { // Do not start by checking if the span is being recorded which requires // acquiring a lock. Make a minimal check that the span is not nil. @@ -560,23 +408,25 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) { } config := trace.NewSpanEndConfig(options...) - if recovered := recover(); recovered != nil { - // Record but don't stop the panic. - defer panic(recovered) - opts := []trace.EventOption{ - trace.WithAttributes( - semconv.ExceptionType(typeStr(recovered)), - semconv.ExceptionMessage(fmt.Sprint(recovered)), - ), - } + if !s.tracer.provider.panicRecordingDisabled { + if recovered := recover(); recovered != nil { + // Record but don't stop the panic. + defer panic(recovered) + opts := []trace.EventOption{ + trace.WithAttributes( + semconv.ExceptionType(typeStr(recovered)), + semconv.ExceptionMessage(fmt.Sprint(recovered)), + ), + } - if config.StackTrace() { - opts = append(opts, trace.WithAttributes( - semconv.ExceptionStacktrace(recordStackTrace()), - )) - } + if config.StackTrace() { + opts = append(opts, trace.WithAttributes( + semconv.ExceptionStacktrace(recordStackTrace()), + )) + } - s.addEvent(semconv.ExceptionEventName, opts...) + s.addEvent(semconv.ExceptionEventName, opts...) + } } if s.executionTracerTaskEnd != nil { @@ -690,7 +540,8 @@ func (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) { // This method assumes s.mu.Lock is held by the caller. func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) { c := trace.NewEventConfig(o...) - e := Event{Name: name, Attributes: c.Attributes(), Time: c.Timestamp()} + attrs, _ := attrnorm.KeyValues(c.Attributes()) + e := Event{Name: name, Attributes: attrs, Time: c.Timestamp()} // Discard attributes over limit. limit := s.tracer.provider.spanLimits.AttributePerEventCountLimit @@ -765,6 +616,7 @@ func (s *recordingSpan) Attributes() []attribute.KeyValue { s.mu.Lock() defer s.mu.Unlock() s.dedupeAttrs() + s.attributesShared = cap(s.attributes) > 0 return s.attributes } @@ -772,6 +624,10 @@ func (s *recordingSpan) Attributes() []attribute.KeyValue { // // This method assumes s.mu.Lock is held by the caller. func (s *recordingSpan) dedupeAttrs() { + if !s.attributesDirty { + return + } + s.ensureAttrsWritable(len(s.attributes)) // Do not set a capacity when creating this map. Benchmark testing has // showed this to only add unused memory allocations in general use. exists := make(map[attribute.Key]int, len(s.attributes)) @@ -795,6 +651,7 @@ func (s *recordingSpan) dedupeAttrsFromRecord(record map[attribute.Key]int) { } clear(s.attributes[len(unique):]) // Erase unneeded elements to let GC collect objects. s.attributes = unique + s.attributesDirty = false } // Links returns the links of this span. @@ -863,7 +720,8 @@ func (s *recordingSpan) AddLink(link trace.Link) { return } - l := Link{SpanContext: link.SpanContext, Attributes: link.Attributes} + attrs, _ := attrnorm.KeyValues(link.Attributes) + l := Link{SpanContext: link.SpanContext, Attributes: attrs} // Discard attributes over limit. limit := s.tracer.provider.spanLimits.AttributePerLinkCountLimit @@ -937,6 +795,7 @@ func (s *recordingSpan) snapshot() ReadOnlySpan { if len(s.attributes) > 0 { s.dedupeAttrs() sd.attributes = s.attributes + s.attributesShared = true } sd.droppedAttributeCount = s.droppedAttributes if len(s.events.queue) > 0 { diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go index 6bdda3d94a4..fad839a24e4 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go index 348ee0e808b..5ee15a88485 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import "go.opentelemetry.io/otel/sdk/trace/internal/env" @@ -35,10 +35,10 @@ const ( type SpanLimits struct { // AttributeValueLengthLimit is the maximum allowed attribute value length. // - // This limit only applies to string, string slice, byte slice, and slice attribute - // values. Any string and byte slice longer than this value will be truncated to this - // length. For slice attribute values, the limit is applied to each string and byte slice - // element recursively. + // This limit only applies to string, string slice, byte slice, slice, and + // map attribute values. Any string and byte slice longer than this value + // will be truncated to this length. For slice and map attribute values, + // the limit is applied recursively to contained values. // // Setting this to a negative value means no limit is applied. AttributeValueLengthLimit int diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go index af7f9177fc5..ffd093a2f7e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go index e1d08fd4d8d..be576ffe088 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/sdk/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/exporter.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/exporter.go index e12fa67e63b..4aa2d562fdd 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/exporter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/exporter.go @@ -4,7 +4,7 @@ // Package tracetest is a testing helper package for the SDK. User can // configure no-op or in-memory exporters to verify different SDK behaviors or // custom instrumentation. -package tracetest // import "go.opentelemetry.io/otel/sdk/trace/tracetest" +package tracetest import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/recorder.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/recorder.go index ca63038f34e..11e3d5b3f61 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/recorder.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/recorder.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tracetest // import "go.opentelemetry.io/otel/sdk/trace/tracetest" +package tracetest import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/span.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/span.go index 12b384b0884..6ee1b3f9854 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/span.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracetest/span.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package tracetest // import "go.opentelemetry.io/otel/sdk/trace/tracetest" +package tracetest import ( "time" diff --git a/vendor/go.opentelemetry.io/otel/sdk/version.go b/vendor/go.opentelemetry.io/otel/sdk/version.go index 218dce1f562..621d6d7e621 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/version.go +++ b/vendor/go.opentelemetry.io/otel/sdk/version.go @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // Package sdk provides the OpenTelemetry default SDK for Go. -package sdk // import "go.opentelemetry.io/otel/sdk" +package sdk // Version is the current release version of the OpenTelemetry SDK in use. func Version() string { - return "1.44.0" + return "1.46.0" } diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/MIGRATION.md b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/MIGRATION.md deleted file mode 100644 index 8a11ea28d3e..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/MIGRATION.md +++ /dev/null @@ -1,155 +0,0 @@ -# Semantic Convention Changes - -The `go.opentelemetry.io/otel/semconv/v1.30.0` should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.28.0` with the following exceptions. - -Note: `go.opentelemetry.io/otel/semconv/v1.29.0` does not exist due to bugs from the upstream [OpenTelemetry Semantic Conventions]. - -## Dropped deprecations - -The following declarations have been deprecated in the [OpenTelemetry Semantic Conventions]. -Refer to the respective documentation in that repository for deprecation instructions for each type. - -- `CodeColumn` -- `CodeColumnKey` -- `CodeFunction` -- `CodeFunctionKey` -- `DBCassandraConsistencyLevelAll` -- `DBCassandraConsistencyLevelAny` -- `DBCassandraConsistencyLevelEachQuorum` -- `DBCassandraConsistencyLevelKey` -- `DBCassandraConsistencyLevelLocalOne` -- `DBCassandraConsistencyLevelLocalQuorum` -- `DBCassandraConsistencyLevelLocalSerial` -- `DBCassandraConsistencyLevelOne` -- `DBCassandraConsistencyLevelQuorum` -- `DBCassandraConsistencyLevelSerial` -- `DBCassandraConsistencyLevelThree` -- `DBCassandraConsistencyLevelTwo` -- `DBCassandraCoordinatorDC` -- `DBCassandraCoordinatorDCKey` -- `DBCassandraCoordinatorID` -- `DBCassandraCoordinatorIDKey` -- `DBCassandraIdempotence` -- `DBCassandraIdempotenceKey` -- `DBCassandraPageSize` -- `DBCassandraPageSizeKey` -- `DBCassandraSpeculativeExecutionCount` -- `DBCassandraSpeculativeExecutionCountKey` -- `DBCosmosDBClientID` -- `DBCosmosDBClientIDKey` -- `DBCosmosDBConnectionModeDirect` -- `DBCosmosDBConnectionModeGateway` -- `DBCosmosDBConnectionModeKey` -- `DBCosmosDBOperationTypeBatch` -- `DBCosmosDBOperationTypeCreate` -- `DBCosmosDBOperationTypeDelete` -- `DBCosmosDBOperationTypeExecute` -- `DBCosmosDBOperationTypeExecuteJavascript` -- `DBCosmosDBOperationTypeHead` -- `DBCosmosDBOperationTypeHeadFeed` -- `DBCosmosDBOperationTypeInvalid` -- `DBCosmosDBOperationTypeKey` -- `DBCosmosDBOperationTypePatch` -- `DBCosmosDBOperationTypeQuery` -- `DBCosmosDBOperationTypeQueryPlan` -- `DBCosmosDBOperationTypeRead` -- `DBCosmosDBOperationTypeReadFeed` -- `DBCosmosDBOperationTypeReplace` -- `DBCosmosDBOperationTypeUpsert` -- `DBCosmosDBRequestCharge` -- `DBCosmosDBRequestChargeKey` -- `DBCosmosDBRequestContentLength` -- `DBCosmosDBRequestContentLengthKey` -- `DBCosmosDBSubStatusCode` -- `DBCosmosDBSubStatusCodeKey` -- `DBElasticsearchNodeName` -- `DBElasticsearchNodeNameKey` -- `DBSystemAdabas` -- `DBSystemCache` -- `DBSystemCassandra` -- `DBSystemClickhouse` -- `DBSystemCloudscape` -- `DBSystemCockroachdb` -- `DBSystemColdfusion` -- `DBSystemCosmosDB` -- `DBSystemCouchDB` -- `DBSystemCouchbase` -- `DBSystemDb2` -- `DBSystemDerby` -- `DBSystemDynamoDB` -- `DBSystemEDB` -- `DBSystemElasticsearch` -- `DBSystemFilemaker` -- `DBSystemFirebird` -- `DBSystemFirstSQL` -- `DBSystemGeode` -- `DBSystemH2` -- `DBSystemHBase` -- `DBSystemHSQLDB` -- `DBSystemHanaDB` -- `DBSystemHive` -- `DBSystemInfluxdb` -- `DBSystemInformix` -- `DBSystemIngres` -- `DBSystemInstantDB` -- `DBSystemInterbase` -- `DBSystemIntersystemsCache` -- `DBSystemKey` -- `DBSystemMSSQL` -- `DBSystemMariaDB` -- `DBSystemMaxDB` -- `DBSystemMemcached` -- `DBSystemMongoDB` -- `DBSystemMssqlcompact` -- `DBSystemMySQL` -- `DBSystemNeo4j` -- `DBSystemNetezza` -- `DBSystemOpensearch` -- `DBSystemOracle` -- `DBSystemOtherSQL` -- `DBSystemPervasive` -- `DBSystemPointbase` -- `DBSystemPostgreSQL` -- `DBSystemProgress` -- `DBSystemRedis` -- `DBSystemRedshift` -- `DBSystemSpanner` -- `DBSystemSqlite` -- `DBSystemSybase` -- `DBSystemTeradata` -- `DBSystemTrino` -- `DBSystemVertica` -- `EventName` -- `EventNameKey` -- `ExceptionEscaped` -- `ExceptionEscapedKey` -- `GenAIOpenaiRequestSeed` -- `GenAIOpenaiRequestSeedKey` -- `ProcessExecutableBuildIDProfiling` -- `ProcessExecutableBuildIDProfilingKey` -- `SystemNetworkStateClose` -- `SystemNetworkStateCloseWait` -- `SystemNetworkStateClosing` -- `SystemNetworkStateDelete` -- `SystemNetworkStateEstablished` -- `SystemNetworkStateFinWait1` -- `SystemNetworkStateFinWait2` -- `SystemNetworkStateKey` -- `SystemNetworkStateLastAck` -- `SystemNetworkStateListen` -- `SystemNetworkStateSynRecv` -- `SystemNetworkStateSynSent` -- `SystemNetworkStateTimeWait` -- `VCSRepositoryChangeID` -- `VCSRepositoryChangeIDKey` -- `VCSRepositoryChangeTitle` -- `VCSRepositoryChangeTitleKey` -- `VCSRepositoryRefName` -- `VCSRepositoryRefNameKey` -- `VCSRepositoryRefRevision` -- `VCSRepositoryRefRevisionKey` -- `VCSRepositoryRefTypeBranch` -- `VCSRepositoryRefTypeKey` -- `VCSRepositoryRefTypeTag` - -[OpenTelemetry Semantic Conventions]: https://github.com/open-telemetry/semantic-conventions diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/README.md deleted file mode 100644 index 072ea6928fb..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Semconv v1.30.0 - -[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.30.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.30.0) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/attribute_group.go deleted file mode 100644 index f6a15666650..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/attribute_group.go +++ /dev/null @@ -1,12335 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// Code generated from semantic convention specification. DO NOT EDIT. - -package semconv - -import "go.opentelemetry.io/otel/attribute" - -// Namespace: android -const ( - // AndroidOSAPILevelKey is the attribute Key conforming to the - // "android.os.api_level" semantic conventions. It represents the uniquely - // identifies the framework API revision offered by a version (`os.version`) of - // the android operating system. More information can be found [here]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "33", "32" - // - // [here]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels - AndroidOSAPILevelKey = attribute.Key("android.os.api_level") -) - -// AndroidOSAPILevel returns an attribute KeyValue conforming to the -// "android.os.api_level" semantic conventions. It represents the uniquely -// identifies the framework API revision offered by a version (`os.version`) of -// the android operating system. More information can be found [here]. -// -// [here]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels -func AndroidOSAPILevel(val string) attribute.KeyValue { - return AndroidOSAPILevelKey.String(val) -} - -// Namespace: artifact -const ( - // ArtifactAttestationFilenameKey is the attribute Key conforming to the - // "artifact.attestation.filename" semantic conventions. It represents the - // provenance filename of the built attestation which directly relates to the - // build artifact filename. This filename SHOULD accompany the artifact at - // publish time. See the [SLSA Relationship] specification for more information. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "golang-binary-amd64-v0.1.0.attestation", - // "docker-image-amd64-v0.1.0.intoto.json1", "release-1.tar.gz.attestation", - // "file-name-package.tar.gz.intoto.json1" - // - // [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations - ArtifactAttestationFilenameKey = attribute.Key("artifact.attestation.filename") - - // ArtifactAttestationHashKey is the attribute Key conforming to the - // "artifact.attestation.hash" semantic conventions. It represents the full - // [hash value (see glossary)], of the built attestation. Some envelopes in the - // [software attestation space] also refer to this as the **digest**. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1b31dfcd5b7f9267bf2ff47651df1cfb9147b9e4df1f335accf65b4cda498408" - // - // [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf - // [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec - ArtifactAttestationHashKey = attribute.Key("artifact.attestation.hash") - - // ArtifactAttestationIDKey is the attribute Key conforming to the - // "artifact.attestation.id" semantic conventions. It represents the id of the - // build [software attestation]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "123" - // - // [software attestation]: https://slsa.dev/attestation-model - ArtifactAttestationIDKey = attribute.Key("artifact.attestation.id") - - // ArtifactFilenameKey is the attribute Key conforming to the - // "artifact.filename" semantic conventions. It represents the human readable - // file name of the artifact, typically generated during build and release - // processes. Often includes the package name and version in the file name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "golang-binary-amd64-v0.1.0", "docker-image-amd64-v0.1.0", - // "release-1.tar.gz", "file-name-package.tar.gz" - // Note: This file name can also act as the [Package Name] - // in cases where the package ecosystem maps accordingly. - // Additionally, the artifact [can be published] - // for others, but that is not a guarantee. - // - // [Package Name]: https://slsa.dev/spec/v1.0/terminology#package-model - // [can be published]: https://slsa.dev/spec/v1.0/terminology#software-supply-chain - ArtifactFilenameKey = attribute.Key("artifact.filename") - - // ArtifactHashKey is the attribute Key conforming to the "artifact.hash" - // semantic conventions. It represents the full [hash value (see glossary)], - // often found in checksum.txt on a release of the artifact and used to verify - // package integrity. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "9ff4c52759e2c4ac70b7d517bc7fcdc1cda631ca0045271ddd1b192544f8a3e9" - // Note: The specific algorithm used to create the cryptographic hash value is - // not defined. In situations where an artifact has multiple - // cryptographic hashes, it is up to the implementer to choose which - // hash value to set here; this should be the most secure hash algorithm - // that is suitable for the situation and consistent with the - // corresponding attestation. The implementer can then provide the other - // hash values through an additional set of attribute extensions as they - // deem necessary. - // - // [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf - ArtifactHashKey = attribute.Key("artifact.hash") - - // ArtifactPurlKey is the attribute Key conforming to the "artifact.purl" - // semantic conventions. It represents the [Package URL] of the - // [package artifact] provides a standard way to identify and locate the - // packaged artifact. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "pkg:github/package-url/purl-spec@1209109710924", - // "pkg:npm/foo@12.12.3" - // - // [Package URL]: https://github.com/package-url/purl-spec - // [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model - ArtifactPurlKey = attribute.Key("artifact.purl") - - // ArtifactVersionKey is the attribute Key conforming to the "artifact.version" - // semantic conventions. It represents the version of the artifact. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "v0.1.0", "1.2.1", "122691-build" - ArtifactVersionKey = attribute.Key("artifact.version") -) - -// ArtifactAttestationFilename returns an attribute KeyValue conforming to the -// "artifact.attestation.filename" semantic conventions. It represents the -// provenance filename of the built attestation which directly relates to the -// build artifact filename. This filename SHOULD accompany the artifact at -// publish time. See the [SLSA Relationship] specification for more information. -// -// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations -func ArtifactAttestationFilename(val string) attribute.KeyValue { - return ArtifactAttestationFilenameKey.String(val) -} - -// ArtifactAttestationHash returns an attribute KeyValue conforming to the -// "artifact.attestation.hash" semantic conventions. It represents the full -// [hash value (see glossary)], of the built attestation. Some envelopes in the -// [software attestation space] also refer to this as the **digest**. -// -// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf -// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec -func ArtifactAttestationHash(val string) attribute.KeyValue { - return ArtifactAttestationHashKey.String(val) -} - -// ArtifactAttestationID returns an attribute KeyValue conforming to the -// "artifact.attestation.id" semantic conventions. It represents the id of the -// build [software attestation]. -// -// [software attestation]: https://slsa.dev/attestation-model -func ArtifactAttestationID(val string) attribute.KeyValue { - return ArtifactAttestationIDKey.String(val) -} - -// ArtifactFilename returns an attribute KeyValue conforming to the -// "artifact.filename" semantic conventions. It represents the human readable -// file name of the artifact, typically generated during build and release -// processes. Often includes the package name and version in the file name. -func ArtifactFilename(val string) attribute.KeyValue { - return ArtifactFilenameKey.String(val) -} - -// ArtifactHash returns an attribute KeyValue conforming to the "artifact.hash" -// semantic conventions. It represents the full [hash value (see glossary)], -// often found in checksum.txt on a release of the artifact and used to verify -// package integrity. -// -// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf -func ArtifactHash(val string) attribute.KeyValue { - return ArtifactHashKey.String(val) -} - -// ArtifactPurl returns an attribute KeyValue conforming to the "artifact.purl" -// semantic conventions. It represents the [Package URL] of the -// [package artifact] provides a standard way to identify and locate the packaged -// artifact. -// -// [Package URL]: https://github.com/package-url/purl-spec -// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model -func ArtifactPurl(val string) attribute.KeyValue { - return ArtifactPurlKey.String(val) -} - -// ArtifactVersion returns an attribute KeyValue conforming to the -// "artifact.version" semantic conventions. It represents the version of the -// artifact. -func ArtifactVersion(val string) attribute.KeyValue { - return ArtifactVersionKey.String(val) -} - -// Namespace: aws -const ( - // AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to the - // "aws.dynamodb.attribute_definitions" semantic conventions. It represents the - // JSON-serialized value of each item in the `AttributeDefinitions` request - // field. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{ "AttributeName": "string", "AttributeType": "string" }" - AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions") - - // AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the - // "aws.dynamodb.attributes_to_get" semantic conventions. It represents the - // value of the `AttributesToGet` request parameter. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "lives", "id" - AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get") - - // AWSDynamoDBConsistentReadKey is the attribute Key conforming to the - // "aws.dynamodb.consistent_read" semantic conventions. It represents the value - // of the `ConsistentRead` request parameter. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read") - - // AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the - // "aws.dynamodb.consumed_capacity" semantic conventions. It represents the - // JSON-serialized value of each item in the `ConsumedCapacity` response field. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : - // { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": - // number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, - // "ReadCapacityUnits": number, "WriteCapacityUnits": number } }, - // "ReadCapacityUnits": number, "Table": { "CapacityUnits": number, - // "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName": - // "string", "WriteCapacityUnits": number }" - AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity") - - // AWSDynamoDBCountKey is the attribute Key conforming to the - // "aws.dynamodb.count" semantic conventions. It represents the value of the - // `Count` response parameter. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 10 - AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count") - - // AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the - // "aws.dynamodb.exclusive_start_table" semantic conventions. It represents the - // value of the `ExclusiveStartTableName` request parameter. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Users", "CatsTable" - AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table") - - // AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key conforming to - // the "aws.dynamodb.global_secondary_index_updates" semantic conventions. It - // represents the JSON-serialized value of each item in the - // `GlobalSecondaryIndexUpdates` request field. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{ "Create": { "IndexName": "string", "KeySchema": [ { - // "AttributeName": "string", "KeyType": "string" } ], "Projection": { - // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, - // "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits": - // number } }" - AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates") - - // AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to the - // "aws.dynamodb.global_secondary_indexes" semantic conventions. It represents - // the JSON-serialized value of each item of the `GlobalSecondaryIndexes` - // request field. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{ "IndexName": "string", "KeySchema": [ { "AttributeName": - // "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ - // "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": { - // "ReadCapacityUnits": number, "WriteCapacityUnits": number } }" - AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes") - - // AWSDynamoDBIndexNameKey is the attribute Key conforming to the - // "aws.dynamodb.index_name" semantic conventions. It represents the value of - // the `IndexName` request parameter. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "name_to_group" - AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name") - - // AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to the - // "aws.dynamodb.item_collection_metrics" semantic conventions. It represents - // the JSON-serialized value of the `ItemCollectionMetrics` response field. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, - // "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : - // "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": - // "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }" - AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics") - - // AWSDynamoDBLimitKey is the attribute Key conforming to the - // "aws.dynamodb.limit" semantic conventions. It represents the value of the - // `Limit` request parameter. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 10 - AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit") - - // AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to the - // "aws.dynamodb.local_secondary_indexes" semantic conventions. It represents - // the JSON-serialized value of each item of the `LocalSecondaryIndexes` request - // field. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": - // number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", - // "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], - // "ProjectionType": "string" } }" - AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes") - - // AWSDynamoDBProjectionKey is the attribute Key conforming to the - // "aws.dynamodb.projection" semantic conventions. It represents the value of - // the `ProjectionExpression` request parameter. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Title", "Title, Price, Color", "Title, Description, RelatedItems, - // ProductReviews" - AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection") - - // AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to the - // "aws.dynamodb.provisioned_read_capacity" semantic conventions. It represents - // the value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1.0, 2.0 - AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity") - - // AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming to the - // "aws.dynamodb.provisioned_write_capacity" semantic conventions. It represents - // the value of the `ProvisionedThroughput.WriteCapacityUnits` request - // parameter. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1.0, 2.0 - AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity") - - // AWSDynamoDBScanForwardKey is the attribute Key conforming to the - // "aws.dynamodb.scan_forward" semantic conventions. It represents the value of - // the `ScanIndexForward` request parameter. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward") - - // AWSDynamoDBScannedCountKey is the attribute Key conforming to the - // "aws.dynamodb.scanned_count" semantic conventions. It represents the value of - // the `ScannedCount` response parameter. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 50 - AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count") - - // AWSDynamoDBSegmentKey is the attribute Key conforming to the - // "aws.dynamodb.segment" semantic conventions. It represents the value of the - // `Segment` request parameter. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 10 - AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment") - - // AWSDynamoDBSelectKey is the attribute Key conforming to the - // "aws.dynamodb.select" semantic conventions. It represents the value of the - // `Select` request parameter. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "ALL_ATTRIBUTES", "COUNT" - AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select") - - // AWSDynamoDBTableCountKey is the attribute Key conforming to the - // "aws.dynamodb.table_count" semantic conventions. It represents the number of - // items in the `TableNames` response parameter. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 20 - AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count") - - // AWSDynamoDBTableNamesKey is the attribute Key conforming to the - // "aws.dynamodb.table_names" semantic conventions. It represents the keys in - // the `RequestItems` object field. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Users", "Cats" - AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names") - - // AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the - // "aws.dynamodb.total_segments" semantic conventions. It represents the value - // of the `TotalSegments` request parameter. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 100 - AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments") - - // AWSECSClusterARNKey is the attribute Key conforming to the - // "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an - // [ECS cluster]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster" - // - // [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html - AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn") - - // AWSECSContainerARNKey is the attribute Key conforming to the - // "aws.ecs.container.arn" semantic conventions. It represents the Amazon - // Resource Name (ARN) of an [ECS container instance]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9" - // - // [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html - AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn") - - // AWSECSLaunchtypeKey is the attribute Key conforming to the - // "aws.ecs.launchtype" semantic conventions. It represents the [launch type] - // for an ECS task. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // - // [launch type]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html - AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype") - - // AWSECSTaskARNKey is the attribute Key conforming to the "aws.ecs.task.arn" - // semantic conventions. It represents the ARN of a running [ECS task]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b", - // "arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd" - // - // [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids - AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn") - - // AWSECSTaskFamilyKey is the attribute Key conforming to the - // "aws.ecs.task.family" semantic conventions. It represents the family name of - // the [ECS task definition] used to create the ECS task. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry-family" - // - // [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html - AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family") - - // AWSECSTaskIDKey is the attribute Key conforming to the "aws.ecs.task.id" - // semantic conventions. It represents the ID of a running ECS task. The ID MUST - // be extracted from `task.arn`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "10838bed-421f-43ef-870a-f43feacbbb5b", - // "23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd" - AWSECSTaskIDKey = attribute.Key("aws.ecs.task.id") - - // AWSECSTaskRevisionKey is the attribute Key conforming to the - // "aws.ecs.task.revision" semantic conventions. It represents the revision for - // the task definition used to create the ECS task. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "8", "26" - AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision") - - // AWSEKSClusterARNKey is the attribute Key conforming to the - // "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS - // cluster. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster" - AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn") - - // AWSExtendedRequestIDKey is the attribute Key conforming to the - // "aws.extended_request_id" semantic conventions. It represents the AWS - // extended request ID as returned in the response header `x-amz-id-2`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "wzHcyEWfmOGDIE5QOhTAqFDoDWP3y8IUvpNINCwL9N4TEHbUw0/gZJ+VZTmCNCWR7fezEN3eCiQ=" - AWSExtendedRequestIDKey = attribute.Key("aws.extended_request_id") - - // AWSLambdaInvokedARNKey is the attribute Key conforming to the - // "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked - // ARN as provided on the `Context` passed to the function ( - // `Lambda-Runtime-Invoked-Function-Arn` header on the - // `/runtime/invocation/next` applicable). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "arn:aws:lambda:us-east-1:123456:function:myfunction:myalias" - // Note: This may be different from `cloud.resource_id` if an alias is involved. - AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn") - - // AWSLogGroupARNsKey is the attribute Key conforming to the - // "aws.log.group.arns" semantic conventions. It represents the Amazon Resource - // Name(s) (ARN) of the AWS log group(s). - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*" - // Note: See the [log group ARN format documentation]. - // - // [log group ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format - AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns") - - // AWSLogGroupNamesKey is the attribute Key conforming to the - // "aws.log.group.names" semantic conventions. It represents the name(s) of the - // AWS log group(s) an application is writing to. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/aws/lambda/my-function", "opentelemetry-service" - // Note: Multiple log groups must be supported for cases like multi-container - // applications, where a single application has sidecar containers, and each - // write to their own log group. - AWSLogGroupNamesKey = attribute.Key("aws.log.group.names") - - // AWSLogStreamARNsKey is the attribute Key conforming to the - // "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the - // AWS log stream(s). - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b" - // Note: See the [log stream ARN format documentation]. One log group can - // contain several log streams, so these ARNs necessarily identify both a log - // group and a log stream. - // - // [log stream ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format - AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns") - - // AWSLogStreamNamesKey is the attribute Key conforming to the - // "aws.log.stream.names" semantic conventions. It represents the name(s) of the - // AWS log stream(s) an application is writing to. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "logs/main/10838bed-421f-43ef-870a-f43feacbbb5b" - AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names") - - // AWSRequestIDKey is the attribute Key conforming to the "aws.request_id" - // semantic conventions. It represents the AWS request ID as returned in the - // response headers `x-amzn-requestid`, `x-amzn-request-id` or - // `x-amz-request-id`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "79b9da39-b7ae-508a-a6bc-864b2829c622", "C9ER4AJX75574TDJ" - AWSRequestIDKey = attribute.Key("aws.request_id") - - // AWSS3BucketKey is the attribute Key conforming to the "aws.s3.bucket" - // semantic conventions. It represents the S3 bucket name the request refers to. - // Corresponds to the `--bucket` parameter of the [S3 API] operations. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "some-bucket-name" - // Note: The `bucket` attribute is applicable to all S3 operations that - // reference a bucket, i.e. that require the bucket name as a mandatory - // parameter. - // This applies to almost all S3 operations except `list-buckets`. - // - // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html - AWSS3BucketKey = attribute.Key("aws.s3.bucket") - - // AWSS3CopySourceKey is the attribute Key conforming to the - // "aws.s3.copy_source" semantic conventions. It represents the source object - // (in the form `bucket`/`key`) for the copy operation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "someFile.yml" - // Note: The `copy_source` attribute applies to S3 copy operations and - // corresponds to the `--copy-source` parameter - // of the [copy-object operation within the S3 API]. - // This applies in particular to the following operations: - // - // - [copy-object] - // - [upload-part-copy] - // - // - // [copy-object operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html - // [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html - // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html - AWSS3CopySourceKey = attribute.Key("aws.s3.copy_source") - - // AWSS3DeleteKey is the attribute Key conforming to the "aws.s3.delete" - // semantic conventions. It represents the delete request container that - // specifies the objects to be deleted. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean" - // Note: The `delete` attribute is only applicable to the [delete-object] - // operation. - // The `delete` attribute corresponds to the `--delete` parameter of the - // [delete-objects operation within the S3 API]. - // - // [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html - // [delete-objects operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html - AWSS3DeleteKey = attribute.Key("aws.s3.delete") - - // AWSS3KeyKey is the attribute Key conforming to the "aws.s3.key" semantic - // conventions. It represents the S3 object key the request refers to. - // Corresponds to the `--key` parameter of the [S3 API] operations. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "someFile.yml" - // Note: The `key` attribute is applicable to all object-related S3 operations, - // i.e. that require the object key as a mandatory parameter. - // This applies in particular to the following operations: - // - // - [copy-object] - // - [delete-object] - // - [get-object] - // - [head-object] - // - [put-object] - // - [restore-object] - // - [select-object-content] - // - [abort-multipart-upload] - // - [complete-multipart-upload] - // - [create-multipart-upload] - // - [list-parts] - // - [upload-part] - // - [upload-part-copy] - // - // - // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html - // [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html - // [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html - // [get-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html - // [head-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html - // [put-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html - // [restore-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html - // [select-object-content]: https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html - // [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html - // [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html - // [create-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html - // [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html - // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html - // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html - AWSS3KeyKey = attribute.Key("aws.s3.key") - - // AWSS3PartNumberKey is the attribute Key conforming to the - // "aws.s3.part_number" semantic conventions. It represents the part number of - // the part being uploaded in a multipart-upload operation. This is a positive - // integer between 1 and 10,000. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 3456 - // Note: The `part_number` attribute is only applicable to the [upload-part] - // and [upload-part-copy] operations. - // The `part_number` attribute corresponds to the `--part-number` parameter of - // the - // [upload-part operation within the S3 API]. - // - // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html - // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html - // [upload-part operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html - AWSS3PartNumberKey = attribute.Key("aws.s3.part_number") - - // AWSS3UploadIDKey is the attribute Key conforming to the "aws.s3.upload_id" - // semantic conventions. It represents the upload ID that identifies the - // multipart upload. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ" - // Note: The `upload_id` attribute applies to S3 multipart-upload operations and - // corresponds to the `--upload-id` parameter - // of the [S3 API] multipart operations. - // This applies in particular to the following operations: - // - // - [abort-multipart-upload] - // - [complete-multipart-upload] - // - [list-parts] - // - [upload-part] - // - [upload-part-copy] - // - // - // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html - // [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html - // [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html - // [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html - // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html - // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html - AWSS3UploadIDKey = attribute.Key("aws.s3.upload_id") -) - -// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming to -// the "aws.dynamodb.attribute_definitions" semantic conventions. It represents -// the JSON-serialized value of each item in the `AttributeDefinitions` request -// field. -func AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue { - return AWSDynamoDBAttributeDefinitionsKey.StringSlice(val) -} - -// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to the -// "aws.dynamodb.attributes_to_get" semantic conventions. It represents the value -// of the `AttributesToGet` request parameter. -func AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue { - return AWSDynamoDBAttributesToGetKey.StringSlice(val) -} - -// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the -// "aws.dynamodb.consistent_read" semantic conventions. It represents the value -// of the `ConsistentRead` request parameter. -func AWSDynamoDBConsistentRead(val bool) attribute.KeyValue { - return AWSDynamoDBConsistentReadKey.Bool(val) -} - -// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to the -// "aws.dynamodb.consumed_capacity" semantic conventions. It represents the -// JSON-serialized value of each item in the `ConsumedCapacity` response field. -func AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue { - return AWSDynamoDBConsumedCapacityKey.StringSlice(val) -} - -// AWSDynamoDBCount returns an attribute KeyValue conforming to the -// "aws.dynamodb.count" semantic conventions. It represents the value of the -// `Count` response parameter. -func AWSDynamoDBCount(val int) attribute.KeyValue { - return AWSDynamoDBCountKey.Int(val) -} - -// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming to the -// "aws.dynamodb.exclusive_start_table" semantic conventions. It represents the -// value of the `ExclusiveStartTableName` request parameter. -func AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue { - return AWSDynamoDBExclusiveStartTableKey.String(val) -} - -// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue -// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic -// conventions. It represents the JSON-serialized value of each item in the -// `GlobalSecondaryIndexUpdates` request field. -func AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue { - return AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val) -} - -// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue conforming to -// the "aws.dynamodb.global_secondary_indexes" semantic conventions. It -// represents the JSON-serialized value of each item of the -// `GlobalSecondaryIndexes` request field. -func AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue { - return AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val) -} - -// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the -// "aws.dynamodb.index_name" semantic conventions. It represents the value of the -// `IndexName` request parameter. -func AWSDynamoDBIndexName(val string) attribute.KeyValue { - return AWSDynamoDBIndexNameKey.String(val) -} - -// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming to -// the "aws.dynamodb.item_collection_metrics" semantic conventions. It represents -// the JSON-serialized value of the `ItemCollectionMetrics` response field. -func AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue { - return AWSDynamoDBItemCollectionMetricsKey.String(val) -} - -// AWSDynamoDBLimit returns an attribute KeyValue conforming to the -// "aws.dynamodb.limit" semantic conventions. It represents the value of the -// `Limit` request parameter. -func AWSDynamoDBLimit(val int) attribute.KeyValue { - return AWSDynamoDBLimitKey.Int(val) -} - -// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming to -// the "aws.dynamodb.local_secondary_indexes" semantic conventions. It represents -// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request -// field. -func AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue { - return AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val) -} - -// AWSDynamoDBProjection returns an attribute KeyValue conforming to the -// "aws.dynamodb.projection" semantic conventions. It represents the value of the -// `ProjectionExpression` request parameter. -func AWSDynamoDBProjection(val string) attribute.KeyValue { - return AWSDynamoDBProjectionKey.String(val) -} - -// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue conforming to -// the "aws.dynamodb.provisioned_read_capacity" semantic conventions. It -// represents the value of the `ProvisionedThroughput.ReadCapacityUnits` request -// parameter. -func AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue { - return AWSDynamoDBProvisionedReadCapacityKey.Float64(val) -} - -// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue conforming -// to the "aws.dynamodb.provisioned_write_capacity" semantic conventions. It -// represents the value of the `ProvisionedThroughput.WriteCapacityUnits` request -// parameter. -func AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue { - return AWSDynamoDBProvisionedWriteCapacityKey.Float64(val) -} - -// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the -// "aws.dynamodb.scan_forward" semantic conventions. It represents the value of -// the `ScanIndexForward` request parameter. -func AWSDynamoDBScanForward(val bool) attribute.KeyValue { - return AWSDynamoDBScanForwardKey.Bool(val) -} - -// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the -// "aws.dynamodb.scanned_count" semantic conventions. It represents the value of -// the `ScannedCount` response parameter. -func AWSDynamoDBScannedCount(val int) attribute.KeyValue { - return AWSDynamoDBScannedCountKey.Int(val) -} - -// AWSDynamoDBSegment returns an attribute KeyValue conforming to the -// "aws.dynamodb.segment" semantic conventions. It represents the value of the -// `Segment` request parameter. -func AWSDynamoDBSegment(val int) attribute.KeyValue { - return AWSDynamoDBSegmentKey.Int(val) -} - -// AWSDynamoDBSelect returns an attribute KeyValue conforming to the -// "aws.dynamodb.select" semantic conventions. It represents the value of the -// `Select` request parameter. -func AWSDynamoDBSelect(val string) attribute.KeyValue { - return AWSDynamoDBSelectKey.String(val) -} - -// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the -// "aws.dynamodb.table_count" semantic conventions. It represents the number of -// items in the `TableNames` response parameter. -func AWSDynamoDBTableCount(val int) attribute.KeyValue { - return AWSDynamoDBTableCountKey.Int(val) -} - -// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the -// "aws.dynamodb.table_names" semantic conventions. It represents the keys in the -// `RequestItems` object field. -func AWSDynamoDBTableNames(val ...string) attribute.KeyValue { - return AWSDynamoDBTableNamesKey.StringSlice(val) -} - -// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the -// "aws.dynamodb.total_segments" semantic conventions. It represents the value of -// the `TotalSegments` request parameter. -func AWSDynamoDBTotalSegments(val int) attribute.KeyValue { - return AWSDynamoDBTotalSegmentsKey.Int(val) -} - -// AWSECSClusterARN returns an attribute KeyValue conforming to the -// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an -// [ECS cluster]. -// -// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html -func AWSECSClusterARN(val string) attribute.KeyValue { - return AWSECSClusterARNKey.String(val) -} - -// AWSECSContainerARN returns an attribute KeyValue conforming to the -// "aws.ecs.container.arn" semantic conventions. It represents the Amazon -// Resource Name (ARN) of an [ECS container instance]. -// -// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html -func AWSECSContainerARN(val string) attribute.KeyValue { - return AWSECSContainerARNKey.String(val) -} - -// AWSECSTaskARN returns an attribute KeyValue conforming to the -// "aws.ecs.task.arn" semantic conventions. It represents the ARN of a running -// [ECS task]. -// -// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids -func AWSECSTaskARN(val string) attribute.KeyValue { - return AWSECSTaskARNKey.String(val) -} - -// AWSECSTaskFamily returns an attribute KeyValue conforming to the -// "aws.ecs.task.family" semantic conventions. It represents the family name of -// the [ECS task definition] used to create the ECS task. -// -// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html -func AWSECSTaskFamily(val string) attribute.KeyValue { - return AWSECSTaskFamilyKey.String(val) -} - -// AWSECSTaskID returns an attribute KeyValue conforming to the "aws.ecs.task.id" -// semantic conventions. It represents the ID of a running ECS task. The ID MUST -// be extracted from `task.arn`. -func AWSECSTaskID(val string) attribute.KeyValue { - return AWSECSTaskIDKey.String(val) -} - -// AWSECSTaskRevision returns an attribute KeyValue conforming to the -// "aws.ecs.task.revision" semantic conventions. It represents the revision for -// the task definition used to create the ECS task. -func AWSECSTaskRevision(val string) attribute.KeyValue { - return AWSECSTaskRevisionKey.String(val) -} - -// AWSEKSClusterARN returns an attribute KeyValue conforming to the -// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS -// cluster. -func AWSEKSClusterARN(val string) attribute.KeyValue { - return AWSEKSClusterARNKey.String(val) -} - -// AWSExtendedRequestID returns an attribute KeyValue conforming to the -// "aws.extended_request_id" semantic conventions. It represents the AWS extended -// request ID as returned in the response header `x-amz-id-2`. -func AWSExtendedRequestID(val string) attribute.KeyValue { - return AWSExtendedRequestIDKey.String(val) -} - -// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the -// "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked -// ARN as provided on the `Context` passed to the function ( -// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` -// -// applicable). -func AWSLambdaInvokedARN(val string) attribute.KeyValue { - return AWSLambdaInvokedARNKey.String(val) -} - -// AWSLogGroupARNs returns an attribute KeyValue conforming to the -// "aws.log.group.arns" semantic conventions. It represents the Amazon Resource -// Name(s) (ARN) of the AWS log group(s). -func AWSLogGroupARNs(val ...string) attribute.KeyValue { - return AWSLogGroupARNsKey.StringSlice(val) -} - -// AWSLogGroupNames returns an attribute KeyValue conforming to the -// "aws.log.group.names" semantic conventions. It represents the name(s) of the -// AWS log group(s) an application is writing to. -func AWSLogGroupNames(val ...string) attribute.KeyValue { - return AWSLogGroupNamesKey.StringSlice(val) -} - -// AWSLogStreamARNs returns an attribute KeyValue conforming to the -// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the -// AWS log stream(s). -func AWSLogStreamARNs(val ...string) attribute.KeyValue { - return AWSLogStreamARNsKey.StringSlice(val) -} - -// AWSLogStreamNames returns an attribute KeyValue conforming to the -// "aws.log.stream.names" semantic conventions. It represents the name(s) of the -// AWS log stream(s) an application is writing to. -func AWSLogStreamNames(val ...string) attribute.KeyValue { - return AWSLogStreamNamesKey.StringSlice(val) -} - -// AWSRequestID returns an attribute KeyValue conforming to the "aws.request_id" -// semantic conventions. It represents the AWS request ID as returned in the -// response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id` -// . -func AWSRequestID(val string) attribute.KeyValue { - return AWSRequestIDKey.String(val) -} - -// AWSS3Bucket returns an attribute KeyValue conforming to the "aws.s3.bucket" -// semantic conventions. It represents the S3 bucket name the request refers to. -// Corresponds to the `--bucket` parameter of the [S3 API] operations. -// -// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html -func AWSS3Bucket(val string) attribute.KeyValue { - return AWSS3BucketKey.String(val) -} - -// AWSS3CopySource returns an attribute KeyValue conforming to the -// "aws.s3.copy_source" semantic conventions. It represents the source object (in -// the form `bucket`/`key`) for the copy operation. -func AWSS3CopySource(val string) attribute.KeyValue { - return AWSS3CopySourceKey.String(val) -} - -// AWSS3Delete returns an attribute KeyValue conforming to the "aws.s3.delete" -// semantic conventions. It represents the delete request container that -// specifies the objects to be deleted. -func AWSS3Delete(val string) attribute.KeyValue { - return AWSS3DeleteKey.String(val) -} - -// AWSS3Key returns an attribute KeyValue conforming to the "aws.s3.key" semantic -// conventions. It represents the S3 object key the request refers to. -// Corresponds to the `--key` parameter of the [S3 API] operations. -// -// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html -func AWSS3Key(val string) attribute.KeyValue { - return AWSS3KeyKey.String(val) -} - -// AWSS3PartNumber returns an attribute KeyValue conforming to the -// "aws.s3.part_number" semantic conventions. It represents the part number of -// the part being uploaded in a multipart-upload operation. This is a positive -// integer between 1 and 10,000. -func AWSS3PartNumber(val int) attribute.KeyValue { - return AWSS3PartNumberKey.Int(val) -} - -// AWSS3UploadID returns an attribute KeyValue conforming to the -// "aws.s3.upload_id" semantic conventions. It represents the upload ID that -// identifies the multipart upload. -func AWSS3UploadID(val string) attribute.KeyValue { - return AWSS3UploadIDKey.String(val) -} - -// Enum values for aws.ecs.launchtype -var ( - // ec2 - // Stability: development - AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2") - // fargate - // Stability: development - AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate") -) - -// Namespace: az -const ( - // AzNamespaceKey is the attribute Key conforming to the "az.namespace" semantic - // conventions. It represents the [Azure Resource Provider Namespace] as - // recognized by the client. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Microsoft.Storage", "Microsoft.KeyVault", "Microsoft.ServiceBus" - // - // [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers - AzNamespaceKey = attribute.Key("az.namespace") - - // AzServiceRequestIDKey is the attribute Key conforming to the - // "az.service_request_id" semantic conventions. It represents the unique - // identifier of the service request. It's generated by the Azure service and - // returned with the response. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "00000000-0000-0000-0000-000000000000" - AzServiceRequestIDKey = attribute.Key("az.service_request_id") -) - -// AzNamespace returns an attribute KeyValue conforming to the "az.namespace" -// semantic conventions. It represents the [Azure Resource Provider Namespace] as -// recognized by the client. -// -// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers -func AzNamespace(val string) attribute.KeyValue { - return AzNamespaceKey.String(val) -} - -// AzServiceRequestID returns an attribute KeyValue conforming to the -// "az.service_request_id" semantic conventions. It represents the unique -// identifier of the service request. It's generated by the Azure service and -// returned with the response. -func AzServiceRequestID(val string) attribute.KeyValue { - return AzServiceRequestIDKey.String(val) -} - -// Namespace: azure -const ( - // AzureClientIDKey is the attribute Key conforming to the "azure.client.id" - // semantic conventions. It represents the unique identifier of the client - // instance. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "3ba4827d-4422-483f-b59f-85b74211c11d", "storage-client-1" - AzureClientIDKey = attribute.Key("azure.client.id") - - // AzureCosmosDBConnectionModeKey is the attribute Key conforming to the - // "azure.cosmosdb.connection.mode" semantic conventions. It represents the - // cosmos client connection mode. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - AzureCosmosDBConnectionModeKey = attribute.Key("azure.cosmosdb.connection.mode") - - // AzureCosmosDBConsistencyLevelKey is the attribute Key conforming to the - // "azure.cosmosdb.consistency.level" semantic conventions. It represents the - // account or request [consistency level]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Eventual", "ConsistentPrefix", "BoundedStaleness", "Strong", - // "Session" - // - // [consistency level]: https://learn.microsoft.com/azure/cosmos-db/consistency-levels - AzureCosmosDBConsistencyLevelKey = attribute.Key("azure.cosmosdb.consistency.level") - - // AzureCosmosDBOperationContactedRegionsKey is the attribute Key conforming to - // the "azure.cosmosdb.operation.contacted_regions" semantic conventions. It - // represents the list of regions contacted during operation in the order that - // they were contacted. If there is more than one region listed, it indicates - // that the operation was performed on multiple regions i.e. cross-regional - // call. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "North Central US", "Australia East", "Australia Southeast" - // Note: Region name matches the format of `displayName` in [Azure Location API] - // - // [Azure Location API]: https://learn.microsoft.com/rest/api/subscription/subscriptions/list-locations?view=rest-subscription-2021-10-01&tabs=HTTP#location - AzureCosmosDBOperationContactedRegionsKey = attribute.Key("azure.cosmosdb.operation.contacted_regions") - - // AzureCosmosDBOperationRequestChargeKey is the attribute Key conforming to the - // "azure.cosmosdb.operation.request_charge" semantic conventions. It represents - // the number of request units consumed by the operation. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 46.18, 1.0 - AzureCosmosDBOperationRequestChargeKey = attribute.Key("azure.cosmosdb.operation.request_charge") - - // AzureCosmosDBRequestBodySizeKey is the attribute Key conforming to the - // "azure.cosmosdb.request.body.size" semantic conventions. It represents the - // request payload size in bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - AzureCosmosDBRequestBodySizeKey = attribute.Key("azure.cosmosdb.request.body.size") - - // AzureCosmosDBResponseSubStatusCodeKey is the attribute Key conforming to the - // "azure.cosmosdb.response.sub_status_code" semantic conventions. It represents - // the cosmos DB sub status code. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1000, 1002 - AzureCosmosDBResponseSubStatusCodeKey = attribute.Key("azure.cosmosdb.response.sub_status_code") -) - -// AzureClientID returns an attribute KeyValue conforming to the -// "azure.client.id" semantic conventions. It represents the unique identifier of -// the client instance. -func AzureClientID(val string) attribute.KeyValue { - return AzureClientIDKey.String(val) -} - -// AzureCosmosDBOperationContactedRegions returns an attribute KeyValue -// conforming to the "azure.cosmosdb.operation.contacted_regions" semantic -// conventions. It represents the list of regions contacted during operation in -// the order that they were contacted. If there is more than one region listed, -// it indicates that the operation was performed on multiple regions i.e. -// cross-regional call. -func AzureCosmosDBOperationContactedRegions(val ...string) attribute.KeyValue { - return AzureCosmosDBOperationContactedRegionsKey.StringSlice(val) -} - -// AzureCosmosDBOperationRequestCharge returns an attribute KeyValue conforming -// to the "azure.cosmosdb.operation.request_charge" semantic conventions. It -// represents the number of request units consumed by the operation. -func AzureCosmosDBOperationRequestCharge(val float64) attribute.KeyValue { - return AzureCosmosDBOperationRequestChargeKey.Float64(val) -} - -// AzureCosmosDBRequestBodySize returns an attribute KeyValue conforming to the -// "azure.cosmosdb.request.body.size" semantic conventions. It represents the -// request payload size in bytes. -func AzureCosmosDBRequestBodySize(val int) attribute.KeyValue { - return AzureCosmosDBRequestBodySizeKey.Int(val) -} - -// AzureCosmosDBResponseSubStatusCode returns an attribute KeyValue conforming to -// the "azure.cosmosdb.response.sub_status_code" semantic conventions. It -// represents the cosmos DB sub status code. -func AzureCosmosDBResponseSubStatusCode(val int) attribute.KeyValue { - return AzureCosmosDBResponseSubStatusCodeKey.Int(val) -} - -// Enum values for azure.cosmosdb.connection.mode -var ( - // Gateway (HTTP) connection. - // Stability: development - AzureCosmosDBConnectionModeGateway = AzureCosmosDBConnectionModeKey.String("gateway") - // Direct connection. - // Stability: development - AzureCosmosDBConnectionModeDirect = AzureCosmosDBConnectionModeKey.String("direct") -) - -// Enum values for azure.cosmosdb.consistency.level -var ( - // strong - // Stability: development - AzureCosmosDBConsistencyLevelStrong = AzureCosmosDBConsistencyLevelKey.String("Strong") - // bounded_staleness - // Stability: development - AzureCosmosDBConsistencyLevelBoundedStaleness = AzureCosmosDBConsistencyLevelKey.String("BoundedStaleness") - // session - // Stability: development - AzureCosmosDBConsistencyLevelSession = AzureCosmosDBConsistencyLevelKey.String("Session") - // eventual - // Stability: development - AzureCosmosDBConsistencyLevelEventual = AzureCosmosDBConsistencyLevelKey.String("Eventual") - // consistent_prefix - // Stability: development - AzureCosmosDBConsistencyLevelConsistentPrefix = AzureCosmosDBConsistencyLevelKey.String("ConsistentPrefix") -) - -// Namespace: browser -const ( - // BrowserBrandsKey is the attribute Key conforming to the "browser.brands" - // semantic conventions. It represents the array of brand name and version - // separated by a space. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: " Not A;Brand 99", "Chromium 99", "Chrome 99" - // Note: This value is intended to be taken from the [UA client hints API] ( - // `navigator.userAgentData.brands`). - // - // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface - BrowserBrandsKey = attribute.Key("browser.brands") - - // BrowserLanguageKey is the attribute Key conforming to the "browser.language" - // semantic conventions. It represents the preferred language of the user using - // the browser. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "en", "en-US", "fr", "fr-FR" - // Note: This value is intended to be taken from the Navigator API - // `navigator.language`. - BrowserLanguageKey = attribute.Key("browser.language") - - // BrowserMobileKey is the attribute Key conforming to the "browser.mobile" - // semantic conventions. It represents a boolean that is true if the browser is - // running on a mobile device. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: This value is intended to be taken from the [UA client hints API] ( - // `navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be - // left unset. - // - // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface - BrowserMobileKey = attribute.Key("browser.mobile") - - // BrowserPlatformKey is the attribute Key conforming to the "browser.platform" - // semantic conventions. It represents the platform on which the browser is - // running. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Windows", "macOS", "Android" - // Note: This value is intended to be taken from the [UA client hints API] ( - // `navigator.userAgentData.platform`). If unavailable, the legacy - // `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD - // be left unset in order for the values to be consistent. - // The list of possible values is defined in the - // [W3C User-Agent Client Hints specification]. Note that some (but not all) of - // these values can overlap with values in the - // [`os.type` and `os.name` attributes]. However, for consistency, the values in - // the `browser.platform` attribute should capture the exact value that the user - // agent provides. - // - // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface - // [W3C User-Agent Client Hints specification]: https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform - // [`os.type` and `os.name` attributes]: ./os.md - BrowserPlatformKey = attribute.Key("browser.platform") -) - -// BrowserBrands returns an attribute KeyValue conforming to the "browser.brands" -// semantic conventions. It represents the array of brand name and version -// separated by a space. -func BrowserBrands(val ...string) attribute.KeyValue { - return BrowserBrandsKey.StringSlice(val) -} - -// BrowserLanguage returns an attribute KeyValue conforming to the -// "browser.language" semantic conventions. It represents the preferred language -// of the user using the browser. -func BrowserLanguage(val string) attribute.KeyValue { - return BrowserLanguageKey.String(val) -} - -// BrowserMobile returns an attribute KeyValue conforming to the "browser.mobile" -// semantic conventions. It represents a boolean that is true if the browser is -// running on a mobile device. -func BrowserMobile(val bool) attribute.KeyValue { - return BrowserMobileKey.Bool(val) -} - -// BrowserPlatform returns an attribute KeyValue conforming to the -// "browser.platform" semantic conventions. It represents the platform on which -// the browser is running. -func BrowserPlatform(val string) attribute.KeyValue { - return BrowserPlatformKey.String(val) -} - -// Namespace: cassandra -const ( - // CassandraConsistencyLevelKey is the attribute Key conforming to the - // "cassandra.consistency.level" semantic conventions. It represents the - // consistency level of the query. Based on consistency values from [CQL]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // - // [CQL]: https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html - CassandraConsistencyLevelKey = attribute.Key("cassandra.consistency.level") - - // CassandraCoordinatorDCKey is the attribute Key conforming to the - // "cassandra.coordinator.dc" semantic conventions. It represents the data - // center of the coordinating node for a query. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: us-west-2 - CassandraCoordinatorDCKey = attribute.Key("cassandra.coordinator.dc") - - // CassandraCoordinatorIDKey is the attribute Key conforming to the - // "cassandra.coordinator.id" semantic conventions. It represents the ID of the - // coordinating node for a query. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: be13faa2-8574-4d71-926d-27f16cf8a7af - CassandraCoordinatorIDKey = attribute.Key("cassandra.coordinator.id") - - // CassandraPageSizeKey is the attribute Key conforming to the - // "cassandra.page.size" semantic conventions. It represents the fetch size used - // for paging, i.e. how many rows will be returned at once. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 5000 - CassandraPageSizeKey = attribute.Key("cassandra.page.size") - - // CassandraQueryIdempotentKey is the attribute Key conforming to the - // "cassandra.query.idempotent" semantic conventions. It represents the whether - // or not the query is idempotent. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - CassandraQueryIdempotentKey = attribute.Key("cassandra.query.idempotent") - - // CassandraSpeculativeExecutionCountKey is the attribute Key conforming to the - // "cassandra.speculative_execution.count" semantic conventions. It represents - // the number of times a query was speculatively executed. Not set or `0` if the - // query was not executed speculatively. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0, 2 - CassandraSpeculativeExecutionCountKey = attribute.Key("cassandra.speculative_execution.count") -) - -// CassandraCoordinatorDC returns an attribute KeyValue conforming to the -// "cassandra.coordinator.dc" semantic conventions. It represents the data center -// of the coordinating node for a query. -func CassandraCoordinatorDC(val string) attribute.KeyValue { - return CassandraCoordinatorDCKey.String(val) -} - -// CassandraCoordinatorID returns an attribute KeyValue conforming to the -// "cassandra.coordinator.id" semantic conventions. It represents the ID of the -// coordinating node for a query. -func CassandraCoordinatorID(val string) attribute.KeyValue { - return CassandraCoordinatorIDKey.String(val) -} - -// CassandraPageSize returns an attribute KeyValue conforming to the -// "cassandra.page.size" semantic conventions. It represents the fetch size used -// for paging, i.e. how many rows will be returned at once. -func CassandraPageSize(val int) attribute.KeyValue { - return CassandraPageSizeKey.Int(val) -} - -// CassandraQueryIdempotent returns an attribute KeyValue conforming to the -// "cassandra.query.idempotent" semantic conventions. It represents the whether -// or not the query is idempotent. -func CassandraQueryIdempotent(val bool) attribute.KeyValue { - return CassandraQueryIdempotentKey.Bool(val) -} - -// CassandraSpeculativeExecutionCount returns an attribute KeyValue conforming to -// the "cassandra.speculative_execution.count" semantic conventions. It -// represents the number of times a query was speculatively executed. Not set or -// `0` if the query was not executed speculatively. -func CassandraSpeculativeExecutionCount(val int) attribute.KeyValue { - return CassandraSpeculativeExecutionCountKey.Int(val) -} - -// Enum values for cassandra.consistency.level -var ( - // all - // Stability: development - CassandraConsistencyLevelAll = CassandraConsistencyLevelKey.String("all") - // each_quorum - // Stability: development - CassandraConsistencyLevelEachQuorum = CassandraConsistencyLevelKey.String("each_quorum") - // quorum - // Stability: development - CassandraConsistencyLevelQuorum = CassandraConsistencyLevelKey.String("quorum") - // local_quorum - // Stability: development - CassandraConsistencyLevelLocalQuorum = CassandraConsistencyLevelKey.String("local_quorum") - // one - // Stability: development - CassandraConsistencyLevelOne = CassandraConsistencyLevelKey.String("one") - // two - // Stability: development - CassandraConsistencyLevelTwo = CassandraConsistencyLevelKey.String("two") - // three - // Stability: development - CassandraConsistencyLevelThree = CassandraConsistencyLevelKey.String("three") - // local_one - // Stability: development - CassandraConsistencyLevelLocalOne = CassandraConsistencyLevelKey.String("local_one") - // any - // Stability: development - CassandraConsistencyLevelAny = CassandraConsistencyLevelKey.String("any") - // serial - // Stability: development - CassandraConsistencyLevelSerial = CassandraConsistencyLevelKey.String("serial") - // local_serial - // Stability: development - CassandraConsistencyLevelLocalSerial = CassandraConsistencyLevelKey.String("local_serial") -) - -// Namespace: cicd -const ( - // CICDPipelineNameKey is the attribute Key conforming to the - // "cicd.pipeline.name" semantic conventions. It represents the human readable - // name of the pipeline within a CI/CD system. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Build and Test", "Lint", "Deploy Go Project", - // "deploy_to_environment" - CICDPipelineNameKey = attribute.Key("cicd.pipeline.name") - - // CICDPipelineResultKey is the attribute Key conforming to the - // "cicd.pipeline.result" semantic conventions. It represents the result of a - // pipeline run. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "success", "failure", "timeout", "skipped" - CICDPipelineResultKey = attribute.Key("cicd.pipeline.result") - - // CICDPipelineRunIDKey is the attribute Key conforming to the - // "cicd.pipeline.run.id" semantic conventions. It represents the unique - // identifier of a pipeline run within a CI/CD system. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "120912" - CICDPipelineRunIDKey = attribute.Key("cicd.pipeline.run.id") - - // CICDPipelineRunStateKey is the attribute Key conforming to the - // "cicd.pipeline.run.state" semantic conventions. It represents the pipeline - // run goes through these states during its lifecycle. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "pending", "executing", "finalizing" - CICDPipelineRunStateKey = attribute.Key("cicd.pipeline.run.state") - - // CICDPipelineTaskNameKey is the attribute Key conforming to the - // "cicd.pipeline.task.name" semantic conventions. It represents the human - // readable name of a task within a pipeline. Task here most closely aligns with - // a [computing process] in a pipeline. Other terms for tasks include commands, - // steps, and procedures. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Run GoLang Linter", "Go Build", "go-test", "deploy_binary" - // - // [computing process]: https://wikipedia.org/wiki/Pipeline_(computing) - CICDPipelineTaskNameKey = attribute.Key("cicd.pipeline.task.name") - - // CICDPipelineTaskRunIDKey is the attribute Key conforming to the - // "cicd.pipeline.task.run.id" semantic conventions. It represents the unique - // identifier of a task run within a pipeline. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "12097" - CICDPipelineTaskRunIDKey = attribute.Key("cicd.pipeline.task.run.id") - - // CICDPipelineTaskRunURLFullKey is the attribute Key conforming to the - // "cicd.pipeline.task.run.url.full" semantic conventions. It represents the - // [URL] of the pipeline run providing the complete address in order to locate - // and identify the pipeline run. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763/job/26920038674?pr=1075" - // - // [URL]: https://wikipedia.org/wiki/URL - CICDPipelineTaskRunURLFullKey = attribute.Key("cicd.pipeline.task.run.url.full") - - // CICDPipelineTaskTypeKey is the attribute Key conforming to the - // "cicd.pipeline.task.type" semantic conventions. It represents the type of the - // task within a pipeline. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "build", "test", "deploy" - CICDPipelineTaskTypeKey = attribute.Key("cicd.pipeline.task.type") - - // CICDSystemComponentKey is the attribute Key conforming to the - // "cicd.system.component" semantic conventions. It represents the name of a - // component of the CICD system. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "controller", "scheduler", "agent" - CICDSystemComponentKey = attribute.Key("cicd.system.component") - - // CICDWorkerStateKey is the attribute Key conforming to the "cicd.worker.state" - // semantic conventions. It represents the state of a CICD worker / agent. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "idle", "busy", "down" - CICDWorkerStateKey = attribute.Key("cicd.worker.state") -) - -// CICDPipelineName returns an attribute KeyValue conforming to the -// "cicd.pipeline.name" semantic conventions. It represents the human readable -// name of the pipeline within a CI/CD system. -func CICDPipelineName(val string) attribute.KeyValue { - return CICDPipelineNameKey.String(val) -} - -// CICDPipelineRunID returns an attribute KeyValue conforming to the -// "cicd.pipeline.run.id" semantic conventions. It represents the unique -// identifier of a pipeline run within a CI/CD system. -func CICDPipelineRunID(val string) attribute.KeyValue { - return CICDPipelineRunIDKey.String(val) -} - -// CICDPipelineTaskName returns an attribute KeyValue conforming to the -// "cicd.pipeline.task.name" semantic conventions. It represents the human -// readable name of a task within a pipeline. Task here most closely aligns with -// a [computing process] in a pipeline. Other terms for tasks include commands, -// steps, and procedures. -// -// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing) -func CICDPipelineTaskName(val string) attribute.KeyValue { - return CICDPipelineTaskNameKey.String(val) -} - -// CICDPipelineTaskRunID returns an attribute KeyValue conforming to the -// "cicd.pipeline.task.run.id" semantic conventions. It represents the unique -// identifier of a task run within a pipeline. -func CICDPipelineTaskRunID(val string) attribute.KeyValue { - return CICDPipelineTaskRunIDKey.String(val) -} - -// CICDPipelineTaskRunURLFull returns an attribute KeyValue conforming to the -// "cicd.pipeline.task.run.url.full" semantic conventions. It represents the -// [URL] of the pipeline run providing the complete address in order to locate -// and identify the pipeline run. -// -// [URL]: https://wikipedia.org/wiki/URL -func CICDPipelineTaskRunURLFull(val string) attribute.KeyValue { - return CICDPipelineTaskRunURLFullKey.String(val) -} - -// CICDSystemComponent returns an attribute KeyValue conforming to the -// "cicd.system.component" semantic conventions. It represents the name of a -// component of the CICD system. -func CICDSystemComponent(val string) attribute.KeyValue { - return CICDSystemComponentKey.String(val) -} - -// Enum values for cicd.pipeline.result -var ( - // The pipeline run finished successfully. - // Stability: development - CICDPipelineResultSuccess = CICDPipelineResultKey.String("success") - // The pipeline run did not finish successfully, eg. due to a compile error or a - // failing test. Such failures are usually detected by non-zero exit codes of - // the tools executed in the pipeline run. - // Stability: development - CICDPipelineResultFailure = CICDPipelineResultKey.String("failure") - // The pipeline run failed due to an error in the CICD system, eg. due to the - // worker being killed. - // Stability: development - CICDPipelineResultError = CICDPipelineResultKey.String("error") - // A timeout caused the pipeline run to be interrupted. - // Stability: development - CICDPipelineResultTimeout = CICDPipelineResultKey.String("timeout") - // The pipeline run was cancelled, eg. by a user manually cancelling the - // pipeline run. - // Stability: development - CICDPipelineResultCancellation = CICDPipelineResultKey.String("cancellation") - // The pipeline run was skipped, eg. due to a precondition not being met. - // Stability: development - CICDPipelineResultSkip = CICDPipelineResultKey.String("skip") -) - -// Enum values for cicd.pipeline.run.state -var ( - // The run pending state spans from the event triggering the pipeline run until - // the execution of the run starts (eg. time spent in a queue, provisioning - // agents, creating run resources). - // - // Stability: development - CICDPipelineRunStatePending = CICDPipelineRunStateKey.String("pending") - // The executing state spans the execution of any run tasks (eg. build, test). - // Stability: development - CICDPipelineRunStateExecuting = CICDPipelineRunStateKey.String("executing") - // The finalizing state spans from when the run has finished executing (eg. - // cleanup of run resources). - // Stability: development - CICDPipelineRunStateFinalizing = CICDPipelineRunStateKey.String("finalizing") -) - -// Enum values for cicd.pipeline.task.type -var ( - // build - // Stability: development - CICDPipelineTaskTypeBuild = CICDPipelineTaskTypeKey.String("build") - // test - // Stability: development - CICDPipelineTaskTypeTest = CICDPipelineTaskTypeKey.String("test") - // deploy - // Stability: development - CICDPipelineTaskTypeDeploy = CICDPipelineTaskTypeKey.String("deploy") -) - -// Enum values for cicd.worker.state -var ( - // The worker is not performing work for the CICD system. It is available to the - // CICD system to perform work on (online / idle). - // Stability: development - CICDWorkerStateAvailable = CICDWorkerStateKey.String("available") - // The worker is performing work for the CICD system. - // Stability: development - CICDWorkerStateBusy = CICDWorkerStateKey.String("busy") - // The worker is not available to the CICD system (disconnected / down). - // Stability: development - CICDWorkerStateOffline = CICDWorkerStateKey.String("offline") -) - -// Namespace: client -const ( - // ClientAddressKey is the attribute Key conforming to the "client.address" - // semantic conventions. It represents the client address - domain name if - // available without reverse DNS lookup; otherwise, IP address or Unix domain - // socket name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "client.example.com", "10.1.2.80", "/tmp/my.sock" - // Note: When observed from the server side, and when communicating through an - // intermediary, `client.address` SHOULD represent the client address behind any - // intermediaries, for example proxies, if it's available. - ClientAddressKey = attribute.Key("client.address") - - // ClientPortKey is the attribute Key conforming to the "client.port" semantic - // conventions. It represents the client port number. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: 65123 - // Note: When observed from the server side, and when communicating through an - // intermediary, `client.port` SHOULD represent the client port behind any - // intermediaries, for example proxies, if it's available. - ClientPortKey = attribute.Key("client.port") -) - -// ClientAddress returns an attribute KeyValue conforming to the "client.address" -// semantic conventions. It represents the client address - domain name if -// available without reverse DNS lookup; otherwise, IP address or Unix domain -// socket name. -func ClientAddress(val string) attribute.KeyValue { - return ClientAddressKey.String(val) -} - -// ClientPort returns an attribute KeyValue conforming to the "client.port" -// semantic conventions. It represents the client port number. -func ClientPort(val int) attribute.KeyValue { - return ClientPortKey.Int(val) -} - -// Namespace: cloud -const ( - // CloudAccountIDKey is the attribute Key conforming to the "cloud.account.id" - // semantic conventions. It represents the cloud account ID the resource is - // assigned to. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "111111111111", "opentelemetry" - CloudAccountIDKey = attribute.Key("cloud.account.id") - - // CloudAvailabilityZoneKey is the attribute Key conforming to the - // "cloud.availability_zone" semantic conventions. It represents the cloud - // regions often have multiple, isolated locations known as zones to increase - // availability. Availability zone represents the zone where the resource is - // running. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "us-east-1c" - // Note: Availability zones are called "zones" on Alibaba Cloud and Google - // Cloud. - CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone") - - // CloudPlatformKey is the attribute Key conforming to the "cloud.platform" - // semantic conventions. It represents the cloud platform in use. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: The prefix of the service SHOULD match the one specified in - // `cloud.provider`. - CloudPlatformKey = attribute.Key("cloud.platform") - - // CloudProviderKey is the attribute Key conforming to the "cloud.provider" - // semantic conventions. It represents the name of the cloud provider. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - CloudProviderKey = attribute.Key("cloud.provider") - - // CloudRegionKey is the attribute Key conforming to the "cloud.region" semantic - // conventions. It represents the geographical region the resource is running. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "us-central1", "us-east-1" - // Note: Refer to your provider's docs to see the available regions, for example - // [Alibaba Cloud regions], [AWS regions], [Azure regions], - // [Google Cloud regions], or [Tencent Cloud regions]. - // - // [Alibaba Cloud regions]: https://www.alibabacloud.com/help/doc-detail/40654.htm - // [AWS regions]: https://aws.amazon.com/about-aws/global-infrastructure/regions_az/ - // [Azure regions]: https://azure.microsoft.com/global-infrastructure/geographies/ - // [Google Cloud regions]: https://cloud.google.com/about/locations - // [Tencent Cloud regions]: https://www.tencentcloud.com/document/product/213/6091 - CloudRegionKey = attribute.Key("cloud.region") - - // CloudResourceIDKey is the attribute Key conforming to the "cloud.resource_id" - // semantic conventions. It represents the cloud provider-specific native - // identifier of the monitored cloud resource (e.g. an [ARN] on AWS, a - // [fully qualified resource ID] on Azure, a [full resource name] on GCP). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function", - // "//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID", - // "/subscriptions//resourceGroups/ - // /providers/Microsoft.Web/sites//functions/" - // Note: On some cloud providers, it may not be possible to determine the full - // ID at startup, - // so it may be necessary to set `cloud.resource_id` as a span attribute - // instead. - // - // The exact value to use for `cloud.resource_id` depends on the cloud provider. - // The following well-known definitions MUST be used if you set this attribute - // and they apply: - // - // - **AWS Lambda:** The function [ARN]. - // Take care not to use the "invoked ARN" directly but replace any - // [alias suffix] - // with the resolved function version, as the same runtime instance may be - // invocable with - // multiple different aliases. - // - **GCP:** The [URI of the resource] - // - **Azure:** The [Fully Qualified Resource ID] of the invoked function, - // *not* the function app, having the form - // - // `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/` - // . - // This means that a span attribute MUST be used, as an Azure function app - // can host multiple functions that would usually share - // a TracerProvider. - // - // - // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - // [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id - // [full resource name]: https://cloud.google.com/apis/design/resource_names#full_resource_name - // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - // [alias suffix]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html - // [URI of the resource]: https://cloud.google.com/iam/docs/full-resource-names - // [Fully Qualified Resource ID]: https://docs.microsoft.com/rest/api/resources/resources/get-by-id - CloudResourceIDKey = attribute.Key("cloud.resource_id") -) - -// CloudAccountID returns an attribute KeyValue conforming to the -// "cloud.account.id" semantic conventions. It represents the cloud account ID -// the resource is assigned to. -func CloudAccountID(val string) attribute.KeyValue { - return CloudAccountIDKey.String(val) -} - -// CloudAvailabilityZone returns an attribute KeyValue conforming to the -// "cloud.availability_zone" semantic conventions. It represents the cloud -// regions often have multiple, isolated locations known as zones to increase -// availability. Availability zone represents the zone where the resource is -// running. -func CloudAvailabilityZone(val string) attribute.KeyValue { - return CloudAvailabilityZoneKey.String(val) -} - -// CloudRegion returns an attribute KeyValue conforming to the "cloud.region" -// semantic conventions. It represents the geographical region the resource is -// running. -func CloudRegion(val string) attribute.KeyValue { - return CloudRegionKey.String(val) -} - -// CloudResourceID returns an attribute KeyValue conforming to the -// "cloud.resource_id" semantic conventions. It represents the cloud -// provider-specific native identifier of the monitored cloud resource (e.g. an -// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name] -// -// on GCP). -// -// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html -// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id -// [full resource name]: https://cloud.google.com/apis/design/resource_names#full_resource_name -func CloudResourceID(val string) attribute.KeyValue { - return CloudResourceIDKey.String(val) -} - -// Enum values for cloud.platform -var ( - // Alibaba Cloud Elastic Compute Service - // Stability: development - CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs") - // Alibaba Cloud Function Compute - // Stability: development - CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc") - // Red Hat OpenShift on Alibaba Cloud - // Stability: development - CloudPlatformAlibabaCloudOpenshift = CloudPlatformKey.String("alibaba_cloud_openshift") - // AWS Elastic Compute Cloud - // Stability: development - CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2") - // AWS Elastic Container Service - // Stability: development - CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs") - // AWS Elastic Kubernetes Service - // Stability: development - CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks") - // AWS Lambda - // Stability: development - CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda") - // AWS Elastic Beanstalk - // Stability: development - CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk") - // AWS App Runner - // Stability: development - CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner") - // Red Hat OpenShift on AWS (ROSA) - // Stability: development - CloudPlatformAWSOpenshift = CloudPlatformKey.String("aws_openshift") - // Azure Virtual Machines - // Stability: development - CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm") - // Azure Container Apps - // Stability: development - CloudPlatformAzureContainerApps = CloudPlatformKey.String("azure_container_apps") - // Azure Container Instances - // Stability: development - CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure_container_instances") - // Azure Kubernetes Service - // Stability: development - CloudPlatformAzureAKS = CloudPlatformKey.String("azure_aks") - // Azure Functions - // Stability: development - CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions") - // Azure App Service - // Stability: development - CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service") - // Azure Red Hat OpenShift - // Stability: development - CloudPlatformAzureOpenshift = CloudPlatformKey.String("azure_openshift") - // Google Bare Metal Solution (BMS) - // Stability: development - CloudPlatformGCPBareMetalSolution = CloudPlatformKey.String("gcp_bare_metal_solution") - // Google Cloud Compute Engine (GCE) - // Stability: development - CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine") - // Google Cloud Run - // Stability: development - CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run") - // Google Cloud Kubernetes Engine (GKE) - // Stability: development - CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine") - // Google Cloud Functions (GCF) - // Stability: development - CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions") - // Google Cloud App Engine (GAE) - // Stability: development - CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine") - // Red Hat OpenShift on Google Cloud - // Stability: development - CloudPlatformGCPOpenshift = CloudPlatformKey.String("gcp_openshift") - // Red Hat OpenShift on IBM Cloud - // Stability: development - CloudPlatformIbmCloudOpenshift = CloudPlatformKey.String("ibm_cloud_openshift") - // Compute on Oracle Cloud Infrastructure (OCI) - // Stability: development - CloudPlatformOracleCloudCompute = CloudPlatformKey.String("oracle_cloud_compute") - // Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI) - // Stability: development - CloudPlatformOracleCloudOke = CloudPlatformKey.String("oracle_cloud_oke") - // Tencent Cloud Cloud Virtual Machine (CVM) - // Stability: development - CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm") - // Tencent Cloud Elastic Kubernetes Service (EKS) - // Stability: development - CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks") - // Tencent Cloud Serverless Cloud Function (SCF) - // Stability: development - CloudPlatformTencentCloudScf = CloudPlatformKey.String("tencent_cloud_scf") -) - -// Enum values for cloud.provider -var ( - // Alibaba Cloud - // Stability: development - CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud") - // Amazon Web Services - // Stability: development - CloudProviderAWS = CloudProviderKey.String("aws") - // Microsoft Azure - // Stability: development - CloudProviderAzure = CloudProviderKey.String("azure") - // Google Cloud Platform - // Stability: development - CloudProviderGCP = CloudProviderKey.String("gcp") - // Heroku Platform as a Service - // Stability: development - CloudProviderHeroku = CloudProviderKey.String("heroku") - // IBM Cloud - // Stability: development - CloudProviderIbmCloud = CloudProviderKey.String("ibm_cloud") - // Oracle Cloud Infrastructure (OCI) - // Stability: development - CloudProviderOracleCloud = CloudProviderKey.String("oracle_cloud") - // Tencent Cloud - // Stability: development - CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud") -) - -// Namespace: cloudevents -const ( - // CloudeventsEventIDKey is the attribute Key conforming to the - // "cloudevents.event_id" semantic conventions. It represents the [event_id] - // uniquely identifies the event. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "123e4567-e89b-12d3-a456-426614174000", "0001" - // - // [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id - CloudeventsEventIDKey = attribute.Key("cloudevents.event_id") - - // CloudeventsEventSourceKey is the attribute Key conforming to the - // "cloudevents.event_source" semantic conventions. It represents the [source] - // identifies the context in which an event happened. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "https://github.com/cloudevents", "/cloudevents/spec/pull/123", - // "my-service" - // - // [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1 - CloudeventsEventSourceKey = attribute.Key("cloudevents.event_source") - - // CloudeventsEventSpecVersionKey is the attribute Key conforming to the - // "cloudevents.event_spec_version" semantic conventions. It represents the - // [version of the CloudEvents specification] which the event uses. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1.0 - // - // [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion - CloudeventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version") - - // CloudeventsEventSubjectKey is the attribute Key conforming to the - // "cloudevents.event_subject" semantic conventions. It represents the [subject] - // of the event in the context of the event producer (identified by source). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: mynewfile.jpg - // - // [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject - CloudeventsEventSubjectKey = attribute.Key("cloudevents.event_subject") - - // CloudeventsEventTypeKey is the attribute Key conforming to the - // "cloudevents.event_type" semantic conventions. It represents the [event_type] - // contains a value describing the type of event related to the originating - // occurrence. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "com.github.pull_request.opened", "com.example.object.deleted.v2" - // - // [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type - CloudeventsEventTypeKey = attribute.Key("cloudevents.event_type") -) - -// CloudeventsEventID returns an attribute KeyValue conforming to the -// "cloudevents.event_id" semantic conventions. It represents the [event_id] -// uniquely identifies the event. -// -// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id -func CloudeventsEventID(val string) attribute.KeyValue { - return CloudeventsEventIDKey.String(val) -} - -// CloudeventsEventSource returns an attribute KeyValue conforming to the -// "cloudevents.event_source" semantic conventions. It represents the [source] -// identifies the context in which an event happened. -// -// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1 -func CloudeventsEventSource(val string) attribute.KeyValue { - return CloudeventsEventSourceKey.String(val) -} - -// CloudeventsEventSpecVersion returns an attribute KeyValue conforming to the -// "cloudevents.event_spec_version" semantic conventions. It represents the -// [version of the CloudEvents specification] which the event uses. -// -// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion -func CloudeventsEventSpecVersion(val string) attribute.KeyValue { - return CloudeventsEventSpecVersionKey.String(val) -} - -// CloudeventsEventSubject returns an attribute KeyValue conforming to the -// "cloudevents.event_subject" semantic conventions. It represents the [subject] -// of the event in the context of the event producer (identified by source). -// -// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject -func CloudeventsEventSubject(val string) attribute.KeyValue { - return CloudeventsEventSubjectKey.String(val) -} - -// CloudeventsEventType returns an attribute KeyValue conforming to the -// "cloudevents.event_type" semantic conventions. It represents the [event_type] -// contains a value describing the type of event related to the originating -// occurrence. -// -// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type -func CloudeventsEventType(val string) attribute.KeyValue { - return CloudeventsEventTypeKey.String(val) -} - -// Namespace: cloudfoundry -const ( - // CloudfoundryAppIDKey is the attribute Key conforming to the - // "cloudfoundry.app.id" semantic conventions. It represents the guid of the - // application. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.application_id`. This is the same value as - // reported by `cf app --guid`. - CloudfoundryAppIDKey = attribute.Key("cloudfoundry.app.id") - - // CloudfoundryAppInstanceIDKey is the attribute Key conforming to the - // "cloudfoundry.app.instance.id" semantic conventions. It represents the index - // of the application instance. 0 when just one instance is active. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0", "1" - // Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope] - // . - // It is used for logs and metrics emitted by CloudFoundry. It is - // supposed to contain the application instance index for applications - // deployed on the runtime. - // - // Application instrumentation should use the value from environment - // variable `CF_INSTANCE_INDEX`. - // - // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope - CloudfoundryAppInstanceIDKey = attribute.Key("cloudfoundry.app.instance.id") - - // CloudfoundryAppNameKey is the attribute Key conforming to the - // "cloudfoundry.app.name" semantic conventions. It represents the name of the - // application. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-app-name" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.application_name`. This is the same value - // as reported by `cf apps`. - CloudfoundryAppNameKey = attribute.Key("cloudfoundry.app.name") - - // CloudfoundryOrgIDKey is the attribute Key conforming to the - // "cloudfoundry.org.id" semantic conventions. It represents the guid of the - // CloudFoundry org the application is running in. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.org_id`. This is the same value as - // reported by `cf org --guid`. - CloudfoundryOrgIDKey = attribute.Key("cloudfoundry.org.id") - - // CloudfoundryOrgNameKey is the attribute Key conforming to the - // "cloudfoundry.org.name" semantic conventions. It represents the name of the - // CloudFoundry organization the app is running in. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-org-name" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.org_name`. This is the same value as - // reported by `cf orgs`. - CloudfoundryOrgNameKey = attribute.Key("cloudfoundry.org.name") - - // CloudfoundryProcessIDKey is the attribute Key conforming to the - // "cloudfoundry.process.id" semantic conventions. It represents the UID - // identifying the process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to - // `VCAP_APPLICATION.app_id` for applications deployed to the runtime. - // For system components, this could be the actual PID. - CloudfoundryProcessIDKey = attribute.Key("cloudfoundry.process.id") - - // CloudfoundryProcessTypeKey is the attribute Key conforming to the - // "cloudfoundry.process.type" semantic conventions. It represents the type of - // process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "web" - // Note: CloudFoundry applications can consist of multiple jobs. Usually the - // main process will be of type `web`. There can be additional background - // tasks or side-cars with different process types. - CloudfoundryProcessTypeKey = attribute.Key("cloudfoundry.process.type") - - // CloudfoundrySpaceIDKey is the attribute Key conforming to the - // "cloudfoundry.space.id" semantic conventions. It represents the guid of the - // CloudFoundry space the application is running in. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.space_id`. This is the same value as - // reported by `cf space --guid`. - CloudfoundrySpaceIDKey = attribute.Key("cloudfoundry.space.id") - - // CloudfoundrySpaceNameKey is the attribute Key conforming to the - // "cloudfoundry.space.name" semantic conventions. It represents the name of the - // CloudFoundry space the application is running in. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-space-name" - // Note: Application instrumentation should use the value from environment - // variable `VCAP_APPLICATION.space_name`. This is the same value as - // reported by `cf spaces`. - CloudfoundrySpaceNameKey = attribute.Key("cloudfoundry.space.name") - - // CloudfoundrySystemIDKey is the attribute Key conforming to the - // "cloudfoundry.system.id" semantic conventions. It represents a guid or - // another name describing the event source. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "cf/gorouter" - // Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope]. - // It is used for logs and metrics emitted by CloudFoundry. It is - // supposed to contain the component name, e.g. "gorouter", for - // CloudFoundry components. - // - // When system components are instrumented, values from the - // [Bosh spec] - // should be used. The `system.id` should be set to - // `spec.deployment/spec.name`. - // - // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope - // [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec - CloudfoundrySystemIDKey = attribute.Key("cloudfoundry.system.id") - - // CloudfoundrySystemInstanceIDKey is the attribute Key conforming to the - // "cloudfoundry.system.instance.id" semantic conventions. It represents a guid - // describing the concrete instance of the event source. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" - // Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope] - // . - // It is used for logs and metrics emitted by CloudFoundry. It is - // supposed to contain the vm id for CloudFoundry components. - // - // When system components are instrumented, values from the - // [Bosh spec] - // should be used. The `system.instance.id` should be set to `spec.id`. - // - // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope - // [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec - CloudfoundrySystemInstanceIDKey = attribute.Key("cloudfoundry.system.instance.id") -) - -// CloudfoundryAppID returns an attribute KeyValue conforming to the -// "cloudfoundry.app.id" semantic conventions. It represents the guid of the -// application. -func CloudfoundryAppID(val string) attribute.KeyValue { - return CloudfoundryAppIDKey.String(val) -} - -// CloudfoundryAppInstanceID returns an attribute KeyValue conforming to the -// "cloudfoundry.app.instance.id" semantic conventions. It represents the index -// of the application instance. 0 when just one instance is active. -func CloudfoundryAppInstanceID(val string) attribute.KeyValue { - return CloudfoundryAppInstanceIDKey.String(val) -} - -// CloudfoundryAppName returns an attribute KeyValue conforming to the -// "cloudfoundry.app.name" semantic conventions. It represents the name of the -// application. -func CloudfoundryAppName(val string) attribute.KeyValue { - return CloudfoundryAppNameKey.String(val) -} - -// CloudfoundryOrgID returns an attribute KeyValue conforming to the -// "cloudfoundry.org.id" semantic conventions. It represents the guid of the -// CloudFoundry org the application is running in. -func CloudfoundryOrgID(val string) attribute.KeyValue { - return CloudfoundryOrgIDKey.String(val) -} - -// CloudfoundryOrgName returns an attribute KeyValue conforming to the -// "cloudfoundry.org.name" semantic conventions. It represents the name of the -// CloudFoundry organization the app is running in. -func CloudfoundryOrgName(val string) attribute.KeyValue { - return CloudfoundryOrgNameKey.String(val) -} - -// CloudfoundryProcessID returns an attribute KeyValue conforming to the -// "cloudfoundry.process.id" semantic conventions. It represents the UID -// identifying the process. -func CloudfoundryProcessID(val string) attribute.KeyValue { - return CloudfoundryProcessIDKey.String(val) -} - -// CloudfoundryProcessType returns an attribute KeyValue conforming to the -// "cloudfoundry.process.type" semantic conventions. It represents the type of -// process. -func CloudfoundryProcessType(val string) attribute.KeyValue { - return CloudfoundryProcessTypeKey.String(val) -} - -// CloudfoundrySpaceID returns an attribute KeyValue conforming to the -// "cloudfoundry.space.id" semantic conventions. It represents the guid of the -// CloudFoundry space the application is running in. -func CloudfoundrySpaceID(val string) attribute.KeyValue { - return CloudfoundrySpaceIDKey.String(val) -} - -// CloudfoundrySpaceName returns an attribute KeyValue conforming to the -// "cloudfoundry.space.name" semantic conventions. It represents the name of the -// CloudFoundry space the application is running in. -func CloudfoundrySpaceName(val string) attribute.KeyValue { - return CloudfoundrySpaceNameKey.String(val) -} - -// CloudfoundrySystemID returns an attribute KeyValue conforming to the -// "cloudfoundry.system.id" semantic conventions. It represents a guid or another -// name describing the event source. -func CloudfoundrySystemID(val string) attribute.KeyValue { - return CloudfoundrySystemIDKey.String(val) -} - -// CloudfoundrySystemInstanceID returns an attribute KeyValue conforming to the -// "cloudfoundry.system.instance.id" semantic conventions. It represents a guid -// describing the concrete instance of the event source. -func CloudfoundrySystemInstanceID(val string) attribute.KeyValue { - return CloudfoundrySystemInstanceIDKey.String(val) -} - -// Namespace: code -const ( - // CodeColumnNumberKey is the attribute Key conforming to the - // "code.column.number" semantic conventions. It represents the column number in - // `code.file.path` best representing the operation. It SHOULD point within the - // code unit named in `code.function.name`. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - CodeColumnNumberKey = attribute.Key("code.column.number") - - // CodeFilePathKey is the attribute Key conforming to the "code.file.path" - // semantic conventions. It represents the source code file name that identifies - // the code unit as uniquely as possible (preferably an absolute file path). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: /usr/local/MyApplication/content_root/app/index.php - CodeFilePathKey = attribute.Key("code.file.path") - - // CodeFilepathKey is the attribute Key conforming to the "code.filepath" - // semantic conventions. It represents the deprecated, use `code.file.path` - // instead. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: /usr/local/MyApplication/content_root/app/index.php - CodeFilepathKey = attribute.Key("code.filepath") - - // CodeFunctionNameKey is the attribute Key conforming to the - // "code.function.name" semantic conventions. It represents the method or - // function name, or equivalent (usually rightmost part of the code unit's - // name). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: serveRequest - CodeFunctionNameKey = attribute.Key("code.function.name") - - // CodeLineNumberKey is the attribute Key conforming to the "code.line.number" - // semantic conventions. It represents the line number in `code.file.path` best - // representing the operation. It SHOULD point within the code unit named in - // `code.function.name`. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - CodeLineNumberKey = attribute.Key("code.line.number") - - // CodeNamespaceKey is the attribute Key conforming to the "code.namespace" - // semantic conventions. It represents the "namespace" within which - // `code.function.name` is defined. Usually the qualified class or module name, - // such that `code.namespace` + some separator + `code.function.name` form a - // unique identifier for the code unit. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: com.example.MyHttpService - CodeNamespaceKey = attribute.Key("code.namespace") - - // CodeStacktraceKey is the attribute Key conforming to the "code.stacktrace" - // semantic conventions. It represents a stacktrace as a string in the natural - // representation for the language runtime. The representation is to be - // determined and documented by each language SIG. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at - // com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at - // com.example.GenerateTrace.main(GenerateTrace.java:5) - CodeStacktraceKey = attribute.Key("code.stacktrace") -) - -// CodeColumnNumber returns an attribute KeyValue conforming to the -// "code.column.number" semantic conventions. It represents the column number in -// `code.file.path` best representing the operation. It SHOULD point within the -// code unit named in `code.function.name`. -func CodeColumnNumber(val int) attribute.KeyValue { - return CodeColumnNumberKey.Int(val) -} - -// CodeFilePath returns an attribute KeyValue conforming to the "code.file.path" -// semantic conventions. It represents the source code file name that identifies -// the code unit as uniquely as possible (preferably an absolute file path). -func CodeFilePath(val string) attribute.KeyValue { - return CodeFilePathKey.String(val) -} - -// CodeFilepath returns an attribute KeyValue conforming to the "code.filepath" -// semantic conventions. It represents the deprecated, use `code.file.path` -// instead. -func CodeFilepath(val string) attribute.KeyValue { - return CodeFilepathKey.String(val) -} - -// CodeFunctionName returns an attribute KeyValue conforming to the -// "code.function.name" semantic conventions. It represents the method or -// function name, or equivalent (usually rightmost part of the code unit's name). -func CodeFunctionName(val string) attribute.KeyValue { - return CodeFunctionNameKey.String(val) -} - -// CodeLineNumber returns an attribute KeyValue conforming to the -// "code.line.number" semantic conventions. It represents the line number in -// `code.file.path` best representing the operation. It SHOULD point within the -// code unit named in `code.function.name`. -func CodeLineNumber(val int) attribute.KeyValue { - return CodeLineNumberKey.Int(val) -} - -// CodeNamespace returns an attribute KeyValue conforming to the "code.namespace" -// semantic conventions. It represents the "namespace" within which -// `code.function.name` is defined. Usually the qualified class or module name, -// such that `code.namespace` + some separator + `code.function.name` form a -// unique identifier for the code unit. -func CodeNamespace(val string) attribute.KeyValue { - return CodeNamespaceKey.String(val) -} - -// CodeStacktrace returns an attribute KeyValue conforming to the -// "code.stacktrace" semantic conventions. It represents a stacktrace as a string -// in the natural representation for the language runtime. The representation is -// to be determined and documented by each language SIG. -func CodeStacktrace(val string) attribute.KeyValue { - return CodeStacktraceKey.String(val) -} - -// Namespace: container -const ( - // ContainerCommandKey is the attribute Key conforming to the - // "container.command" semantic conventions. It represents the command used to - // run the container (i.e. the command name). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "otelcontribcol" - // Note: If using embedded credentials or sensitive data, it is recommended to - // remove them to prevent potential leakage. - ContainerCommandKey = attribute.Key("container.command") - - // ContainerCommandArgsKey is the attribute Key conforming to the - // "container.command_args" semantic conventions. It represents the all the - // command arguments (including the command/executable itself) run by the - // container. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "otelcontribcol", "--config", "config.yaml" - ContainerCommandArgsKey = attribute.Key("container.command_args") - - // ContainerCommandLineKey is the attribute Key conforming to the - // "container.command_line" semantic conventions. It represents the full command - // run by the container as a single string representing the full command. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "otelcontribcol --config config.yaml" - ContainerCommandLineKey = attribute.Key("container.command_line") - - // ContainerCsiPluginNameKey is the attribute Key conforming to the - // "container.csi.plugin.name" semantic conventions. It represents the name of - // the CSI ([Container Storage Interface]) plugin used by the volume. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "pd.csi.storage.gke.io" - // Note: This can sometimes be referred to as a "driver" in CSI implementations. - // This should represent the `name` field of the GetPluginInfo RPC. - // - // [Container Storage Interface]: https://github.com/container-storage-interface/spec - ContainerCsiPluginNameKey = attribute.Key("container.csi.plugin.name") - - // ContainerCsiVolumeIDKey is the attribute Key conforming to the - // "container.csi.volume.id" semantic conventions. It represents the unique - // volume ID returned by the CSI ([Container Storage Interface]) plugin. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk" - // Note: This can sometimes be referred to as a "volume handle" in CSI - // implementations. This should represent the `Volume.volume_id` field in CSI - // spec. - // - // [Container Storage Interface]: https://github.com/container-storage-interface/spec - ContainerCsiVolumeIDKey = attribute.Key("container.csi.volume.id") - - // ContainerIDKey is the attribute Key conforming to the "container.id" semantic - // conventions. It represents the container ID. Usually a UUID, as for example - // used to [identify Docker containers]. The UUID might be abbreviated. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "a3bf90e006b2" - // - // [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification - ContainerIDKey = attribute.Key("container.id") - - // ContainerImageIDKey is the attribute Key conforming to the - // "container.image.id" semantic conventions. It represents the runtime specific - // image identifier. Usually a hash algorithm followed by a UUID. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f" - // Note: Docker defines a sha256 of the image id; `container.image.id` - // corresponds to the `Image` field from the Docker container inspect [API] - // endpoint. - // K8s defines a link to the container registry repository with digest - // `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"` - // . - // The ID is assigned by the container runtime and can vary in different - // environments. Consider using `oci.manifest.digest` if it is important to - // identify the same image in different environments/runtimes. - // - // [API]: https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect - ContainerImageIDKey = attribute.Key("container.image.id") - - // ContainerImageNameKey is the attribute Key conforming to the - // "container.image.name" semantic conventions. It represents the name of the - // image the container was built on. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "gcr.io/opentelemetry/operator" - ContainerImageNameKey = attribute.Key("container.image.name") - - // ContainerImageRepoDigestsKey is the attribute Key conforming to the - // "container.image.repo_digests" semantic conventions. It represents the repo - // digests of the container image as provided by the container runtime. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb", - // "internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578" - // Note: [Docker] and [CRI] report those under the `RepoDigests` field. - // - // [Docker]: https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect - // [CRI]: https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238 - ContainerImageRepoDigestsKey = attribute.Key("container.image.repo_digests") - - // ContainerImageTagsKey is the attribute Key conforming to the - // "container.image.tags" semantic conventions. It represents the container - // image tags. An example can be found in [Docker Image Inspect]. Should be only - // the `` section of the full name for example from - // `registry.example.com/my-org/my-image:`. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "v1.27.1", "3.5.7-0" - // - // [Docker Image Inspect]: https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect - ContainerImageTagsKey = attribute.Key("container.image.tags") - - // ContainerNameKey is the attribute Key conforming to the "container.name" - // semantic conventions. It represents the container name used by container - // runtime. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry-autoconf" - ContainerNameKey = attribute.Key("container.name") - - // ContainerRuntimeKey is the attribute Key conforming to the - // "container.runtime" semantic conventions. It represents the container runtime - // managing this container. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "docker", "containerd", "rkt" - ContainerRuntimeKey = attribute.Key("container.runtime") -) - -// ContainerCommand returns an attribute KeyValue conforming to the -// "container.command" semantic conventions. It represents the command used to -// run the container (i.e. the command name). -func ContainerCommand(val string) attribute.KeyValue { - return ContainerCommandKey.String(val) -} - -// ContainerCommandArgs returns an attribute KeyValue conforming to the -// "container.command_args" semantic conventions. It represents the all the -// command arguments (including the command/executable itself) run by the -// container. -func ContainerCommandArgs(val ...string) attribute.KeyValue { - return ContainerCommandArgsKey.StringSlice(val) -} - -// ContainerCommandLine returns an attribute KeyValue conforming to the -// "container.command_line" semantic conventions. It represents the full command -// run by the container as a single string representing the full command. -func ContainerCommandLine(val string) attribute.KeyValue { - return ContainerCommandLineKey.String(val) -} - -// ContainerCsiPluginName returns an attribute KeyValue conforming to the -// "container.csi.plugin.name" semantic conventions. It represents the name of -// the CSI ([Container Storage Interface]) plugin used by the volume. -// -// [Container Storage Interface]: https://github.com/container-storage-interface/spec -func ContainerCsiPluginName(val string) attribute.KeyValue { - return ContainerCsiPluginNameKey.String(val) -} - -// ContainerCsiVolumeID returns an attribute KeyValue conforming to the -// "container.csi.volume.id" semantic conventions. It represents the unique -// volume ID returned by the CSI ([Container Storage Interface]) plugin. -// -// [Container Storage Interface]: https://github.com/container-storage-interface/spec -func ContainerCsiVolumeID(val string) attribute.KeyValue { - return ContainerCsiVolumeIDKey.String(val) -} - -// ContainerID returns an attribute KeyValue conforming to the "container.id" -// semantic conventions. It represents the container ID. Usually a UUID, as for -// example used to [identify Docker containers]. The UUID might be abbreviated. -// -// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification -func ContainerID(val string) attribute.KeyValue { - return ContainerIDKey.String(val) -} - -// ContainerImageID returns an attribute KeyValue conforming to the -// "container.image.id" semantic conventions. It represents the runtime specific -// image identifier. Usually a hash algorithm followed by a UUID. -func ContainerImageID(val string) attribute.KeyValue { - return ContainerImageIDKey.String(val) -} - -// ContainerImageName returns an attribute KeyValue conforming to the -// "container.image.name" semantic conventions. It represents the name of the -// image the container was built on. -func ContainerImageName(val string) attribute.KeyValue { - return ContainerImageNameKey.String(val) -} - -// ContainerImageRepoDigests returns an attribute KeyValue conforming to the -// "container.image.repo_digests" semantic conventions. It represents the repo -// digests of the container image as provided by the container runtime. -func ContainerImageRepoDigests(val ...string) attribute.KeyValue { - return ContainerImageRepoDigestsKey.StringSlice(val) -} - -// ContainerImageTags returns an attribute KeyValue conforming to the -// "container.image.tags" semantic conventions. It represents the container image -// tags. An example can be found in [Docker Image Inspect]. Should be only the -// `` section of the full name for example from -// `registry.example.com/my-org/my-image:`. -// -// [Docker Image Inspect]: https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect -func ContainerImageTags(val ...string) attribute.KeyValue { - return ContainerImageTagsKey.StringSlice(val) -} - -// ContainerName returns an attribute KeyValue conforming to the "container.name" -// semantic conventions. It represents the container name used by container -// runtime. -func ContainerName(val string) attribute.KeyValue { - return ContainerNameKey.String(val) -} - -// ContainerRuntime returns an attribute KeyValue conforming to the -// "container.runtime" semantic conventions. It represents the container runtime -// managing this container. -func ContainerRuntime(val string) attribute.KeyValue { - return ContainerRuntimeKey.String(val) -} - -// Namespace: cpu -const ( - // CPUModeKey is the attribute Key conforming to the "cpu.mode" semantic - // conventions. It represents the mode of the CPU. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "user", "system" - CPUModeKey = attribute.Key("cpu.mode") -) - -// Enum values for cpu.mode -var ( - // user - // Stability: development - CPUModeUser = CPUModeKey.String("user") - // system - // Stability: development - CPUModeSystem = CPUModeKey.String("system") - // nice - // Stability: development - CPUModeNice = CPUModeKey.String("nice") - // idle - // Stability: development - CPUModeIdle = CPUModeKey.String("idle") - // iowait - // Stability: development - CPUModeIowait = CPUModeKey.String("iowait") - // interrupt - // Stability: development - CPUModeInterrupt = CPUModeKey.String("interrupt") - // steal - // Stability: development - CPUModeSteal = CPUModeKey.String("steal") - // kernel - // Stability: development - CPUModeKernel = CPUModeKey.String("kernel") -) - -// Namespace: db -const ( - // DBClientConnectionPoolNameKey is the attribute Key conforming to the - // "db.client.connection.pool.name" semantic conventions. It represents the name - // of the connection pool; unique within the instrumented application. In case - // the connection pool implementation doesn't provide a name, instrumentation - // SHOULD use a combination of parameters that would make the name unique, for - // example, combining attributes `server.address`, `server.port`, and - // `db.namespace`, formatted as `server.address:server.port/db.namespace`. - // Instrumentations that generate connection pool name following different - // patterns SHOULD document it. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "myDataSource" - DBClientConnectionPoolNameKey = attribute.Key("db.client.connection.pool.name") - - // DBClientConnectionStateKey is the attribute Key conforming to the - // "db.client.connection.state" semantic conventions. It represents the state of - // a connection in the pool. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "idle" - DBClientConnectionStateKey = attribute.Key("db.client.connection.state") - - // DBCollectionNameKey is the attribute Key conforming to the - // "db.collection.name" semantic conventions. It represents the name of a - // collection (table, container) within the database. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: "public.users", "customers" - // Note: It is RECOMMENDED to capture the value as provided by the application - // without attempting to do any case normalization. - // - // The collection name SHOULD NOT be extracted from `db.query.text`, - // unless the query format is known to only ever have a single collection name - // present. - // - // For batch operations, if the individual operations are known to have the same - // collection name - // then that collection name SHOULD be used. - DBCollectionNameKey = attribute.Key("db.collection.name") - - // DBNamespaceKey is the attribute Key conforming to the "db.namespace" semantic - // conventions. It represents the name of the database, fully qualified within - // the server address and port. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: "customers", "test.users" - // Note: If a database system has multiple namespace components, they SHOULD be - // concatenated (potentially using database system specific conventions) from - // most general to most specific namespace component, and more specific - // namespaces SHOULD NOT be captured without the more general namespaces, to - // ensure that "startswith" queries for the more general namespaces will be - // valid. - // Semantic conventions for individual database systems SHOULD document what - // `db.namespace` means in the context of that system. - // It is RECOMMENDED to capture the value as provided by the application without - // attempting to do any case normalization. - DBNamespaceKey = attribute.Key("db.namespace") - - // DBOperationBatchSizeKey is the attribute Key conforming to the - // "db.operation.batch.size" semantic conventions. It represents the number of - // queries included in a batch operation. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: 2, 3, 4 - // Note: Operations are only considered batches when they contain two or more - // operations, and so `db.operation.batch.size` SHOULD never be `1`. - DBOperationBatchSizeKey = attribute.Key("db.operation.batch.size") - - // DBOperationNameKey is the attribute Key conforming to the "db.operation.name" - // semantic conventions. It represents the name of the operation or command - // being executed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: "findAndModify", "HMSET", "SELECT" - // Note: It is RECOMMENDED to capture the value as provided by the application - // without attempting to do any case normalization. - // - // The operation name SHOULD NOT be extracted from `db.query.text`, - // unless the query format is known to only ever have a single operation name - // present. - // - // For batch operations, if the individual operations are known to have the same - // operation name - // then that operation name SHOULD be used prepended by `BATCH `, - // otherwise `db.operation.name` SHOULD be `BATCH` or some other database - // system specific term if more applicable. - DBOperationNameKey = attribute.Key("db.operation.name") - - // DBQuerySummaryKey is the attribute Key conforming to the "db.query.summary" - // semantic conventions. It represents the low cardinality representation of a - // database query text. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: "SELECT wuser_table", "INSERT shipping_details SELECT orders", "get - // user by id" - // Note: `db.query.summary` provides static summary of the query text. It - // describes a class of database queries and is useful as a grouping key, - // especially when analyzing telemetry for database calls involving complex - // queries. - // Summary may be available to the instrumentation through instrumentation hooks - // or other means. If it is not available, instrumentations that support query - // parsing SHOULD generate a summary following [Generating query summary] - // section. - // - // [Generating query summary]: ../../docs/database/database-spans.md#generating-a-summary-of-the-query-text - DBQuerySummaryKey = attribute.Key("db.query.summary") - - // DBQueryTextKey is the attribute Key conforming to the "db.query.text" - // semantic conventions. It represents the database query being executed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: "SELECT * FROM wuser_table where username = ?", "SET mykey ?" - // Note: For sanitization see [Sanitization of `db.query.text`]. - // For batch operations, if the individual operations are known to have the same - // query text then that query text SHOULD be used, otherwise all of the - // individual query texts SHOULD be concatenated with separator `; ` or some - // other database system specific separator if more applicable. - // Even though parameterized query text can potentially have sensitive data, by - // using a parameterized query the user is giving a strong signal that any - // sensitive data will be passed as parameter values, and the benefit to - // observability of capturing the static part of the query text by default - // outweighs the risk. - // - // [Sanitization of `db.query.text`]: ../../docs/database/database-spans.md#sanitization-of-dbquerytext - DBQueryTextKey = attribute.Key("db.query.text") - - // DBResponseReturnedRowsKey is the attribute Key conforming to the - // "db.response.returned_rows" semantic conventions. It represents the number of - // rows returned by the operation. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 10, 30, 1000 - DBResponseReturnedRowsKey = attribute.Key("db.response.returned_rows") - - // DBResponseStatusCodeKey is the attribute Key conforming to the - // "db.response.status_code" semantic conventions. It represents the database - // response status code. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: "102", "ORA-17002", "08P01", "404" - // Note: The status code returned by the database. Usually it represents an - // error code, but may also represent partial success, warning, or differentiate - // between various types of successful outcomes. - // Semantic conventions for individual database systems SHOULD document what - // `db.response.status_code` means in the context of that system. - DBResponseStatusCodeKey = attribute.Key("db.response.status_code") - - // DBSystemNameKey is the attribute Key conforming to the "db.system.name" - // semantic conventions. It represents the database management system (DBMS) - // product as identified by the client instrumentation. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Release_Candidate - // - // Examples: - // Note: The actual DBMS may differ from the one identified by the client. For - // example, when using PostgreSQL client libraries to connect to a CockroachDB, - // the `db.system.name` is set to `postgresql` based on the instrumentation's - // best knowledge. - DBSystemNameKey = attribute.Key("db.system.name") -) - -// DBClientConnectionPoolName returns an attribute KeyValue conforming to the -// "db.client.connection.pool.name" semantic conventions. It represents the name -// of the connection pool; unique within the instrumented application. In case -// the connection pool implementation doesn't provide a name, instrumentation -// SHOULD use a combination of parameters that would make the name unique, for -// example, combining attributes `server.address`, `server.port`, and -// `db.namespace`, formatted as `server.address:server.port/db.namespace`. -// Instrumentations that generate connection pool name following different -// patterns SHOULD document it. -func DBClientConnectionPoolName(val string) attribute.KeyValue { - return DBClientConnectionPoolNameKey.String(val) -} - -// DBCollectionName returns an attribute KeyValue conforming to the -// "db.collection.name" semantic conventions. It represents the name of a -// collection (table, container) within the database. -func DBCollectionName(val string) attribute.KeyValue { - return DBCollectionNameKey.String(val) -} - -// DBNamespace returns an attribute KeyValue conforming to the "db.namespace" -// semantic conventions. It represents the name of the database, fully qualified -// within the server address and port. -func DBNamespace(val string) attribute.KeyValue { - return DBNamespaceKey.String(val) -} - -// DBOperationBatchSize returns an attribute KeyValue conforming to the -// "db.operation.batch.size" semantic conventions. It represents the number of -// queries included in a batch operation. -func DBOperationBatchSize(val int) attribute.KeyValue { - return DBOperationBatchSizeKey.Int(val) -} - -// DBOperationName returns an attribute KeyValue conforming to the -// "db.operation.name" semantic conventions. It represents the name of the -// operation or command being executed. -func DBOperationName(val string) attribute.KeyValue { - return DBOperationNameKey.String(val) -} - -// DBQuerySummary returns an attribute KeyValue conforming to the -// "db.query.summary" semantic conventions. It represents the low cardinality -// representation of a database query text. -func DBQuerySummary(val string) attribute.KeyValue { - return DBQuerySummaryKey.String(val) -} - -// DBQueryText returns an attribute KeyValue conforming to the "db.query.text" -// semantic conventions. It represents the database query being executed. -func DBQueryText(val string) attribute.KeyValue { - return DBQueryTextKey.String(val) -} - -// DBResponseReturnedRows returns an attribute KeyValue conforming to the -// "db.response.returned_rows" semantic conventions. It represents the number of -// rows returned by the operation. -func DBResponseReturnedRows(val int) attribute.KeyValue { - return DBResponseReturnedRowsKey.Int(val) -} - -// DBResponseStatusCode returns an attribute KeyValue conforming to the -// "db.response.status_code" semantic conventions. It represents the database -// response status code. -func DBResponseStatusCode(val string) attribute.KeyValue { - return DBResponseStatusCodeKey.String(val) -} - -// Enum values for db.client.connection.state -var ( - // idle - // Stability: development - DBClientConnectionStateIdle = DBClientConnectionStateKey.String("idle") - // used - // Stability: development - DBClientConnectionStateUsed = DBClientConnectionStateKey.String("used") -) - -// Enum values for db.system.name -var ( - // Some other SQL database. Fallback only. - // Stability: development - DBSystemNameOtherSQL = DBSystemNameKey.String("other_sql") - // [Adabas (Adaptable Database System)] - // Stability: development - // - // [Adabas (Adaptable Database System)]: https://documentation.softwareag.com/?pf=adabas - DBSystemNameSoftwareagAdabas = DBSystemNameKey.String("softwareag.adabas") - // [Actian Ingres] - // Stability: development - // - // [Actian Ingres]: https://www.actian.com/databases/ingres/ - DBSystemNameActianIngres = DBSystemNameKey.String("actian.ingres") - // [Amazon DynamoDB] - // Stability: development - // - // [Amazon DynamoDB]: https://aws.amazon.com/pm/dynamodb/ - DBSystemNameAWSDynamoDB = DBSystemNameKey.String("aws.dynamodb") - // [Amazon Redshift] - // Stability: development - // - // [Amazon Redshift]: https://aws.amazon.com/redshift/ - DBSystemNameAWSRedshift = DBSystemNameKey.String("aws.redshift") - // [Azure Cosmos DB] - // Stability: development - // - // [Azure Cosmos DB]: https://learn.microsoft.com/azure/cosmos-db - DBSystemNameAzureCosmosDB = DBSystemNameKey.String("azure.cosmosdb") - // [InterSystems Caché] - // Stability: development - // - // [InterSystems Caché]: https://www.intersystems.com/products/cache/ - DBSystemNameIntersystemsCache = DBSystemNameKey.String("intersystems.cache") - // [Apache Cassandra] - // Stability: development - // - // [Apache Cassandra]: https://cassandra.apache.org/ - DBSystemNameCassandra = DBSystemNameKey.String("cassandra") - // [ClickHouse] - // Stability: development - // - // [ClickHouse]: https://clickhouse.com/ - DBSystemNameClickhouse = DBSystemNameKey.String("clickhouse") - // [CockroachDB] - // Stability: development - // - // [CockroachDB]: https://www.cockroachlabs.com/ - DBSystemNameCockroachdb = DBSystemNameKey.String("cockroachdb") - // [Couchbase] - // Stability: development - // - // [Couchbase]: https://www.couchbase.com/ - DBSystemNameCouchbase = DBSystemNameKey.String("couchbase") - // [Apache CouchDB] - // Stability: development - // - // [Apache CouchDB]: https://couchdb.apache.org/ - DBSystemNameCouchDB = DBSystemNameKey.String("couchdb") - // [Apache Derby] - // Stability: development - // - // [Apache Derby]: https://db.apache.org/derby/ - DBSystemNameDerby = DBSystemNameKey.String("derby") - // [Elasticsearch] - // Stability: development - // - // [Elasticsearch]: https://www.elastic.co/elasticsearch - DBSystemNameElasticsearch = DBSystemNameKey.String("elasticsearch") - // [Firebird] - // Stability: development - // - // [Firebird]: https://www.firebirdsql.org/ - DBSystemNameFirebirdsql = DBSystemNameKey.String("firebirdsql") - // [Google Cloud Spanner] - // Stability: development - // - // [Google Cloud Spanner]: https://cloud.google.com/spanner - DBSystemNameGCPSpanner = DBSystemNameKey.String("gcp.spanner") - // [Apache Geode] - // Stability: development - // - // [Apache Geode]: https://geode.apache.org/ - DBSystemNameGeode = DBSystemNameKey.String("geode") - // [H2 Database] - // Stability: development - // - // [H2 Database]: https://h2database.com/ - DBSystemNameH2database = DBSystemNameKey.String("h2database") - // [Apache HBase] - // Stability: development - // - // [Apache HBase]: https://hbase.apache.org/ - DBSystemNameHBase = DBSystemNameKey.String("hbase") - // [Apache Hive] - // Stability: development - // - // [Apache Hive]: https://hive.apache.org/ - DBSystemNameHive = DBSystemNameKey.String("hive") - // [HyperSQL Database] - // Stability: development - // - // [HyperSQL Database]: https://hsqldb.org/ - DBSystemNameHSQLDB = DBSystemNameKey.String("hsqldb") - // [IBM Db2] - // Stability: development - // - // [IBM Db2]: https://www.ibm.com/db2 - DBSystemNameIbmDb2 = DBSystemNameKey.String("ibm.db2") - // [IBM Informix] - // Stability: development - // - // [IBM Informix]: https://www.ibm.com/products/informix - DBSystemNameIbmInformix = DBSystemNameKey.String("ibm.informix") - // [IBM Netezza] - // Stability: development - // - // [IBM Netezza]: https://www.ibm.com/products/netezza - DBSystemNameIbmNetezza = DBSystemNameKey.String("ibm.netezza") - // [InfluxDB] - // Stability: development - // - // [InfluxDB]: https://www.influxdata.com/ - DBSystemNameInfluxdb = DBSystemNameKey.String("influxdb") - // [Instant] - // Stability: development - // - // [Instant]: https://www.instantdb.com/ - DBSystemNameInstantDB = DBSystemNameKey.String("instantdb") - // [MariaDB] - // Stability: release_candidate - // - // [MariaDB]: https://mariadb.org/ - DBSystemNameMariaDB = DBSystemNameKey.String("mariadb") - // [Memcached] - // Stability: development - // - // [Memcached]: https://memcached.org/ - DBSystemNameMemcached = DBSystemNameKey.String("memcached") - // [MongoDB] - // Stability: development - // - // [MongoDB]: https://www.mongodb.com/ - DBSystemNameMongoDB = DBSystemNameKey.String("mongodb") - // [Microsoft SQL Server] - // Stability: release_candidate - // - // [Microsoft SQL Server]: https://www.microsoft.com/sql-server - DBSystemNameMicrosoftSQLServer = DBSystemNameKey.String("microsoft.sql_server") - // [MySQL] - // Stability: release_candidate - // - // [MySQL]: https://www.mysql.com/ - DBSystemNameMySQL = DBSystemNameKey.String("mysql") - // [Neo4j] - // Stability: development - // - // [Neo4j]: https://neo4j.com/ - DBSystemNameNeo4j = DBSystemNameKey.String("neo4j") - // [OpenSearch] - // Stability: development - // - // [OpenSearch]: https://opensearch.org/ - DBSystemNameOpensearch = DBSystemNameKey.String("opensearch") - // [Oracle Database] - // Stability: development - // - // [Oracle Database]: https://www.oracle.com/database/ - DBSystemNameOracleDB = DBSystemNameKey.String("oracle.db") - // [PostgreSQL] - // Stability: release_candidate - // - // [PostgreSQL]: https://www.postgresql.org/ - DBSystemNamePostgreSQL = DBSystemNameKey.String("postgresql") - // [Redis] - // Stability: development - // - // [Redis]: https://redis.io/ - DBSystemNameRedis = DBSystemNameKey.String("redis") - // [SAP HANA] - // Stability: development - // - // [SAP HANA]: https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html - DBSystemNameSapHana = DBSystemNameKey.String("sap.hana") - // [SAP MaxDB] - // Stability: development - // - // [SAP MaxDB]: https://maxdb.sap.com/ - DBSystemNameSapMaxDB = DBSystemNameKey.String("sap.maxdb") - // [SQLite] - // Stability: development - // - // [SQLite]: https://www.sqlite.org/ - DBSystemNameSqlite = DBSystemNameKey.String("sqlite") - // [Teradata] - // Stability: development - // - // [Teradata]: https://www.teradata.com/ - DBSystemNameTeradata = DBSystemNameKey.String("teradata") - // [Trino] - // Stability: development - // - // [Trino]: https://trino.io/ - DBSystemNameTrino = DBSystemNameKey.String("trino") -) - -// Namespace: deployment -const ( - // DeploymentEnvironmentNameKey is the attribute Key conforming to the - // "deployment.environment.name" semantic conventions. It represents the name of - // the [deployment environment] (aka deployment tier). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "staging", "production" - // Note: `deployment.environment.name` does not affect the uniqueness - // constraints defined through - // the `service.namespace`, `service.name` and `service.instance.id` resource - // attributes. - // This implies that resources carrying the following attribute combinations - // MUST be - // considered to be identifying the same service: - // - // - `service.name=frontend`, `deployment.environment.name=production` - // - `service.name=frontend`, `deployment.environment.name=staging`. - // - // - // [deployment environment]: https://wikipedia.org/wiki/Deployment_environment - DeploymentEnvironmentNameKey = attribute.Key("deployment.environment.name") - - // DeploymentIDKey is the attribute Key conforming to the "deployment.id" - // semantic conventions. It represents the id of the deployment. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1208" - DeploymentIDKey = attribute.Key("deployment.id") - - // DeploymentNameKey is the attribute Key conforming to the "deployment.name" - // semantic conventions. It represents the name of the deployment. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "deploy my app", "deploy-frontend" - DeploymentNameKey = attribute.Key("deployment.name") - - // DeploymentStatusKey is the attribute Key conforming to the - // "deployment.status" semantic conventions. It represents the status of the - // deployment. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - DeploymentStatusKey = attribute.Key("deployment.status") -) - -// DeploymentEnvironmentName returns an attribute KeyValue conforming to the -// "deployment.environment.name" semantic conventions. It represents the name of -// the [deployment environment] (aka deployment tier). -// -// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment -func DeploymentEnvironmentName(val string) attribute.KeyValue { - return DeploymentEnvironmentNameKey.String(val) -} - -// DeploymentID returns an attribute KeyValue conforming to the "deployment.id" -// semantic conventions. It represents the id of the deployment. -func DeploymentID(val string) attribute.KeyValue { - return DeploymentIDKey.String(val) -} - -// DeploymentName returns an attribute KeyValue conforming to the -// "deployment.name" semantic conventions. It represents the name of the -// deployment. -func DeploymentName(val string) attribute.KeyValue { - return DeploymentNameKey.String(val) -} - -// Enum values for deployment.status -var ( - // failed - // Stability: development - DeploymentStatusFailed = DeploymentStatusKey.String("failed") - // succeeded - // Stability: development - DeploymentStatusSucceeded = DeploymentStatusKey.String("succeeded") -) - -// Namespace: destination -const ( - // DestinationAddressKey is the attribute Key conforming to the - // "destination.address" semantic conventions. It represents the destination - // address - domain name if available without reverse DNS lookup; otherwise, IP - // address or Unix domain socket name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "destination.example.com", "10.1.2.80", "/tmp/my.sock" - // Note: When observed from the source side, and when communicating through an - // intermediary, `destination.address` SHOULD represent the destination address - // behind any intermediaries, for example proxies, if it's available. - DestinationAddressKey = attribute.Key("destination.address") - - // DestinationPortKey is the attribute Key conforming to the "destination.port" - // semantic conventions. It represents the destination port number. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 3389, 2888 - DestinationPortKey = attribute.Key("destination.port") -) - -// DestinationAddress returns an attribute KeyValue conforming to the -// "destination.address" semantic conventions. It represents the destination -// address - domain name if available without reverse DNS lookup; otherwise, IP -// address or Unix domain socket name. -func DestinationAddress(val string) attribute.KeyValue { - return DestinationAddressKey.String(val) -} - -// DestinationPort returns an attribute KeyValue conforming to the -// "destination.port" semantic conventions. It represents the destination port -// number. -func DestinationPort(val int) attribute.KeyValue { - return DestinationPortKey.Int(val) -} - -// Namespace: device -const ( - // DeviceIDKey is the attribute Key conforming to the "device.id" semantic - // conventions. It represents a unique identifier representing the device. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2ab2916d-a51f-4ac8-80ee-45ac31a28092" - // Note: The device identifier MUST only be defined using the values outlined - // below. This value is not an advertising identifier and MUST NOT be used as - // such. On iOS (Swift or Objective-C), this value MUST be equal to the - // [vendor identifier]. On Android (Java or Kotlin), this value MUST be equal to - // the Firebase Installation ID or a globally unique UUID which is persisted - // across sessions in your application. More information can be found [here] on - // best practices and exact implementation details. Caution should be taken when - // storing personal data or anything which can identify a user. GDPR and data - // protection laws may apply, ensure you do your own due diligence. - // - // [vendor identifier]: https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor - // [here]: https://developer.android.com/training/articles/user-data-ids - DeviceIDKey = attribute.Key("device.id") - - // DeviceManufacturerKey is the attribute Key conforming to the - // "device.manufacturer" semantic conventions. It represents the name of the - // device manufacturer. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Apple", "Samsung" - // Note: The Android OS provides this field via [Build]. iOS apps SHOULD - // hardcode the value `Apple`. - // - // [Build]: https://developer.android.com/reference/android/os/Build#MANUFACTURER - DeviceManufacturerKey = attribute.Key("device.manufacturer") - - // DeviceModelIdentifierKey is the attribute Key conforming to the - // "device.model.identifier" semantic conventions. It represents the model - // identifier for the device. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "iPhone3,4", "SM-G920F" - // Note: It's recommended this value represents a machine-readable version of - // the model identifier rather than the market or consumer-friendly name of the - // device. - DeviceModelIdentifierKey = attribute.Key("device.model.identifier") - - // DeviceModelNameKey is the attribute Key conforming to the "device.model.name" - // semantic conventions. It represents the marketing name for the device model. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "iPhone 6s Plus", "Samsung Galaxy S6" - // Note: It's recommended this value represents a human-readable version of the - // device model rather than a machine-readable alternative. - DeviceModelNameKey = attribute.Key("device.model.name") -) - -// DeviceID returns an attribute KeyValue conforming to the "device.id" semantic -// conventions. It represents a unique identifier representing the device. -func DeviceID(val string) attribute.KeyValue { - return DeviceIDKey.String(val) -} - -// DeviceManufacturer returns an attribute KeyValue conforming to the -// "device.manufacturer" semantic conventions. It represents the name of the -// device manufacturer. -func DeviceManufacturer(val string) attribute.KeyValue { - return DeviceManufacturerKey.String(val) -} - -// DeviceModelIdentifier returns an attribute KeyValue conforming to the -// "device.model.identifier" semantic conventions. It represents the model -// identifier for the device. -func DeviceModelIdentifier(val string) attribute.KeyValue { - return DeviceModelIdentifierKey.String(val) -} - -// DeviceModelName returns an attribute KeyValue conforming to the -// "device.model.name" semantic conventions. It represents the marketing name for -// the device model. -func DeviceModelName(val string) attribute.KeyValue { - return DeviceModelNameKey.String(val) -} - -// Namespace: disk -const ( - // DiskIoDirectionKey is the attribute Key conforming to the "disk.io.direction" - // semantic conventions. It represents the disk IO operation direction. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "read" - DiskIoDirectionKey = attribute.Key("disk.io.direction") -) - -// Enum values for disk.io.direction -var ( - // read - // Stability: development - DiskIoDirectionRead = DiskIoDirectionKey.String("read") - // write - // Stability: development - DiskIoDirectionWrite = DiskIoDirectionKey.String("write") -) - -// Namespace: dns -const ( - // DNSQuestionNameKey is the attribute Key conforming to the "dns.question.name" - // semantic conventions. It represents the name being queried. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "www.example.com", "opentelemetry.io" - // Note: If the name field contains non-printable characters (below 32 or above - // 126), those characters should be represented as escaped base 10 integers - // (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, - // and line feeds should be converted to \t, \r, and \n respectively. - DNSQuestionNameKey = attribute.Key("dns.question.name") -) - -// DNSQuestionName returns an attribute KeyValue conforming to the -// "dns.question.name" semantic conventions. It represents the name being -// queried. -func DNSQuestionName(val string) attribute.KeyValue { - return DNSQuestionNameKey.String(val) -} - -// Namespace: elasticsearch -const ( - // ElasticsearchNodeNameKey is the attribute Key conforming to the - // "elasticsearch.node.name" semantic conventions. It represents the represents - // the human-readable identifier of the node/instance to which a request was - // routed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "instance-0000000001" - ElasticsearchNodeNameKey = attribute.Key("elasticsearch.node.name") -) - -// ElasticsearchNodeName returns an attribute KeyValue conforming to the -// "elasticsearch.node.name" semantic conventions. It represents the represents -// the human-readable identifier of the node/instance to which a request was -// routed. -func ElasticsearchNodeName(val string) attribute.KeyValue { - return ElasticsearchNodeNameKey.String(val) -} - -// Namespace: error -const ( - // ErrorTypeKey is the attribute Key conforming to the "error.type" semantic - // conventions. It represents the describes a class of error the operation ended - // with. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "timeout", "java.net.UnknownHostException", - // "server_certificate_invalid", "500" - // Note: The `error.type` SHOULD be predictable, and SHOULD have low - // cardinality. - // - // When `error.type` is set to a type (e.g., an exception type), its - // canonical class name identifying the type within the artifact SHOULD be used. - // - // Instrumentations SHOULD document the list of errors they report. - // - // The cardinality of `error.type` within one instrumentation library SHOULD be - // low. - // Telemetry consumers that aggregate data from multiple instrumentation - // libraries and applications - // should be prepared for `error.type` to have high cardinality at query time - // when no - // additional filters are applied. - // - // If the operation has completed successfully, instrumentations SHOULD NOT set - // `error.type`. - // - // If a specific domain defines its own set of error identifiers (such as HTTP - // or gRPC status codes), - // it's RECOMMENDED to: - // - // - Use a domain-specific attribute - // - Set `error.type` to capture all errors, regardless of whether they are - // defined within the domain-specific set or not. - ErrorTypeKey = attribute.Key("error.type") -) - -// Enum values for error.type -var ( - // A fallback error value to be used when the instrumentation doesn't define a - // custom value. - // - // Stability: stable - ErrorTypeOther = ErrorTypeKey.String("_OTHER") -) - -// Namespace: exception -const ( - // ExceptionMessageKey is the attribute Key conforming to the - // "exception.message" semantic conventions. It represents the exception - // message. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "Division by zero", "Can't convert 'int' object to str implicitly" - ExceptionMessageKey = attribute.Key("exception.message") - - // ExceptionStacktraceKey is the attribute Key conforming to the - // "exception.stacktrace" semantic conventions. It represents a stacktrace as a - // string in the natural representation for the language runtime. The - // representation is to be determined and documented by each language SIG. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: Exception in thread "main" java.lang.RuntimeException: Test - // exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at - // com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at - // com.example.GenerateTrace.main(GenerateTrace.java:5) - ExceptionStacktraceKey = attribute.Key("exception.stacktrace") - - // ExceptionTypeKey is the attribute Key conforming to the "exception.type" - // semantic conventions. It represents the type of the exception (its - // fully-qualified class name, if applicable). The dynamic type of the exception - // should be preferred over the static type in languages that support it. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "java.net.ConnectException", "OSError" - ExceptionTypeKey = attribute.Key("exception.type") -) - -// ExceptionMessage returns an attribute KeyValue conforming to the -// "exception.message" semantic conventions. It represents the exception message. -func ExceptionMessage(val string) attribute.KeyValue { - return ExceptionMessageKey.String(val) -} - -// ExceptionStacktrace returns an attribute KeyValue conforming to the -// "exception.stacktrace" semantic conventions. It represents a stacktrace as a -// string in the natural representation for the language runtime. The -// representation is to be determined and documented by each language SIG. -func ExceptionStacktrace(val string) attribute.KeyValue { - return ExceptionStacktraceKey.String(val) -} - -// ExceptionType returns an attribute KeyValue conforming to the "exception.type" -// semantic conventions. It represents the type of the exception (its -// fully-qualified class name, if applicable). The dynamic type of the exception -// should be preferred over the static type in languages that support it. -func ExceptionType(val string) attribute.KeyValue { - return ExceptionTypeKey.String(val) -} - -// Namespace: faas -const ( - // FaaSColdstartKey is the attribute Key conforming to the "faas.coldstart" - // semantic conventions. It represents a boolean that is true if the serverless - // function is executed for the first time (aka cold-start). - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - FaaSColdstartKey = attribute.Key("faas.coldstart") - - // FaaSCronKey is the attribute Key conforming to the "faas.cron" semantic - // conventions. It represents a string containing the schedule period as - // [Cron Expression]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0/5 * * * ? * - // - // [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm - FaaSCronKey = attribute.Key("faas.cron") - - // FaaSDocumentCollectionKey is the attribute Key conforming to the - // "faas.document.collection" semantic conventions. It represents the name of - // the source on which the triggering operation was performed. For example, in - // Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the - // database name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "myBucketName", "myDbName" - FaaSDocumentCollectionKey = attribute.Key("faas.document.collection") - - // FaaSDocumentNameKey is the attribute Key conforming to the - // "faas.document.name" semantic conventions. It represents the document - // name/table subjected to the operation. For example, in Cloud Storage or S3 is - // the name of the file, and in Cosmos DB the table name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "myFile.txt", "myTableName" - FaaSDocumentNameKey = attribute.Key("faas.document.name") - - // FaaSDocumentOperationKey is the attribute Key conforming to the - // "faas.document.operation" semantic conventions. It represents the describes - // the type of the operation that was performed on the data. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - FaaSDocumentOperationKey = attribute.Key("faas.document.operation") - - // FaaSDocumentTimeKey is the attribute Key conforming to the - // "faas.document.time" semantic conventions. It represents a string containing - // the time when the data was accessed in the [ISO 8601] format expressed in - // [UTC]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 2020-01-23T13:47:06Z - // - // [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html - // [UTC]: https://www.w3.org/TR/NOTE-datetime - FaaSDocumentTimeKey = attribute.Key("faas.document.time") - - // FaaSInstanceKey is the attribute Key conforming to the "faas.instance" - // semantic conventions. It represents the execution environment ID as a string, - // that will be potentially reused for other invocations to the same - // function/function version. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de" - // Note: - **AWS Lambda:** Use the (full) log stream name. - FaaSInstanceKey = attribute.Key("faas.instance") - - // FaaSInvocationIDKey is the attribute Key conforming to the - // "faas.invocation_id" semantic conventions. It represents the invocation ID of - // the current function invocation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: af9d5aa4-a685-4c5f-a22b-444f80b3cc28 - FaaSInvocationIDKey = attribute.Key("faas.invocation_id") - - // FaaSInvokedNameKey is the attribute Key conforming to the "faas.invoked_name" - // semantic conventions. It represents the name of the invoked function. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: my-function - // Note: SHOULD be equal to the `faas.name` resource attribute of the invoked - // function. - FaaSInvokedNameKey = attribute.Key("faas.invoked_name") - - // FaaSInvokedProviderKey is the attribute Key conforming to the - // "faas.invoked_provider" semantic conventions. It represents the cloud - // provider of the invoked function. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: SHOULD be equal to the `cloud.provider` resource attribute of the - // invoked function. - FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider") - - // FaaSInvokedRegionKey is the attribute Key conforming to the - // "faas.invoked_region" semantic conventions. It represents the cloud region of - // the invoked function. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: eu-central-1 - // Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked - // function. - FaaSInvokedRegionKey = attribute.Key("faas.invoked_region") - - // FaaSMaxMemoryKey is the attribute Key conforming to the "faas.max_memory" - // semantic conventions. It represents the amount of memory available to the - // serverless function converted to Bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Note: It's recommended to set this attribute since e.g. too little memory can - // easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, - // the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this - // information (which must be multiplied by 1,048,576). - FaaSMaxMemoryKey = attribute.Key("faas.max_memory") - - // FaaSNameKey is the attribute Key conforming to the "faas.name" semantic - // conventions. It represents the name of the single function that this runtime - // instance executes. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-function", "myazurefunctionapp/some-function-name" - // Note: This is the name of the function as configured/deployed on the FaaS - // platform and is usually different from the name of the callback - // function (which may be stored in the - // [`code.namespace`/`code.function.name`] - // span attributes). - // - // For some cloud providers, the above definition is ambiguous. The following - // definition of function name MUST be used for this attribute - // (and consequently the span name) for the listed cloud providers/products: - // - // - **Azure:** The full name `/`, i.e., function app name - // followed by a forward slash followed by the function name (this form - // can also be seen in the resource JSON for the function). - // This means that a span attribute MUST be used, as an Azure function - // app can host multiple functions that would usually share - // a TracerProvider (see also the `cloud.resource_id` attribute). - // - // - // [`code.namespace`/`code.function.name`]: /docs/general/attributes.md#source-code-attributes - FaaSNameKey = attribute.Key("faas.name") - - // FaaSTimeKey is the attribute Key conforming to the "faas.time" semantic - // conventions. It represents a string containing the function invocation time - // in the [ISO 8601] format expressed in [UTC]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 2020-01-23T13:47:06Z - // - // [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html - // [UTC]: https://www.w3.org/TR/NOTE-datetime - FaaSTimeKey = attribute.Key("faas.time") - - // FaaSTriggerKey is the attribute Key conforming to the "faas.trigger" semantic - // conventions. It represents the type of the trigger which caused this function - // invocation. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - FaaSTriggerKey = attribute.Key("faas.trigger") - - // FaaSVersionKey is the attribute Key conforming to the "faas.version" semantic - // conventions. It represents the immutable version of the function being - // executed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "26", "pinkfroid-00002" - // Note: Depending on the cloud provider and platform, use: - // - // - **AWS Lambda:** The [function version] - // (an integer represented as a decimal string). - // - **Google Cloud Run (Services):** The [revision] - // (i.e., the function name plus the revision suffix). - // - **Google Cloud Functions:** The value of the - // [`K_REVISION` environment variable]. - // - **Azure Functions:** Not applicable. Do not set this attribute. - // - // - // [function version]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html - // [revision]: https://cloud.google.com/run/docs/managing/revisions - // [`K_REVISION` environment variable]: https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically - FaaSVersionKey = attribute.Key("faas.version") -) - -// FaaSColdstart returns an attribute KeyValue conforming to the "faas.coldstart" -// semantic conventions. It represents a boolean that is true if the serverless -// function is executed for the first time (aka cold-start). -func FaaSColdstart(val bool) attribute.KeyValue { - return FaaSColdstartKey.Bool(val) -} - -// FaaSCron returns an attribute KeyValue conforming to the "faas.cron" semantic -// conventions. It represents a string containing the schedule period as -// [Cron Expression]. -// -// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm -func FaaSCron(val string) attribute.KeyValue { - return FaaSCronKey.String(val) -} - -// FaaSDocumentCollection returns an attribute KeyValue conforming to the -// "faas.document.collection" semantic conventions. It represents the name of the -// source on which the triggering operation was performed. For example, in Cloud -// Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database -// name. -func FaaSDocumentCollection(val string) attribute.KeyValue { - return FaaSDocumentCollectionKey.String(val) -} - -// FaaSDocumentName returns an attribute KeyValue conforming to the -// "faas.document.name" semantic conventions. It represents the document -// name/table subjected to the operation. For example, in Cloud Storage or S3 is -// the name of the file, and in Cosmos DB the table name. -func FaaSDocumentName(val string) attribute.KeyValue { - return FaaSDocumentNameKey.String(val) -} - -// FaaSDocumentTime returns an attribute KeyValue conforming to the -// "faas.document.time" semantic conventions. It represents a string containing -// the time when the data was accessed in the [ISO 8601] format expressed in -// [UTC]. -// -// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html -// [UTC]: https://www.w3.org/TR/NOTE-datetime -func FaaSDocumentTime(val string) attribute.KeyValue { - return FaaSDocumentTimeKey.String(val) -} - -// FaaSInstance returns an attribute KeyValue conforming to the "faas.instance" -// semantic conventions. It represents the execution environment ID as a string, -// that will be potentially reused for other invocations to the same -// function/function version. -func FaaSInstance(val string) attribute.KeyValue { - return FaaSInstanceKey.String(val) -} - -// FaaSInvocationID returns an attribute KeyValue conforming to the -// "faas.invocation_id" semantic conventions. It represents the invocation ID of -// the current function invocation. -func FaaSInvocationID(val string) attribute.KeyValue { - return FaaSInvocationIDKey.String(val) -} - -// FaaSInvokedName returns an attribute KeyValue conforming to the -// "faas.invoked_name" semantic conventions. It represents the name of the -// invoked function. -func FaaSInvokedName(val string) attribute.KeyValue { - return FaaSInvokedNameKey.String(val) -} - -// FaaSInvokedRegion returns an attribute KeyValue conforming to the -// "faas.invoked_region" semantic conventions. It represents the cloud region of -// the invoked function. -func FaaSInvokedRegion(val string) attribute.KeyValue { - return FaaSInvokedRegionKey.String(val) -} - -// FaaSMaxMemory returns an attribute KeyValue conforming to the -// "faas.max_memory" semantic conventions. It represents the amount of memory -// available to the serverless function converted to Bytes. -func FaaSMaxMemory(val int) attribute.KeyValue { - return FaaSMaxMemoryKey.Int(val) -} - -// FaaSName returns an attribute KeyValue conforming to the "faas.name" semantic -// conventions. It represents the name of the single function that this runtime -// instance executes. -func FaaSName(val string) attribute.KeyValue { - return FaaSNameKey.String(val) -} - -// FaaSTime returns an attribute KeyValue conforming to the "faas.time" semantic -// conventions. It represents a string containing the function invocation time in -// the [ISO 8601] format expressed in [UTC]. -// -// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html -// [UTC]: https://www.w3.org/TR/NOTE-datetime -func FaaSTime(val string) attribute.KeyValue { - return FaaSTimeKey.String(val) -} - -// FaaSVersion returns an attribute KeyValue conforming to the "faas.version" -// semantic conventions. It represents the immutable version of the function -// being executed. -func FaaSVersion(val string) attribute.KeyValue { - return FaaSVersionKey.String(val) -} - -// Enum values for faas.document.operation -var ( - // When a new object is created. - // Stability: development - FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert") - // When an object is modified. - // Stability: development - FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit") - // When an object is deleted. - // Stability: development - FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete") -) - -// Enum values for faas.invoked_provider -var ( - // Alibaba Cloud - // Stability: development - FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud") - // Amazon Web Services - // Stability: development - FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws") - // Microsoft Azure - // Stability: development - FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure") - // Google Cloud Platform - // Stability: development - FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp") - // Tencent Cloud - // Stability: development - FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud") -) - -// Enum values for faas.trigger -var ( - // A response to some data source operation such as a database or filesystem - // read/write - // Stability: development - FaaSTriggerDatasource = FaaSTriggerKey.String("datasource") - // To provide an answer to an inbound HTTP request - // Stability: development - FaaSTriggerHTTP = FaaSTriggerKey.String("http") - // A function is set to be executed when messages are sent to a messaging system - // Stability: development - FaaSTriggerPubsub = FaaSTriggerKey.String("pubsub") - // A function is scheduled to be executed regularly - // Stability: development - FaaSTriggerTimer = FaaSTriggerKey.String("timer") - // If none of the others apply - // Stability: development - FaaSTriggerOther = FaaSTriggerKey.String("other") -) - -// Namespace: feature_flag -const ( - // FeatureFlagContextIDKey is the attribute Key conforming to the - // "feature_flag.context.id" semantic conventions. It represents the unique - // identifier for the flag evaluation context. For example, the targeting key. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "5157782b-2203-4c80-a857-dbbd5e7761db" - FeatureFlagContextIDKey = attribute.Key("feature_flag.context.id") - - // FeatureFlagEvaluationErrorMessageKey is the attribute Key conforming to the - // "feature_flag.evaluation.error.message" semantic conventions. It represents a - // message explaining the nature of an error occurring during flag evaluation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Flag `header-color` expected type `string` but found type `number` - // " - FeatureFlagEvaluationErrorMessageKey = attribute.Key("feature_flag.evaluation.error.message") - - // FeatureFlagEvaluationReasonKey is the attribute Key conforming to the - // "feature_flag.evaluation.reason" semantic conventions. It represents the - // reason code which shows how a feature flag value was determined. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "static", "targeting_match", "error", "default" - FeatureFlagEvaluationReasonKey = attribute.Key("feature_flag.evaluation.reason") - - // FeatureFlagKeyKey is the attribute Key conforming to the "feature_flag.key" - // semantic conventions. It represents the lookup key of the feature flag. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "logo-color" - FeatureFlagKeyKey = attribute.Key("feature_flag.key") - - // FeatureFlagProviderNameKey is the attribute Key conforming to the - // "feature_flag.provider_name" semantic conventions. It represents the - // identifies the feature flag provider. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Flag Manager" - FeatureFlagProviderNameKey = attribute.Key("feature_flag.provider_name") - - // FeatureFlagSetIDKey is the attribute Key conforming to the - // "feature_flag.set.id" semantic conventions. It represents the identifier of - // the [flag set] to which the feature flag belongs. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "proj-1", "ab98sgs", "service1/dev" - // - // [flag set]: https://openfeature.dev/specification/glossary/#flag-set - FeatureFlagSetIDKey = attribute.Key("feature_flag.set.id") - - // FeatureFlagVariantKey is the attribute Key conforming to the - // "feature_flag.variant" semantic conventions. It represents a semantic - // identifier for an evaluated flag value. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "red", "true", "on" - // Note: A semantic identifier, commonly referred to as a variant, provides a - // means - // for referring to a value without including the value itself. This can - // provide additional context for understanding the meaning behind a value. - // For example, the variant `red` maybe be used for the value `#c05543`. - FeatureFlagVariantKey = attribute.Key("feature_flag.variant") - - // FeatureFlagVersionKey is the attribute Key conforming to the - // "feature_flag.version" semantic conventions. It represents the version of the - // ruleset used during the evaluation. This may be any stable value which - // uniquely identifies the ruleset. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1", "01ABCDEF" - FeatureFlagVersionKey = attribute.Key("feature_flag.version") -) - -// FeatureFlagContextID returns an attribute KeyValue conforming to the -// "feature_flag.context.id" semantic conventions. It represents the unique -// identifier for the flag evaluation context. For example, the targeting key. -func FeatureFlagContextID(val string) attribute.KeyValue { - return FeatureFlagContextIDKey.String(val) -} - -// FeatureFlagEvaluationErrorMessage returns an attribute KeyValue conforming to -// the "feature_flag.evaluation.error.message" semantic conventions. It -// represents a message explaining the nature of an error occurring during flag -// evaluation. -func FeatureFlagEvaluationErrorMessage(val string) attribute.KeyValue { - return FeatureFlagEvaluationErrorMessageKey.String(val) -} - -// FeatureFlagKey returns an attribute KeyValue conforming to the -// "feature_flag.key" semantic conventions. It represents the lookup key of the -// feature flag. -func FeatureFlagKey(val string) attribute.KeyValue { - return FeatureFlagKeyKey.String(val) -} - -// FeatureFlagProviderName returns an attribute KeyValue conforming to the -// "feature_flag.provider_name" semantic conventions. It represents the -// identifies the feature flag provider. -func FeatureFlagProviderName(val string) attribute.KeyValue { - return FeatureFlagProviderNameKey.String(val) -} - -// FeatureFlagSetID returns an attribute KeyValue conforming to the -// "feature_flag.set.id" semantic conventions. It represents the identifier of -// the [flag set] to which the feature flag belongs. -// -// [flag set]: https://openfeature.dev/specification/glossary/#flag-set -func FeatureFlagSetID(val string) attribute.KeyValue { - return FeatureFlagSetIDKey.String(val) -} - -// FeatureFlagVariant returns an attribute KeyValue conforming to the -// "feature_flag.variant" semantic conventions. It represents a semantic -// identifier for an evaluated flag value. -func FeatureFlagVariant(val string) attribute.KeyValue { - return FeatureFlagVariantKey.String(val) -} - -// FeatureFlagVersion returns an attribute KeyValue conforming to the -// "feature_flag.version" semantic conventions. It represents the version of the -// ruleset used during the evaluation. This may be any stable value which -// uniquely identifies the ruleset. -func FeatureFlagVersion(val string) attribute.KeyValue { - return FeatureFlagVersionKey.String(val) -} - -// Enum values for feature_flag.evaluation.reason -var ( - // The resolved value is static (no dynamic evaluation). - // Stability: development - FeatureFlagEvaluationReasonStatic = FeatureFlagEvaluationReasonKey.String("static") - // The resolved value fell back to a pre-configured value (no dynamic evaluation - // occurred or dynamic evaluation yielded no result). - // Stability: development - FeatureFlagEvaluationReasonDefault = FeatureFlagEvaluationReasonKey.String("default") - // The resolved value was the result of a dynamic evaluation, such as a rule or - // specific user-targeting. - // Stability: development - FeatureFlagEvaluationReasonTargetingMatch = FeatureFlagEvaluationReasonKey.String("targeting_match") - // The resolved value was the result of pseudorandom assignment. - // Stability: development - FeatureFlagEvaluationReasonSplit = FeatureFlagEvaluationReasonKey.String("split") - // The resolved value was retrieved from cache. - // Stability: development - FeatureFlagEvaluationReasonCached = FeatureFlagEvaluationReasonKey.String("cached") - // The resolved value was the result of the flag being disabled in the - // management system. - // Stability: development - FeatureFlagEvaluationReasonDisabled = FeatureFlagEvaluationReasonKey.String("disabled") - // The reason for the resolved value could not be determined. - // Stability: development - FeatureFlagEvaluationReasonUnknown = FeatureFlagEvaluationReasonKey.String("unknown") - // The resolved value is non-authoritative or possibly out of date - // Stability: development - FeatureFlagEvaluationReasonStale = FeatureFlagEvaluationReasonKey.String("stale") - // The resolved value was the result of an error. - // Stability: development - FeatureFlagEvaluationReasonError = FeatureFlagEvaluationReasonKey.String("error") -) - -// Namespace: file -const ( - // FileAccessedKey is the attribute Key conforming to the "file.accessed" - // semantic conventions. It represents the time when the file was last accessed, - // in ISO 8601 format. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021-01-01T12:00:00Z" - // Note: This attribute might not be supported by some file systems — NFS, - // FAT32, in embedded OS, etc. - FileAccessedKey = attribute.Key("file.accessed") - - // FileAttributesKey is the attribute Key conforming to the "file.attributes" - // semantic conventions. It represents the array of file attributes. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "readonly", "hidden" - // Note: Attributes names depend on the OS or file system. Here’s a - // non-exhaustive list of values expected for this attribute: `archive`, - // `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`, - // `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`, - // `write`. - FileAttributesKey = attribute.Key("file.attributes") - - // FileChangedKey is the attribute Key conforming to the "file.changed" semantic - // conventions. It represents the time when the file attributes or metadata was - // last changed, in ISO 8601 format. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021-01-01T12:00:00Z" - // Note: `file.changed` captures the time when any of the file's properties or - // attributes (including the content) are changed, while `file.modified` - // captures the timestamp when the file content is modified. - FileChangedKey = attribute.Key("file.changed") - - // FileCreatedKey is the attribute Key conforming to the "file.created" semantic - // conventions. It represents the time when the file was created, in ISO 8601 - // format. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021-01-01T12:00:00Z" - // Note: This attribute might not be supported by some file systems — NFS, - // FAT32, in embedded OS, etc. - FileCreatedKey = attribute.Key("file.created") - - // FileDirectoryKey is the attribute Key conforming to the "file.directory" - // semantic conventions. It represents the directory where the file is located. - // It should include the drive letter, when appropriate. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/home/user", "C:\Program Files\MyApp" - FileDirectoryKey = attribute.Key("file.directory") - - // FileExtensionKey is the attribute Key conforming to the "file.extension" - // semantic conventions. It represents the file extension, excluding the leading - // dot. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "png", "gz" - // Note: When the file name has multiple extensions (example.tar.gz), only the - // last one should be captured ("gz", not "tar.gz"). - FileExtensionKey = attribute.Key("file.extension") - - // FileForkNameKey is the attribute Key conforming to the "file.fork_name" - // semantic conventions. It represents the name of the fork. A fork is - // additional data associated with a filesystem object. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Zone.Identifer" - // Note: On Linux, a resource fork is used to store additional data with a - // filesystem object. A file always has at least one fork for the data portion, - // and additional forks may exist. - // On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default - // data stream for a file is just called $DATA. Zone.Identifier is commonly used - // by Windows to track contents downloaded from the Internet. An ADS is - // typically of the form: C:\path\to\filename.extension:some_fork_name, and - // some_fork_name is the value that should populate `fork_name`. - // `filename.extension` should populate `file.name`, and `extension` should - // populate `file.extension`. The full path, `file.path`, will include the fork - // name. - FileForkNameKey = attribute.Key("file.fork_name") - - // FileGroupIDKey is the attribute Key conforming to the "file.group.id" - // semantic conventions. It represents the primary Group ID (GID) of the file. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1000" - FileGroupIDKey = attribute.Key("file.group.id") - - // FileGroupNameKey is the attribute Key conforming to the "file.group.name" - // semantic conventions. It represents the primary group name of the file. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "users" - FileGroupNameKey = attribute.Key("file.group.name") - - // FileInodeKey is the attribute Key conforming to the "file.inode" semantic - // conventions. It represents the inode representing the file in the filesystem. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "256383" - FileInodeKey = attribute.Key("file.inode") - - // FileModeKey is the attribute Key conforming to the "file.mode" semantic - // conventions. It represents the mode of the file in octal representation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0640" - FileModeKey = attribute.Key("file.mode") - - // FileModifiedKey is the attribute Key conforming to the "file.modified" - // semantic conventions. It represents the time when the file content was last - // modified, in ISO 8601 format. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021-01-01T12:00:00Z" - FileModifiedKey = attribute.Key("file.modified") - - // FileNameKey is the attribute Key conforming to the "file.name" semantic - // conventions. It represents the name of the file including the extension, - // without the directory. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "example.png" - FileNameKey = attribute.Key("file.name") - - // FileOwnerIDKey is the attribute Key conforming to the "file.owner.id" - // semantic conventions. It represents the user ID (UID) or security identifier - // (SID) of the file owner. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1000" - FileOwnerIDKey = attribute.Key("file.owner.id") - - // FileOwnerNameKey is the attribute Key conforming to the "file.owner.name" - // semantic conventions. It represents the username of the file owner. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "root" - FileOwnerNameKey = attribute.Key("file.owner.name") - - // FilePathKey is the attribute Key conforming to the "file.path" semantic - // conventions. It represents the full path to the file, including the file - // name. It should include the drive letter, when appropriate. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/home/alice/example.png", "C:\Program Files\MyApp\myapp.exe" - FilePathKey = attribute.Key("file.path") - - // FileSizeKey is the attribute Key conforming to the "file.size" semantic - // conventions. It represents the file size in bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - FileSizeKey = attribute.Key("file.size") - - // FileSymbolicLinkTargetPathKey is the attribute Key conforming to the - // "file.symbolic_link.target_path" semantic conventions. It represents the path - // to the target of a symbolic link. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/usr/bin/python3" - // Note: This attribute is only applicable to symbolic links. - FileSymbolicLinkTargetPathKey = attribute.Key("file.symbolic_link.target_path") -) - -// FileAccessed returns an attribute KeyValue conforming to the "file.accessed" -// semantic conventions. It represents the time when the file was last accessed, -// in ISO 8601 format. -func FileAccessed(val string) attribute.KeyValue { - return FileAccessedKey.String(val) -} - -// FileAttributes returns an attribute KeyValue conforming to the -// "file.attributes" semantic conventions. It represents the array of file -// attributes. -func FileAttributes(val ...string) attribute.KeyValue { - return FileAttributesKey.StringSlice(val) -} - -// FileChanged returns an attribute KeyValue conforming to the "file.changed" -// semantic conventions. It represents the time when the file attributes or -// metadata was last changed, in ISO 8601 format. -func FileChanged(val string) attribute.KeyValue { - return FileChangedKey.String(val) -} - -// FileCreated returns an attribute KeyValue conforming to the "file.created" -// semantic conventions. It represents the time when the file was created, in ISO -// 8601 format. -func FileCreated(val string) attribute.KeyValue { - return FileCreatedKey.String(val) -} - -// FileDirectory returns an attribute KeyValue conforming to the "file.directory" -// semantic conventions. It represents the directory where the file is located. -// It should include the drive letter, when appropriate. -func FileDirectory(val string) attribute.KeyValue { - return FileDirectoryKey.String(val) -} - -// FileExtension returns an attribute KeyValue conforming to the "file.extension" -// semantic conventions. It represents the file extension, excluding the leading -// dot. -func FileExtension(val string) attribute.KeyValue { - return FileExtensionKey.String(val) -} - -// FileForkName returns an attribute KeyValue conforming to the "file.fork_name" -// semantic conventions. It represents the name of the fork. A fork is additional -// data associated with a filesystem object. -func FileForkName(val string) attribute.KeyValue { - return FileForkNameKey.String(val) -} - -// FileGroupID returns an attribute KeyValue conforming to the "file.group.id" -// semantic conventions. It represents the primary Group ID (GID) of the file. -func FileGroupID(val string) attribute.KeyValue { - return FileGroupIDKey.String(val) -} - -// FileGroupName returns an attribute KeyValue conforming to the -// "file.group.name" semantic conventions. It represents the primary group name -// of the file. -func FileGroupName(val string) attribute.KeyValue { - return FileGroupNameKey.String(val) -} - -// FileInode returns an attribute KeyValue conforming to the "file.inode" -// semantic conventions. It represents the inode representing the file in the -// filesystem. -func FileInode(val string) attribute.KeyValue { - return FileInodeKey.String(val) -} - -// FileMode returns an attribute KeyValue conforming to the "file.mode" semantic -// conventions. It represents the mode of the file in octal representation. -func FileMode(val string) attribute.KeyValue { - return FileModeKey.String(val) -} - -// FileModified returns an attribute KeyValue conforming to the "file.modified" -// semantic conventions. It represents the time when the file content was last -// modified, in ISO 8601 format. -func FileModified(val string) attribute.KeyValue { - return FileModifiedKey.String(val) -} - -// FileName returns an attribute KeyValue conforming to the "file.name" semantic -// conventions. It represents the name of the file including the extension, -// without the directory. -func FileName(val string) attribute.KeyValue { - return FileNameKey.String(val) -} - -// FileOwnerID returns an attribute KeyValue conforming to the "file.owner.id" -// semantic conventions. It represents the user ID (UID) or security identifier -// (SID) of the file owner. -func FileOwnerID(val string) attribute.KeyValue { - return FileOwnerIDKey.String(val) -} - -// FileOwnerName returns an attribute KeyValue conforming to the -// "file.owner.name" semantic conventions. It represents the username of the file -// owner. -func FileOwnerName(val string) attribute.KeyValue { - return FileOwnerNameKey.String(val) -} - -// FilePath returns an attribute KeyValue conforming to the "file.path" semantic -// conventions. It represents the full path to the file, including the file name. -// It should include the drive letter, when appropriate. -func FilePath(val string) attribute.KeyValue { - return FilePathKey.String(val) -} - -// FileSize returns an attribute KeyValue conforming to the "file.size" semantic -// conventions. It represents the file size in bytes. -func FileSize(val int) attribute.KeyValue { - return FileSizeKey.Int(val) -} - -// FileSymbolicLinkTargetPath returns an attribute KeyValue conforming to the -// "file.symbolic_link.target_path" semantic conventions. It represents the path -// to the target of a symbolic link. -func FileSymbolicLinkTargetPath(val string) attribute.KeyValue { - return FileSymbolicLinkTargetPathKey.String(val) -} - -// Namespace: gcp -const ( - // GCPClientServiceKey is the attribute Key conforming to the - // "gcp.client.service" semantic conventions. It represents the identifies the - // Google Cloud service for which the official client library is intended. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "appengine", "run", "firestore", "alloydb", "spanner" - // Note: Intended to be a stable identifier for Google Cloud client libraries - // that is uniform across implementation languages. The value should be derived - // from the canonical service domain for the service; for example, - // 'foo.googleapis.com' should result in a value of 'foo'. - GCPClientServiceKey = attribute.Key("gcp.client.service") - - // GCPCloudRunJobExecutionKey is the attribute Key conforming to the - // "gcp.cloud_run.job.execution" semantic conventions. It represents the name of - // the Cloud Run [execution] being run for the Job, as set by the - // [`CLOUD_RUN_EXECUTION`] environment variable. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "job-name-xxxx", "sample-job-mdw84" - // - // [execution]: https://cloud.google.com/run/docs/managing/job-executions - // [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars - GCPCloudRunJobExecutionKey = attribute.Key("gcp.cloud_run.job.execution") - - // GCPCloudRunJobTaskIndexKey is the attribute Key conforming to the - // "gcp.cloud_run.job.task_index" semantic conventions. It represents the index - // for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`] - // environment variable. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0, 1 - // - // [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars - GCPCloudRunJobTaskIndexKey = attribute.Key("gcp.cloud_run.job.task_index") - - // GCPGceInstanceHostnameKey is the attribute Key conforming to the - // "gcp.gce.instance.hostname" semantic conventions. It represents the hostname - // of a GCE instance. This is the full value of the default or [custom hostname] - // . - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-host1234.example.com", - // "sample-vm.us-west1-b.c.my-project.internal" - // - // [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm - GCPGceInstanceHostnameKey = attribute.Key("gcp.gce.instance.hostname") - - // GCPGceInstanceNameKey is the attribute Key conforming to the - // "gcp.gce.instance.name" semantic conventions. It represents the instance name - // of a GCE instance. This is the value provided by `host.name`, the visible - // name of the instance in the Cloud Console UI, and the prefix for the default - // hostname of the instance as defined by the [default internal DNS name]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "instance-1", "my-vm-name" - // - // [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names - GCPGceInstanceNameKey = attribute.Key("gcp.gce.instance.name") -) - -// GCPClientService returns an attribute KeyValue conforming to the -// "gcp.client.service" semantic conventions. It represents the identifies the -// Google Cloud service for which the official client library is intended. -func GCPClientService(val string) attribute.KeyValue { - return GCPClientServiceKey.String(val) -} - -// GCPCloudRunJobExecution returns an attribute KeyValue conforming to the -// "gcp.cloud_run.job.execution" semantic conventions. It represents the name of -// the Cloud Run [execution] being run for the Job, as set by the -// [`CLOUD_RUN_EXECUTION`] environment variable. -// -// [execution]: https://cloud.google.com/run/docs/managing/job-executions -// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars -func GCPCloudRunJobExecution(val string) attribute.KeyValue { - return GCPCloudRunJobExecutionKey.String(val) -} - -// GCPCloudRunJobTaskIndex returns an attribute KeyValue conforming to the -// "gcp.cloud_run.job.task_index" semantic conventions. It represents the index -// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`] -// environment variable. -// -// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars -func GCPCloudRunJobTaskIndex(val int) attribute.KeyValue { - return GCPCloudRunJobTaskIndexKey.Int(val) -} - -// GCPGceInstanceHostname returns an attribute KeyValue conforming to the -// "gcp.gce.instance.hostname" semantic conventions. It represents the hostname -// of a GCE instance. This is the full value of the default or [custom hostname] -// . -// -// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm -func GCPGceInstanceHostname(val string) attribute.KeyValue { - return GCPGceInstanceHostnameKey.String(val) -} - -// GCPGceInstanceName returns an attribute KeyValue conforming to the -// "gcp.gce.instance.name" semantic conventions. It represents the instance name -// of a GCE instance. This is the value provided by `host.name`, the visible name -// of the instance in the Cloud Console UI, and the prefix for the default -// hostname of the instance as defined by the [default internal DNS name]. -// -// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names -func GCPGceInstanceName(val string) attribute.KeyValue { - return GCPGceInstanceNameKey.String(val) -} - -// Namespace: gen_ai -const ( - // GenAIOpenaiRequestResponseFormatKey is the attribute Key conforming to the - // "gen_ai.openai.request.response_format" semantic conventions. It represents - // the response format that is requested. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "json" - GenAIOpenaiRequestResponseFormatKey = attribute.Key("gen_ai.openai.request.response_format") - - // GenAIOpenaiRequestServiceTierKey is the attribute Key conforming to the - // "gen_ai.openai.request.service_tier" semantic conventions. It represents the - // service tier requested. May be a specific tier, default, or auto. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "auto", "default" - GenAIOpenaiRequestServiceTierKey = attribute.Key("gen_ai.openai.request.service_tier") - - // GenAIOpenaiResponseServiceTierKey is the attribute Key conforming to the - // "gen_ai.openai.response.service_tier" semantic conventions. It represents the - // service tier used for the response. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "scale", "default" - GenAIOpenaiResponseServiceTierKey = attribute.Key("gen_ai.openai.response.service_tier") - - // GenAIOpenaiResponseSystemFingerprintKey is the attribute Key conforming to - // the "gen_ai.openai.response.system_fingerprint" semantic conventions. It - // represents a fingerprint to track any eventual change in the Generative AI - // environment. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "fp_44709d6fcb" - GenAIOpenaiResponseSystemFingerprintKey = attribute.Key("gen_ai.openai.response.system_fingerprint") - - // GenAIOperationNameKey is the attribute Key conforming to the - // "gen_ai.operation.name" semantic conventions. It represents the name of the - // operation being performed. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: If one of the predefined values applies, but specific system uses a - // different name it's RECOMMENDED to document it in the semantic conventions - // for specific GenAI system and use system-specific name in the - // instrumentation. If a different name is not documented, instrumentation - // libraries SHOULD use applicable predefined value. - GenAIOperationNameKey = attribute.Key("gen_ai.operation.name") - - // GenAIRequestEncodingFormatsKey is the attribute Key conforming to the - // "gen_ai.request.encoding_formats" semantic conventions. It represents the - // encoding formats requested in an embeddings operation, if specified. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "base64"], ["float", "binary" - // Note: In some GenAI systems the encoding formats are called embedding types. - // Also, some GenAI systems only accept a single format per request. - GenAIRequestEncodingFormatsKey = attribute.Key("gen_ai.request.encoding_formats") - - // GenAIRequestFrequencyPenaltyKey is the attribute Key conforming to the - // "gen_ai.request.frequency_penalty" semantic conventions. It represents the - // frequency penalty setting for the GenAI request. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0.1 - GenAIRequestFrequencyPenaltyKey = attribute.Key("gen_ai.request.frequency_penalty") - - // GenAIRequestMaxTokensKey is the attribute Key conforming to the - // "gen_ai.request.max_tokens" semantic conventions. It represents the maximum - // number of tokens the model generates for a request. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 100 - GenAIRequestMaxTokensKey = attribute.Key("gen_ai.request.max_tokens") - - // GenAIRequestModelKey is the attribute Key conforming to the - // "gen_ai.request.model" semantic conventions. It represents the name of the - // GenAI model a request is being made to. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: gpt-4 - GenAIRequestModelKey = attribute.Key("gen_ai.request.model") - - // GenAIRequestPresencePenaltyKey is the attribute Key conforming to the - // "gen_ai.request.presence_penalty" semantic conventions. It represents the - // presence penalty setting for the GenAI request. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0.1 - GenAIRequestPresencePenaltyKey = attribute.Key("gen_ai.request.presence_penalty") - - // GenAIRequestSeedKey is the attribute Key conforming to the - // "gen_ai.request.seed" semantic conventions. It represents the requests with - // same seed value more likely to return same result. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 100 - GenAIRequestSeedKey = attribute.Key("gen_ai.request.seed") - - // GenAIRequestStopSequencesKey is the attribute Key conforming to the - // "gen_ai.request.stop_sequences" semantic conventions. It represents the list - // of sequences that the model will use to stop generating further tokens. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "forest", "lived" - GenAIRequestStopSequencesKey = attribute.Key("gen_ai.request.stop_sequences") - - // GenAIRequestTemperatureKey is the attribute Key conforming to the - // "gen_ai.request.temperature" semantic conventions. It represents the - // temperature setting for the GenAI request. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0.0 - GenAIRequestTemperatureKey = attribute.Key("gen_ai.request.temperature") - - // GenAIRequestTopKKey is the attribute Key conforming to the - // "gen_ai.request.top_k" semantic conventions. It represents the top_k sampling - // setting for the GenAI request. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1.0 - GenAIRequestTopKKey = attribute.Key("gen_ai.request.top_k") - - // GenAIRequestTopPKey is the attribute Key conforming to the - // "gen_ai.request.top_p" semantic conventions. It represents the top_p sampling - // setting for the GenAI request. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1.0 - GenAIRequestTopPKey = attribute.Key("gen_ai.request.top_p") - - // GenAIResponseFinishReasonsKey is the attribute Key conforming to the - // "gen_ai.response.finish_reasons" semantic conventions. It represents the - // array of reasons the model stopped generating tokens, corresponding to each - // generation received. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "stop"], ["stop", "length" - GenAIResponseFinishReasonsKey = attribute.Key("gen_ai.response.finish_reasons") - - // GenAIResponseIDKey is the attribute Key conforming to the - // "gen_ai.response.id" semantic conventions. It represents the unique - // identifier for the completion. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "chatcmpl-123" - GenAIResponseIDKey = attribute.Key("gen_ai.response.id") - - // GenAIResponseModelKey is the attribute Key conforming to the - // "gen_ai.response.model" semantic conventions. It represents the name of the - // model that generated the response. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "gpt-4-0613" - GenAIResponseModelKey = attribute.Key("gen_ai.response.model") - - // GenAISystemKey is the attribute Key conforming to the "gen_ai.system" - // semantic conventions. It represents the Generative AI product as identified - // by the client or server instrumentation. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: openai - // Note: The `gen_ai.system` describes a family of GenAI models with specific - // model identified - // by `gen_ai.request.model` and `gen_ai.response.model` attributes. - // - // The actual GenAI product may differ from the one identified by the client. - // Multiple systems, including Azure OpenAI and Gemini, are accessible by OpenAI - // client - // libraries. In such cases, the `gen_ai.system` is set to `openai` based on the - // instrumentation's best knowledge, instead of the actual system. The - // `server.address` - // attribute may help identify the actual system in use for `openai`. - // - // For custom model, a custom friendly name SHOULD be used. - // If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER` - // . - GenAISystemKey = attribute.Key("gen_ai.system") - - // GenAITokenTypeKey is the attribute Key conforming to the "gen_ai.token.type" - // semantic conventions. It represents the type of token being counted. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "input", "output" - GenAITokenTypeKey = attribute.Key("gen_ai.token.type") - - // GenAIUsageInputTokensKey is the attribute Key conforming to the - // "gen_ai.usage.input_tokens" semantic conventions. It represents the number of - // tokens used in the GenAI input (prompt). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 100 - GenAIUsageInputTokensKey = attribute.Key("gen_ai.usage.input_tokens") - - // GenAIUsageOutputTokensKey is the attribute Key conforming to the - // "gen_ai.usage.output_tokens" semantic conventions. It represents the number - // of tokens used in the GenAI response (completion). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 180 - GenAIUsageOutputTokensKey = attribute.Key("gen_ai.usage.output_tokens") -) - -// GenAIOpenaiResponseServiceTier returns an attribute KeyValue conforming to the -// "gen_ai.openai.response.service_tier" semantic conventions. It represents the -// service tier used for the response. -func GenAIOpenaiResponseServiceTier(val string) attribute.KeyValue { - return GenAIOpenaiResponseServiceTierKey.String(val) -} - -// GenAIOpenaiResponseSystemFingerprint returns an attribute KeyValue conforming -// to the "gen_ai.openai.response.system_fingerprint" semantic conventions. It -// represents a fingerprint to track any eventual change in the Generative AI -// environment. -func GenAIOpenaiResponseSystemFingerprint(val string) attribute.KeyValue { - return GenAIOpenaiResponseSystemFingerprintKey.String(val) -} - -// GenAIRequestEncodingFormats returns an attribute KeyValue conforming to the -// "gen_ai.request.encoding_formats" semantic conventions. It represents the -// encoding formats requested in an embeddings operation, if specified. -func GenAIRequestEncodingFormats(val ...string) attribute.KeyValue { - return GenAIRequestEncodingFormatsKey.StringSlice(val) -} - -// GenAIRequestFrequencyPenalty returns an attribute KeyValue conforming to the -// "gen_ai.request.frequency_penalty" semantic conventions. It represents the -// frequency penalty setting for the GenAI request. -func GenAIRequestFrequencyPenalty(val float64) attribute.KeyValue { - return GenAIRequestFrequencyPenaltyKey.Float64(val) -} - -// GenAIRequestMaxTokens returns an attribute KeyValue conforming to the -// "gen_ai.request.max_tokens" semantic conventions. It represents the maximum -// number of tokens the model generates for a request. -func GenAIRequestMaxTokens(val int) attribute.KeyValue { - return GenAIRequestMaxTokensKey.Int(val) -} - -// GenAIRequestModel returns an attribute KeyValue conforming to the -// "gen_ai.request.model" semantic conventions. It represents the name of the -// GenAI model a request is being made to. -func GenAIRequestModel(val string) attribute.KeyValue { - return GenAIRequestModelKey.String(val) -} - -// GenAIRequestPresencePenalty returns an attribute KeyValue conforming to the -// "gen_ai.request.presence_penalty" semantic conventions. It represents the -// presence penalty setting for the GenAI request. -func GenAIRequestPresencePenalty(val float64) attribute.KeyValue { - return GenAIRequestPresencePenaltyKey.Float64(val) -} - -// GenAIRequestSeed returns an attribute KeyValue conforming to the -// "gen_ai.request.seed" semantic conventions. It represents the requests with -// same seed value more likely to return same result. -func GenAIRequestSeed(val int) attribute.KeyValue { - return GenAIRequestSeedKey.Int(val) -} - -// GenAIRequestStopSequences returns an attribute KeyValue conforming to the -// "gen_ai.request.stop_sequences" semantic conventions. It represents the list -// of sequences that the model will use to stop generating further tokens. -func GenAIRequestStopSequences(val ...string) attribute.KeyValue { - return GenAIRequestStopSequencesKey.StringSlice(val) -} - -// GenAIRequestTemperature returns an attribute KeyValue conforming to the -// "gen_ai.request.temperature" semantic conventions. It represents the -// temperature setting for the GenAI request. -func GenAIRequestTemperature(val float64) attribute.KeyValue { - return GenAIRequestTemperatureKey.Float64(val) -} - -// GenAIRequestTopK returns an attribute KeyValue conforming to the -// "gen_ai.request.top_k" semantic conventions. It represents the top_k sampling -// setting for the GenAI request. -func GenAIRequestTopK(val float64) attribute.KeyValue { - return GenAIRequestTopKKey.Float64(val) -} - -// GenAIRequestTopP returns an attribute KeyValue conforming to the -// "gen_ai.request.top_p" semantic conventions. It represents the top_p sampling -// setting for the GenAI request. -func GenAIRequestTopP(val float64) attribute.KeyValue { - return GenAIRequestTopPKey.Float64(val) -} - -// GenAIResponseFinishReasons returns an attribute KeyValue conforming to the -// "gen_ai.response.finish_reasons" semantic conventions. It represents the array -// of reasons the model stopped generating tokens, corresponding to each -// generation received. -func GenAIResponseFinishReasons(val ...string) attribute.KeyValue { - return GenAIResponseFinishReasonsKey.StringSlice(val) -} - -// GenAIResponseID returns an attribute KeyValue conforming to the -// "gen_ai.response.id" semantic conventions. It represents the unique identifier -// for the completion. -func GenAIResponseID(val string) attribute.KeyValue { - return GenAIResponseIDKey.String(val) -} - -// GenAIResponseModel returns an attribute KeyValue conforming to the -// "gen_ai.response.model" semantic conventions. It represents the name of the -// model that generated the response. -func GenAIResponseModel(val string) attribute.KeyValue { - return GenAIResponseModelKey.String(val) -} - -// GenAIUsageInputTokens returns an attribute KeyValue conforming to the -// "gen_ai.usage.input_tokens" semantic conventions. It represents the number of -// tokens used in the GenAI input (prompt). -func GenAIUsageInputTokens(val int) attribute.KeyValue { - return GenAIUsageInputTokensKey.Int(val) -} - -// GenAIUsageOutputTokens returns an attribute KeyValue conforming to the -// "gen_ai.usage.output_tokens" semantic conventions. It represents the number of -// tokens used in the GenAI response (completion). -func GenAIUsageOutputTokens(val int) attribute.KeyValue { - return GenAIUsageOutputTokensKey.Int(val) -} - -// Enum values for gen_ai.openai.request.response_format -var ( - // Text response format - // Stability: development - GenAIOpenaiRequestResponseFormatText = GenAIOpenaiRequestResponseFormatKey.String("text") - // JSON object response format - // Stability: development - GenAIOpenaiRequestResponseFormatJSONObject = GenAIOpenaiRequestResponseFormatKey.String("json_object") - // JSON schema response format - // Stability: development - GenAIOpenaiRequestResponseFormatJSONSchema = GenAIOpenaiRequestResponseFormatKey.String("json_schema") -) - -// Enum values for gen_ai.openai.request.service_tier -var ( - // The system will utilize scale tier credits until they are exhausted. - // Stability: development - GenAIOpenaiRequestServiceTierAuto = GenAIOpenaiRequestServiceTierKey.String("auto") - // The system will utilize the default scale tier. - // Stability: development - GenAIOpenaiRequestServiceTierDefault = GenAIOpenaiRequestServiceTierKey.String("default") -) - -// Enum values for gen_ai.operation.name -var ( - // Chat completion operation such as [OpenAI Chat API] - // Stability: development - // - // [OpenAI Chat API]: https://platform.openai.com/docs/api-reference/chat - GenAIOperationNameChat = GenAIOperationNameKey.String("chat") - // Text completions operation such as [OpenAI Completions API (Legacy)] - // Stability: development - // - // [OpenAI Completions API (Legacy)]: https://platform.openai.com/docs/api-reference/completions - GenAIOperationNameTextCompletion = GenAIOperationNameKey.String("text_completion") - // Embeddings operation such as [OpenAI Create embeddings API] - // Stability: development - // - // [OpenAI Create embeddings API]: https://platform.openai.com/docs/api-reference/embeddings/create - GenAIOperationNameEmbeddings = GenAIOperationNameKey.String("embeddings") -) - -// Enum values for gen_ai.system -var ( - // OpenAI - // Stability: development - GenAISystemOpenai = GenAISystemKey.String("openai") - // Vertex AI - // Stability: development - GenAISystemVertexAI = GenAISystemKey.String("vertex_ai") - // Gemini - // Stability: development - GenAISystemGemini = GenAISystemKey.String("gemini") - // Anthropic - // Stability: development - GenAISystemAnthropic = GenAISystemKey.String("anthropic") - // Cohere - // Stability: development - GenAISystemCohere = GenAISystemKey.String("cohere") - // Azure AI Inference - // Stability: development - GenAISystemAzAIInference = GenAISystemKey.String("az.ai.inference") - // Azure OpenAI - // Stability: development - GenAISystemAzAIOpenai = GenAISystemKey.String("az.ai.openai") - // IBM Watsonx AI - // Stability: development - GenAISystemIbmWatsonxAI = GenAISystemKey.String("ibm.watsonx.ai") - // AWS Bedrock - // Stability: development - GenAISystemAWSBedrock = GenAISystemKey.String("aws.bedrock") - // Perplexity - // Stability: development - GenAISystemPerplexity = GenAISystemKey.String("perplexity") - // xAI - // Stability: development - GenAISystemXai = GenAISystemKey.String("xai") - // DeepSeek - // Stability: development - GenAISystemDeepseek = GenAISystemKey.String("deepseek") - // Groq - // Stability: development - GenAISystemGroq = GenAISystemKey.String("groq") - // Mistral AI - // Stability: development - GenAISystemMistralAI = GenAISystemKey.String("mistral_ai") -) - -// Enum values for gen_ai.token.type -var ( - // Input tokens (prompt, input, etc.) - // Stability: development - GenAITokenTypeInput = GenAITokenTypeKey.String("input") - // Output tokens (completion, response, etc.) - // Stability: development - GenAITokenTypeCompletion = GenAITokenTypeKey.String("output") -) - -// Namespace: geo -const ( - // GeoContinentCodeKey is the attribute Key conforming to the - // "geo.continent.code" semantic conventions. It represents the two-letter code - // representing continent’s name. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - GeoContinentCodeKey = attribute.Key("geo.continent.code") - - // GeoCountryIsoCodeKey is the attribute Key conforming to the - // "geo.country.iso_code" semantic conventions. It represents the two-letter ISO - // Country Code ([ISO 3166-1 alpha2]). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "CA" - // - // [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes - GeoCountryIsoCodeKey = attribute.Key("geo.country.iso_code") - - // GeoLocalityNameKey is the attribute Key conforming to the "geo.locality.name" - // semantic conventions. It represents the locality name. Represents the name of - // a city, town, village, or similar populated place. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Montreal", "Berlin" - GeoLocalityNameKey = attribute.Key("geo.locality.name") - - // GeoLocationLatKey is the attribute Key conforming to the "geo.location.lat" - // semantic conventions. It represents the latitude of the geo location in - // [WGS84]. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 45.505918 - // - // [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84 - GeoLocationLatKey = attribute.Key("geo.location.lat") - - // GeoLocationLonKey is the attribute Key conforming to the "geo.location.lon" - // semantic conventions. It represents the longitude of the geo location in - // [WGS84]. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: -73.61483 - // - // [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84 - GeoLocationLonKey = attribute.Key("geo.location.lon") - - // GeoPostalCodeKey is the attribute Key conforming to the "geo.postal_code" - // semantic conventions. It represents the postal code associated with the - // location. Values appropriate for this field may also be known as a postcode - // or ZIP code and will vary widely from country to country. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "94040" - GeoPostalCodeKey = attribute.Key("geo.postal_code") - - // GeoRegionIsoCodeKey is the attribute Key conforming to the - // "geo.region.iso_code" semantic conventions. It represents the region ISO code - // ([ISO 3166-2]). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "CA-QC" - // - // [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2 - GeoRegionIsoCodeKey = attribute.Key("geo.region.iso_code") -) - -// GeoCountryIsoCode returns an attribute KeyValue conforming to the -// "geo.country.iso_code" semantic conventions. It represents the two-letter ISO -// Country Code ([ISO 3166-1 alpha2]). -// -// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes -func GeoCountryIsoCode(val string) attribute.KeyValue { - return GeoCountryIsoCodeKey.String(val) -} - -// GeoLocalityName returns an attribute KeyValue conforming to the -// "geo.locality.name" semantic conventions. It represents the locality name. -// Represents the name of a city, town, village, or similar populated place. -func GeoLocalityName(val string) attribute.KeyValue { - return GeoLocalityNameKey.String(val) -} - -// GeoLocationLat returns an attribute KeyValue conforming to the -// "geo.location.lat" semantic conventions. It represents the latitude of the geo -// location in [WGS84]. -// -// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84 -func GeoLocationLat(val float64) attribute.KeyValue { - return GeoLocationLatKey.Float64(val) -} - -// GeoLocationLon returns an attribute KeyValue conforming to the -// "geo.location.lon" semantic conventions. It represents the longitude of the -// geo location in [WGS84]. -// -// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84 -func GeoLocationLon(val float64) attribute.KeyValue { - return GeoLocationLonKey.Float64(val) -} - -// GeoPostalCode returns an attribute KeyValue conforming to the -// "geo.postal_code" semantic conventions. It represents the postal code -// associated with the location. Values appropriate for this field may also be -// known as a postcode or ZIP code and will vary widely from country to country. -func GeoPostalCode(val string) attribute.KeyValue { - return GeoPostalCodeKey.String(val) -} - -// GeoRegionIsoCode returns an attribute KeyValue conforming to the -// "geo.region.iso_code" semantic conventions. It represents the region ISO code -// ([ISO 3166-2]). -// -// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2 -func GeoRegionIsoCode(val string) attribute.KeyValue { - return GeoRegionIsoCodeKey.String(val) -} - -// Enum values for geo.continent.code -var ( - // Africa - // Stability: development - GeoContinentCodeAf = GeoContinentCodeKey.String("AF") - // Antarctica - // Stability: development - GeoContinentCodeAn = GeoContinentCodeKey.String("AN") - // Asia - // Stability: development - GeoContinentCodeAs = GeoContinentCodeKey.String("AS") - // Europe - // Stability: development - GeoContinentCodeEu = GeoContinentCodeKey.String("EU") - // North America - // Stability: development - GeoContinentCodeNa = GeoContinentCodeKey.String("NA") - // Oceania - // Stability: development - GeoContinentCodeOc = GeoContinentCodeKey.String("OC") - // South America - // Stability: development - GeoContinentCodeSa = GeoContinentCodeKey.String("SA") -) - -// Namespace: go -const ( - // GoMemoryTypeKey is the attribute Key conforming to the "go.memory.type" - // semantic conventions. It represents the type of memory. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "other", "stack" - GoMemoryTypeKey = attribute.Key("go.memory.type") -) - -// Enum values for go.memory.type -var ( - // Memory allocated from the heap that is reserved for stack space, whether or - // not it is currently in-use. - // Stability: development - GoMemoryTypeStack = GoMemoryTypeKey.String("stack") - // Memory used by the Go runtime, excluding other categories of memory usage - // described in this enumeration. - // Stability: development - GoMemoryTypeOther = GoMemoryTypeKey.String("other") -) - -// Namespace: graphql -const ( - // GraphqlDocumentKey is the attribute Key conforming to the "graphql.document" - // semantic conventions. It represents the GraphQL document being executed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: query findBookById { bookById(id: ?) { name } } - // Note: The value may be sanitized to exclude sensitive information. - GraphqlDocumentKey = attribute.Key("graphql.document") - - // GraphqlOperationNameKey is the attribute Key conforming to the - // "graphql.operation.name" semantic conventions. It represents the name of the - // operation being executed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: findBookById - GraphqlOperationNameKey = attribute.Key("graphql.operation.name") - - // GraphqlOperationTypeKey is the attribute Key conforming to the - // "graphql.operation.type" semantic conventions. It represents the type of the - // operation being executed. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "query", "mutation", "subscription" - GraphqlOperationTypeKey = attribute.Key("graphql.operation.type") -) - -// GraphqlDocument returns an attribute KeyValue conforming to the -// "graphql.document" semantic conventions. It represents the GraphQL document -// being executed. -func GraphqlDocument(val string) attribute.KeyValue { - return GraphqlDocumentKey.String(val) -} - -// GraphqlOperationName returns an attribute KeyValue conforming to the -// "graphql.operation.name" semantic conventions. It represents the name of the -// operation being executed. -func GraphqlOperationName(val string) attribute.KeyValue { - return GraphqlOperationNameKey.String(val) -} - -// Enum values for graphql.operation.type -var ( - // GraphQL query - // Stability: development - GraphqlOperationTypeQuery = GraphqlOperationTypeKey.String("query") - // GraphQL mutation - // Stability: development - GraphqlOperationTypeMutation = GraphqlOperationTypeKey.String("mutation") - // GraphQL subscription - // Stability: development - GraphqlOperationTypeSubscription = GraphqlOperationTypeKey.String("subscription") -) - -// Namespace: heroku -const ( - // HerokuAppIDKey is the attribute Key conforming to the "heroku.app.id" - // semantic conventions. It represents the unique identifier for the - // application. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2daa2797-e42b-4624-9322-ec3f968df4da" - HerokuAppIDKey = attribute.Key("heroku.app.id") - - // HerokuReleaseCommitKey is the attribute Key conforming to the - // "heroku.release.commit" semantic conventions. It represents the commit hash - // for the current release. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "e6134959463efd8966b20e75b913cafe3f5ec" - HerokuReleaseCommitKey = attribute.Key("heroku.release.commit") - - // HerokuReleaseCreationTimestampKey is the attribute Key conforming to the - // "heroku.release.creation_timestamp" semantic conventions. It represents the - // time and date the release was created. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2022-10-23T18:00:42Z" - HerokuReleaseCreationTimestampKey = attribute.Key("heroku.release.creation_timestamp") -) - -// HerokuAppID returns an attribute KeyValue conforming to the "heroku.app.id" -// semantic conventions. It represents the unique identifier for the application. -func HerokuAppID(val string) attribute.KeyValue { - return HerokuAppIDKey.String(val) -} - -// HerokuReleaseCommit returns an attribute KeyValue conforming to the -// "heroku.release.commit" semantic conventions. It represents the commit hash -// for the current release. -func HerokuReleaseCommit(val string) attribute.KeyValue { - return HerokuReleaseCommitKey.String(val) -} - -// HerokuReleaseCreationTimestamp returns an attribute KeyValue conforming to the -// "heroku.release.creation_timestamp" semantic conventions. It represents the -// time and date the release was created. -func HerokuReleaseCreationTimestamp(val string) attribute.KeyValue { - return HerokuReleaseCreationTimestampKey.String(val) -} - -// Namespace: host -const ( - // HostArchKey is the attribute Key conforming to the "host.arch" semantic - // conventions. It represents the CPU architecture the host system is running - // on. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - HostArchKey = attribute.Key("host.arch") - - // HostCPUCacheL2SizeKey is the attribute Key conforming to the - // "host.cpu.cache.l2.size" semantic conventions. It represents the amount of - // level 2 memory cache available to the processor (in Bytes). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 12288000 - HostCPUCacheL2SizeKey = attribute.Key("host.cpu.cache.l2.size") - - // HostCPUFamilyKey is the attribute Key conforming to the "host.cpu.family" - // semantic conventions. It represents the family or generation of the CPU. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "6", "PA-RISC 1.1e" - HostCPUFamilyKey = attribute.Key("host.cpu.family") - - // HostCPUModelIDKey is the attribute Key conforming to the "host.cpu.model.id" - // semantic conventions. It represents the model identifier. It provides more - // granular information about the CPU, distinguishing it from other CPUs within - // the same family. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "6", "9000/778/B180L" - HostCPUModelIDKey = attribute.Key("host.cpu.model.id") - - // HostCPUModelNameKey is the attribute Key conforming to the - // "host.cpu.model.name" semantic conventions. It represents the model - // designation of the processor. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz" - HostCPUModelNameKey = attribute.Key("host.cpu.model.name") - - // HostCPUSteppingKey is the attribute Key conforming to the "host.cpu.stepping" - // semantic conventions. It represents the stepping or core revisions. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1", "r1p1" - HostCPUSteppingKey = attribute.Key("host.cpu.stepping") - - // HostCPUVendorIDKey is the attribute Key conforming to the - // "host.cpu.vendor.id" semantic conventions. It represents the processor - // manufacturer identifier. A maximum 12-character string. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "GenuineIntel" - // Note: [CPUID] command returns the vendor ID string in EBX, EDX and ECX - // registers. Writing these to memory in this order results in a 12-character - // string. - // - // [CPUID]: https://wiki.osdev.org/CPUID - HostCPUVendorIDKey = attribute.Key("host.cpu.vendor.id") - - // HostIDKey is the attribute Key conforming to the "host.id" semantic - // conventions. It represents the unique host ID. For Cloud, this must be the - // instance_id assigned by the cloud provider. For non-containerized systems, - // this should be the `machine-id`. See the table below for the sources to use - // to determine the `machine-id` based on operating system. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "fdbf79e8af94cb7f9e8df36789187052" - HostIDKey = attribute.Key("host.id") - - // HostImageIDKey is the attribute Key conforming to the "host.image.id" - // semantic conventions. It represents the vM image ID or host OS image ID. For - // Cloud, this value is from the provider. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "ami-07b06b442921831e5" - HostImageIDKey = attribute.Key("host.image.id") - - // HostImageNameKey is the attribute Key conforming to the "host.image.name" - // semantic conventions. It represents the name of the VM image or OS install - // the host was instantiated from. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "infra-ami-eks-worker-node-7d4ec78312", "CentOS-8-x86_64-1905" - HostImageNameKey = attribute.Key("host.image.name") - - // HostImageVersionKey is the attribute Key conforming to the - // "host.image.version" semantic conventions. It represents the version string - // of the VM image or host OS as defined in [Version Attributes]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0.1" - // - // [Version Attributes]: /docs/resource/README.md#version-attributes - HostImageVersionKey = attribute.Key("host.image.version") - - // HostIPKey is the attribute Key conforming to the "host.ip" semantic - // conventions. It represents the available IP addresses of the host, excluding - // loopback interfaces. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "192.168.1.140", "fe80::abc2:4a28:737a:609e" - // Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 - // addresses MUST be specified in the [RFC 5952] format. - // - // [RFC 5952]: https://www.rfc-editor.org/rfc/rfc5952.html - HostIPKey = attribute.Key("host.ip") - - // HostMacKey is the attribute Key conforming to the "host.mac" semantic - // conventions. It represents the available MAC addresses of the host, excluding - // loopback interfaces. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "AC-DE-48-23-45-67", "AC-DE-48-23-45-67-01-9F" - // Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form]: as - // hyphen-separated octets in uppercase hexadecimal form from most to least - // significant. - // - // [IEEE RA hexadecimal form]: https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf - HostMacKey = attribute.Key("host.mac") - - // HostNameKey is the attribute Key conforming to the "host.name" semantic - // conventions. It represents the name of the host. On Unix systems, it may - // contain what the hostname command returns, or the fully qualified hostname, - // or another name specified by the user. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry-test" - HostNameKey = attribute.Key("host.name") - - // HostTypeKey is the attribute Key conforming to the "host.type" semantic - // conventions. It represents the type of host. For Cloud, this must be the - // machine type. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "n1-standard-1" - HostTypeKey = attribute.Key("host.type") -) - -// HostCPUCacheL2Size returns an attribute KeyValue conforming to the -// "host.cpu.cache.l2.size" semantic conventions. It represents the amount of -// level 2 memory cache available to the processor (in Bytes). -func HostCPUCacheL2Size(val int) attribute.KeyValue { - return HostCPUCacheL2SizeKey.Int(val) -} - -// HostCPUFamily returns an attribute KeyValue conforming to the -// "host.cpu.family" semantic conventions. It represents the family or generation -// of the CPU. -func HostCPUFamily(val string) attribute.KeyValue { - return HostCPUFamilyKey.String(val) -} - -// HostCPUModelID returns an attribute KeyValue conforming to the -// "host.cpu.model.id" semantic conventions. It represents the model identifier. -// It provides more granular information about the CPU, distinguishing it from -// other CPUs within the same family. -func HostCPUModelID(val string) attribute.KeyValue { - return HostCPUModelIDKey.String(val) -} - -// HostCPUModelName returns an attribute KeyValue conforming to the -// "host.cpu.model.name" semantic conventions. It represents the model -// designation of the processor. -func HostCPUModelName(val string) attribute.KeyValue { - return HostCPUModelNameKey.String(val) -} - -// HostCPUStepping returns an attribute KeyValue conforming to the -// "host.cpu.stepping" semantic conventions. It represents the stepping or core -// revisions. -func HostCPUStepping(val string) attribute.KeyValue { - return HostCPUSteppingKey.String(val) -} - -// HostCPUVendorID returns an attribute KeyValue conforming to the -// "host.cpu.vendor.id" semantic conventions. It represents the processor -// manufacturer identifier. A maximum 12-character string. -func HostCPUVendorID(val string) attribute.KeyValue { - return HostCPUVendorIDKey.String(val) -} - -// HostID returns an attribute KeyValue conforming to the "host.id" semantic -// conventions. It represents the unique host ID. For Cloud, this must be the -// instance_id assigned by the cloud provider. For non-containerized systems, -// this should be the `machine-id`. See the table below for the sources to use to -// determine the `machine-id` based on operating system. -func HostID(val string) attribute.KeyValue { - return HostIDKey.String(val) -} - -// HostImageID returns an attribute KeyValue conforming to the "host.image.id" -// semantic conventions. It represents the vM image ID or host OS image ID. For -// Cloud, this value is from the provider. -func HostImageID(val string) attribute.KeyValue { - return HostImageIDKey.String(val) -} - -// HostImageName returns an attribute KeyValue conforming to the -// "host.image.name" semantic conventions. It represents the name of the VM image -// or OS install the host was instantiated from. -func HostImageName(val string) attribute.KeyValue { - return HostImageNameKey.String(val) -} - -// HostImageVersion returns an attribute KeyValue conforming to the -// "host.image.version" semantic conventions. It represents the version string of -// the VM image or host OS as defined in [Version Attributes]. -// -// [Version Attributes]: /docs/resource/README.md#version-attributes -func HostImageVersion(val string) attribute.KeyValue { - return HostImageVersionKey.String(val) -} - -// HostIP returns an attribute KeyValue conforming to the "host.ip" semantic -// conventions. It represents the available IP addresses of the host, excluding -// loopback interfaces. -func HostIP(val ...string) attribute.KeyValue { - return HostIPKey.StringSlice(val) -} - -// HostMac returns an attribute KeyValue conforming to the "host.mac" semantic -// conventions. It represents the available MAC addresses of the host, excluding -// loopback interfaces. -func HostMac(val ...string) attribute.KeyValue { - return HostMacKey.StringSlice(val) -} - -// HostName returns an attribute KeyValue conforming to the "host.name" semantic -// conventions. It represents the name of the host. On Unix systems, it may -// contain what the hostname command returns, or the fully qualified hostname, or -// another name specified by the user. -func HostName(val string) attribute.KeyValue { - return HostNameKey.String(val) -} - -// HostType returns an attribute KeyValue conforming to the "host.type" semantic -// conventions. It represents the type of host. For Cloud, this must be the -// machine type. -func HostType(val string) attribute.KeyValue { - return HostTypeKey.String(val) -} - -// Enum values for host.arch -var ( - // AMD64 - // Stability: development - HostArchAMD64 = HostArchKey.String("amd64") - // ARM32 - // Stability: development - HostArchARM32 = HostArchKey.String("arm32") - // ARM64 - // Stability: development - HostArchARM64 = HostArchKey.String("arm64") - // Itanium - // Stability: development - HostArchIA64 = HostArchKey.String("ia64") - // 32-bit PowerPC - // Stability: development - HostArchPPC32 = HostArchKey.String("ppc32") - // 64-bit PowerPC - // Stability: development - HostArchPPC64 = HostArchKey.String("ppc64") - // IBM z/Architecture - // Stability: development - HostArchS390x = HostArchKey.String("s390x") - // 32-bit x86 - // Stability: development - HostArchX86 = HostArchKey.String("x86") -) - -// Namespace: http -const ( - // HTTPConnectionStateKey is the attribute Key conforming to the - // "http.connection.state" semantic conventions. It represents the state of the - // HTTP connection in the HTTP connection pool. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "active", "idle" - HTTPConnectionStateKey = attribute.Key("http.connection.state") - - // HTTPRequestBodySizeKey is the attribute Key conforming to the - // "http.request.body.size" semantic conventions. It represents the size of the - // request payload body in bytes. This is the number of bytes transferred - // excluding headers and is often, but not always, present as the - // [Content-Length] header. For requests using transport encoding, this should - // be the compressed size. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length - HTTPRequestBodySizeKey = attribute.Key("http.request.body.size") - - // HTTPRequestMethodKey is the attribute Key conforming to the - // "http.request.method" semantic conventions. It represents the hTTP request - // method. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "GET", "POST", "HEAD" - // Note: HTTP request method value SHOULD be "known" to the instrumentation. - // By default, this convention defines "known" methods as the ones listed in - // [RFC9110] - // and the PATCH method defined in [RFC5789]. - // - // If the HTTP request method is not known to instrumentation, it MUST set the - // `http.request.method` attribute to `_OTHER`. - // - // If the HTTP instrumentation could end up converting valid HTTP request - // methods to `_OTHER`, then it MUST provide a way to override - // the list of known HTTP methods. If this override is done via environment - // variable, then the environment variable MUST be named - // OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of - // case-sensitive known HTTP methods - // (this list MUST be a full override of the default known method, it is not a - // list of known methods in addition to the defaults). - // - // HTTP method names are case-sensitive and `http.request.method` attribute - // value MUST match a known HTTP method name exactly. - // Instrumentations for specific web frameworks that consider HTTP methods to be - // case insensitive, SHOULD populate a canonical equivalent. - // Tracing instrumentations that do so, MUST also set - // `http.request.method_original` to the original value. - // - // [RFC9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-methods - // [RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html - HTTPRequestMethodKey = attribute.Key("http.request.method") - - // HTTPRequestMethodOriginalKey is the attribute Key conforming to the - // "http.request.method_original" semantic conventions. It represents the - // original HTTP method sent by the client in the request line. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "GeT", "ACL", "foo" - HTTPRequestMethodOriginalKey = attribute.Key("http.request.method_original") - - // HTTPRequestResendCountKey is the attribute Key conforming to the - // "http.request.resend_count" semantic conventions. It represents the ordinal - // number of request resending attempt (for any reason, including redirects). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Stable - // - // Note: The resend count SHOULD be updated each time an HTTP request gets - // resent by the client, regardless of what was the cause of the resending (e.g. - // redirection, authorization failure, 503 Server Unavailable, network issues, - // or any other). - HTTPRequestResendCountKey = attribute.Key("http.request.resend_count") - - // HTTPRequestSizeKey is the attribute Key conforming to the "http.request.size" - // semantic conventions. It represents the total size of the request in bytes. - // This should be the total number of bytes sent over the wire, including the - // request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request - // body if any. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - HTTPRequestSizeKey = attribute.Key("http.request.size") - - // HTTPResponseBodySizeKey is the attribute Key conforming to the - // "http.response.body.size" semantic conventions. It represents the size of the - // response payload body in bytes. This is the number of bytes transferred - // excluding headers and is often, but not always, present as the - // [Content-Length] header. For requests using transport encoding, this should - // be the compressed size. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length - HTTPResponseBodySizeKey = attribute.Key("http.response.body.size") - - // HTTPResponseSizeKey is the attribute Key conforming to the - // "http.response.size" semantic conventions. It represents the total size of - // the response in bytes. This should be the total number of bytes sent over the - // wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), - // headers, and response body and trailers if any. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - HTTPResponseSizeKey = attribute.Key("http.response.size") - - // HTTPResponseStatusCodeKey is the attribute Key conforming to the - // "http.response.status_code" semantic conventions. It represents the - // [HTTP response status code]. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: 200 - // - // [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 - HTTPResponseStatusCodeKey = attribute.Key("http.response.status_code") - - // HTTPRouteKey is the attribute Key conforming to the "http.route" semantic - // conventions. It represents the matched route, that is, the path template in - // the format used by the respective server framework. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "/users/:userID?", "{controller}/{action}/{id?}" - // Note: MUST NOT be populated when this is not supported by the HTTP server - // framework as the route attribute should have low-cardinality and the URI path - // can NOT substitute it. - // SHOULD include the [application root] if there is one. - // - // [application root]: /docs/http/http-spans.md#http-server-definitions - HTTPRouteKey = attribute.Key("http.route") -) - -// HTTPRequestBodySize returns an attribute KeyValue conforming to the -// "http.request.body.size" semantic conventions. It represents the size of the -// request payload body in bytes. This is the number of bytes transferred -// excluding headers and is often, but not always, present as the -// [Content-Length] header. For requests using transport encoding, this should be -// the compressed size. -// -// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length -func HTTPRequestBodySize(val int) attribute.KeyValue { - return HTTPRequestBodySizeKey.Int(val) -} - -// HTTPRequestMethodOriginal returns an attribute KeyValue conforming to the -// "http.request.method_original" semantic conventions. It represents the -// original HTTP method sent by the client in the request line. -func HTTPRequestMethodOriginal(val string) attribute.KeyValue { - return HTTPRequestMethodOriginalKey.String(val) -} - -// HTTPRequestResendCount returns an attribute KeyValue conforming to the -// "http.request.resend_count" semantic conventions. It represents the ordinal -// number of request resending attempt (for any reason, including redirects). -func HTTPRequestResendCount(val int) attribute.KeyValue { - return HTTPRequestResendCountKey.Int(val) -} - -// HTTPRequestSize returns an attribute KeyValue conforming to the -// "http.request.size" semantic conventions. It represents the total size of the -// request in bytes. This should be the total number of bytes sent over the wire, -// including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, -// and request body if any. -func HTTPRequestSize(val int) attribute.KeyValue { - return HTTPRequestSizeKey.Int(val) -} - -// HTTPResponseBodySize returns an attribute KeyValue conforming to the -// "http.response.body.size" semantic conventions. It represents the size of the -// response payload body in bytes. This is the number of bytes transferred -// excluding headers and is often, but not always, present as the -// [Content-Length] header. For requests using transport encoding, this should be -// the compressed size. -// -// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length -func HTTPResponseBodySize(val int) attribute.KeyValue { - return HTTPResponseBodySizeKey.Int(val) -} - -// HTTPResponseSize returns an attribute KeyValue conforming to the -// "http.response.size" semantic conventions. It represents the total size of the -// response in bytes. This should be the total number of bytes sent over the -// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), -// headers, and response body and trailers if any. -func HTTPResponseSize(val int) attribute.KeyValue { - return HTTPResponseSizeKey.Int(val) -} - -// HTTPResponseStatusCode returns an attribute KeyValue conforming to the -// "http.response.status_code" semantic conventions. It represents the -// [HTTP response status code]. -// -// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 -func HTTPResponseStatusCode(val int) attribute.KeyValue { - return HTTPResponseStatusCodeKey.Int(val) -} - -// HTTPRoute returns an attribute KeyValue conforming to the "http.route" -// semantic conventions. It represents the matched route, that is, the path -// template in the format used by the respective server framework. -func HTTPRoute(val string) attribute.KeyValue { - return HTTPRouteKey.String(val) -} - -// Enum values for http.connection.state -var ( - // active state. - // Stability: development - HTTPConnectionStateActive = HTTPConnectionStateKey.String("active") - // idle state. - // Stability: development - HTTPConnectionStateIdle = HTTPConnectionStateKey.String("idle") -) - -// Enum values for http.request.method -var ( - // CONNECT method. - // Stability: stable - HTTPRequestMethodConnect = HTTPRequestMethodKey.String("CONNECT") - // DELETE method. - // Stability: stable - HTTPRequestMethodDelete = HTTPRequestMethodKey.String("DELETE") - // GET method. - // Stability: stable - HTTPRequestMethodGet = HTTPRequestMethodKey.String("GET") - // HEAD method. - // Stability: stable - HTTPRequestMethodHead = HTTPRequestMethodKey.String("HEAD") - // OPTIONS method. - // Stability: stable - HTTPRequestMethodOptions = HTTPRequestMethodKey.String("OPTIONS") - // PATCH method. - // Stability: stable - HTTPRequestMethodPatch = HTTPRequestMethodKey.String("PATCH") - // POST method. - // Stability: stable - HTTPRequestMethodPost = HTTPRequestMethodKey.String("POST") - // PUT method. - // Stability: stable - HTTPRequestMethodPut = HTTPRequestMethodKey.String("PUT") - // TRACE method. - // Stability: stable - HTTPRequestMethodTrace = HTTPRequestMethodKey.String("TRACE") - // Any HTTP method that the instrumentation has no prior knowledge of. - // Stability: stable - HTTPRequestMethodOther = HTTPRequestMethodKey.String("_OTHER") -) - -// Namespace: hw -const ( - // HwIDKey is the attribute Key conforming to the "hw.id" semantic conventions. - // It represents an identifier for the hardware component, unique within the - // monitored host. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "win32battery_battery_testsysa33_1" - HwIDKey = attribute.Key("hw.id") - - // HwNameKey is the attribute Key conforming to the "hw.name" semantic - // conventions. It represents an easily-recognizable name for the hardware - // component. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "eth0" - HwNameKey = attribute.Key("hw.name") - - // HwParentKey is the attribute Key conforming to the "hw.parent" semantic - // conventions. It represents the unique identifier of the parent component - // (typically the `hw.id` attribute of the enclosure, or disk controller). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "dellStorage_perc_0" - HwParentKey = attribute.Key("hw.parent") - - // HwStateKey is the attribute Key conforming to the "hw.state" semantic - // conventions. It represents the current state of the component. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - HwStateKey = attribute.Key("hw.state") - - // HwTypeKey is the attribute Key conforming to the "hw.type" semantic - // conventions. It represents the type of the component. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: Describes the category of the hardware component for which `hw.state` - // is being reported. For example, `hw.type=temperature` along with - // `hw.state=degraded` would indicate that the temperature of the hardware - // component has been reported as `degraded`. - HwTypeKey = attribute.Key("hw.type") -) - -// HwID returns an attribute KeyValue conforming to the "hw.id" semantic -// conventions. It represents an identifier for the hardware component, unique -// within the monitored host. -func HwID(val string) attribute.KeyValue { - return HwIDKey.String(val) -} - -// HwName returns an attribute KeyValue conforming to the "hw.name" semantic -// conventions. It represents an easily-recognizable name for the hardware -// component. -func HwName(val string) attribute.KeyValue { - return HwNameKey.String(val) -} - -// HwParent returns an attribute KeyValue conforming to the "hw.parent" semantic -// conventions. It represents the unique identifier of the parent component -// (typically the `hw.id` attribute of the enclosure, or disk controller). -func HwParent(val string) attribute.KeyValue { - return HwParentKey.String(val) -} - -// Enum values for hw.state -var ( - // Ok - // Stability: development - HwStateOk = HwStateKey.String("ok") - // Degraded - // Stability: development - HwStateDegraded = HwStateKey.String("degraded") - // Failed - // Stability: development - HwStateFailed = HwStateKey.String("failed") -) - -// Enum values for hw.type -var ( - // Battery - // Stability: development - HwTypeBattery = HwTypeKey.String("battery") - // CPU - // Stability: development - HwTypeCPU = HwTypeKey.String("cpu") - // Disk controller - // Stability: development - HwTypeDiskController = HwTypeKey.String("disk_controller") - // Enclosure - // Stability: development - HwTypeEnclosure = HwTypeKey.String("enclosure") - // Fan - // Stability: development - HwTypeFan = HwTypeKey.String("fan") - // GPU - // Stability: development - HwTypeGpu = HwTypeKey.String("gpu") - // Logical disk - // Stability: development - HwTypeLogicalDisk = HwTypeKey.String("logical_disk") - // Memory - // Stability: development - HwTypeMemory = HwTypeKey.String("memory") - // Network - // Stability: development - HwTypeNetwork = HwTypeKey.String("network") - // Physical disk - // Stability: development - HwTypePhysicalDisk = HwTypeKey.String("physical_disk") - // Power supply - // Stability: development - HwTypePowerSupply = HwTypeKey.String("power_supply") - // Tape drive - // Stability: development - HwTypeTapeDrive = HwTypeKey.String("tape_drive") - // Temperature - // Stability: development - HwTypeTemperature = HwTypeKey.String("temperature") - // Voltage - // Stability: development - HwTypeVoltage = HwTypeKey.String("voltage") -) - -// Namespace: k8s -const ( - // K8SClusterNameKey is the attribute Key conforming to the "k8s.cluster.name" - // semantic conventions. It represents the name of the cluster. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry-cluster" - K8SClusterNameKey = attribute.Key("k8s.cluster.name") - - // K8SClusterUIDKey is the attribute Key conforming to the "k8s.cluster.uid" - // semantic conventions. It represents a pseudo-ID for the cluster, set to the - // UID of the `kube-system` namespace. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" - // Note: K8s doesn't have support for obtaining a cluster ID. If this is ever - // added, we will recommend collecting the `k8s.cluster.uid` through the - // official APIs. In the meantime, we are able to use the `uid` of the - // `kube-system` namespace as a proxy for cluster ID. Read on for the - // rationale. - // - // Every object created in a K8s cluster is assigned a distinct UID. The - // `kube-system` namespace is used by Kubernetes itself and will exist - // for the lifetime of the cluster. Using the `uid` of the `kube-system` - // namespace is a reasonable proxy for the K8s ClusterID as it will only - // change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are - // UUIDs as standardized by - // [ISO/IEC 9834-8 and ITU-T X.667]. - // Which states: - // - // > If generated according to one of the mechanisms defined in Rec. - // > ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be - // > different from all other UUIDs generated before 3603 A.D., or is - // > extremely likely to be different (depending on the mechanism chosen). - // - // Therefore, UIDs between clusters should be extremely unlikely to - // conflict. - // - // [ISO/IEC 9834-8 and ITU-T X.667]: https://www.itu.int/ITU-T/studygroups/com17/oid.html - K8SClusterUIDKey = attribute.Key("k8s.cluster.uid") - - // K8SContainerNameKey is the attribute Key conforming to the - // "k8s.container.name" semantic conventions. It represents the name of the - // Container from Pod specification, must be unique within a Pod. Container - // runtime usually uses different globally unique name (`container.name`). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "redis" - K8SContainerNameKey = attribute.Key("k8s.container.name") - - // K8SContainerRestartCountKey is the attribute Key conforming to the - // "k8s.container.restart_count" semantic conventions. It represents the number - // of times the container was restarted. This attribute can be used to identify - // a particular container (running or stopped) within a container spec. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count") - - // K8SContainerStatusLastTerminatedReasonKey is the attribute Key conforming to - // the "k8s.container.status.last_terminated_reason" semantic conventions. It - // represents the last terminated reason of the Container. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Evicted", "Error" - K8SContainerStatusLastTerminatedReasonKey = attribute.Key("k8s.container.status.last_terminated_reason") - - // K8SCronJobNameKey is the attribute Key conforming to the "k8s.cronjob.name" - // semantic conventions. It represents the name of the CronJob. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry" - K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") - - // K8SCronJobUIDKey is the attribute Key conforming to the "k8s.cronjob.uid" - // semantic conventions. It represents the UID of the CronJob. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") - - // K8SDaemonSetNameKey is the attribute Key conforming to the - // "k8s.daemonset.name" semantic conventions. It represents the name of the - // DaemonSet. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry" - K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") - - // K8SDaemonSetUIDKey is the attribute Key conforming to the "k8s.daemonset.uid" - // semantic conventions. It represents the UID of the DaemonSet. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") - - // K8SDeploymentNameKey is the attribute Key conforming to the - // "k8s.deployment.name" semantic conventions. It represents the name of the - // Deployment. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry" - K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") - - // K8SDeploymentUIDKey is the attribute Key conforming to the - // "k8s.deployment.uid" semantic conventions. It represents the UID of the - // Deployment. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") - - // K8SJobNameKey is the attribute Key conforming to the "k8s.job.name" semantic - // conventions. It represents the name of the Job. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry" - K8SJobNameKey = attribute.Key("k8s.job.name") - - // K8SJobUIDKey is the attribute Key conforming to the "k8s.job.uid" semantic - // conventions. It represents the UID of the Job. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SJobUIDKey = attribute.Key("k8s.job.uid") - - // K8SNamespaceNameKey is the attribute Key conforming to the - // "k8s.namespace.name" semantic conventions. It represents the name of the - // namespace that the pod is running in. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "default" - K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") - - // K8SNamespacePhaseKey is the attribute Key conforming to the - // "k8s.namespace.phase" semantic conventions. It represents the phase of the - // K8s namespace. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "active", "terminating" - // Note: This attribute aligns with the `phase` field of the - // [K8s NamespaceStatus] - // - // [K8s NamespaceStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#namespacestatus-v1-core - K8SNamespacePhaseKey = attribute.Key("k8s.namespace.phase") - - // K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name" - // semantic conventions. It represents the name of the Node. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "node-1" - K8SNodeNameKey = attribute.Key("k8s.node.name") - - // K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid" semantic - // conventions. It represents the UID of the Node. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2" - K8SNodeUIDKey = attribute.Key("k8s.node.uid") - - // K8SPodNameKey is the attribute Key conforming to the "k8s.pod.name" semantic - // conventions. It represents the name of the Pod. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry-pod-autoconf" - K8SPodNameKey = attribute.Key("k8s.pod.name") - - // K8SPodUIDKey is the attribute Key conforming to the "k8s.pod.uid" semantic - // conventions. It represents the UID of the Pod. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SPodUIDKey = attribute.Key("k8s.pod.uid") - - // K8SReplicaSetNameKey is the attribute Key conforming to the - // "k8s.replicaset.name" semantic conventions. It represents the name of the - // ReplicaSet. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry" - K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") - - // K8SReplicaSetUIDKey is the attribute Key conforming to the - // "k8s.replicaset.uid" semantic conventions. It represents the UID of the - // ReplicaSet. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") - - // K8SStatefulSetNameKey is the attribute Key conforming to the - // "k8s.statefulset.name" semantic conventions. It represents the name of the - // StatefulSet. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "opentelemetry" - K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") - - // K8SStatefulSetUIDKey is the attribute Key conforming to the - // "k8s.statefulset.uid" semantic conventions. It represents the UID of the - // StatefulSet. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" - K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") - - // K8SVolumeNameKey is the attribute Key conforming to the "k8s.volume.name" - // semantic conventions. It represents the name of the K8s volume. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "volume0" - K8SVolumeNameKey = attribute.Key("k8s.volume.name") - - // K8SVolumeTypeKey is the attribute Key conforming to the "k8s.volume.type" - // semantic conventions. It represents the type of the K8s volume. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "emptyDir", "persistentVolumeClaim" - K8SVolumeTypeKey = attribute.Key("k8s.volume.type") -) - -// K8SClusterName returns an attribute KeyValue conforming to the -// "k8s.cluster.name" semantic conventions. It represents the name of the -// cluster. -func K8SClusterName(val string) attribute.KeyValue { - return K8SClusterNameKey.String(val) -} - -// K8SClusterUID returns an attribute KeyValue conforming to the -// "k8s.cluster.uid" semantic conventions. It represents a pseudo-ID for the -// cluster, set to the UID of the `kube-system` namespace. -func K8SClusterUID(val string) attribute.KeyValue { - return K8SClusterUIDKey.String(val) -} - -// K8SContainerName returns an attribute KeyValue conforming to the -// "k8s.container.name" semantic conventions. It represents the name of the -// Container from Pod specification, must be unique within a Pod. Container -// runtime usually uses different globally unique name (`container.name`). -func K8SContainerName(val string) attribute.KeyValue { - return K8SContainerNameKey.String(val) -} - -// K8SContainerRestartCount returns an attribute KeyValue conforming to the -// "k8s.container.restart_count" semantic conventions. It represents the number -// of times the container was restarted. This attribute can be used to identify a -// particular container (running or stopped) within a container spec. -func K8SContainerRestartCount(val int) attribute.KeyValue { - return K8SContainerRestartCountKey.Int(val) -} - -// K8SContainerStatusLastTerminatedReason returns an attribute KeyValue -// conforming to the "k8s.container.status.last_terminated_reason" semantic -// conventions. It represents the last terminated reason of the Container. -func K8SContainerStatusLastTerminatedReason(val string) attribute.KeyValue { - return K8SContainerStatusLastTerminatedReasonKey.String(val) -} - -// K8SCronJobName returns an attribute KeyValue conforming to the -// "k8s.cronjob.name" semantic conventions. It represents the name of the -// CronJob. -func K8SCronJobName(val string) attribute.KeyValue { - return K8SCronJobNameKey.String(val) -} - -// K8SCronJobUID returns an attribute KeyValue conforming to the -// "k8s.cronjob.uid" semantic conventions. It represents the UID of the CronJob. -func K8SCronJobUID(val string) attribute.KeyValue { - return K8SCronJobUIDKey.String(val) -} - -// K8SDaemonSetName returns an attribute KeyValue conforming to the -// "k8s.daemonset.name" semantic conventions. It represents the name of the -// DaemonSet. -func K8SDaemonSetName(val string) attribute.KeyValue { - return K8SDaemonSetNameKey.String(val) -} - -// K8SDaemonSetUID returns an attribute KeyValue conforming to the -// "k8s.daemonset.uid" semantic conventions. It represents the UID of the -// DaemonSet. -func K8SDaemonSetUID(val string) attribute.KeyValue { - return K8SDaemonSetUIDKey.String(val) -} - -// K8SDeploymentName returns an attribute KeyValue conforming to the -// "k8s.deployment.name" semantic conventions. It represents the name of the -// Deployment. -func K8SDeploymentName(val string) attribute.KeyValue { - return K8SDeploymentNameKey.String(val) -} - -// K8SDeploymentUID returns an attribute KeyValue conforming to the -// "k8s.deployment.uid" semantic conventions. It represents the UID of the -// Deployment. -func K8SDeploymentUID(val string) attribute.KeyValue { - return K8SDeploymentUIDKey.String(val) -} - -// K8SJobName returns an attribute KeyValue conforming to the "k8s.job.name" -// semantic conventions. It represents the name of the Job. -func K8SJobName(val string) attribute.KeyValue { - return K8SJobNameKey.String(val) -} - -// K8SJobUID returns an attribute KeyValue conforming to the "k8s.job.uid" -// semantic conventions. It represents the UID of the Job. -func K8SJobUID(val string) attribute.KeyValue { - return K8SJobUIDKey.String(val) -} - -// K8SNamespaceName returns an attribute KeyValue conforming to the -// "k8s.namespace.name" semantic conventions. It represents the name of the -// namespace that the pod is running in. -func K8SNamespaceName(val string) attribute.KeyValue { - return K8SNamespaceNameKey.String(val) -} - -// K8SNodeName returns an attribute KeyValue conforming to the "k8s.node.name" -// semantic conventions. It represents the name of the Node. -func K8SNodeName(val string) attribute.KeyValue { - return K8SNodeNameKey.String(val) -} - -// K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid" -// semantic conventions. It represents the UID of the Node. -func K8SNodeUID(val string) attribute.KeyValue { - return K8SNodeUIDKey.String(val) -} - -// K8SPodName returns an attribute KeyValue conforming to the "k8s.pod.name" -// semantic conventions. It represents the name of the Pod. -func K8SPodName(val string) attribute.KeyValue { - return K8SPodNameKey.String(val) -} - -// K8SPodUID returns an attribute KeyValue conforming to the "k8s.pod.uid" -// semantic conventions. It represents the UID of the Pod. -func K8SPodUID(val string) attribute.KeyValue { - return K8SPodUIDKey.String(val) -} - -// K8SReplicaSetName returns an attribute KeyValue conforming to the -// "k8s.replicaset.name" semantic conventions. It represents the name of the -// ReplicaSet. -func K8SReplicaSetName(val string) attribute.KeyValue { - return K8SReplicaSetNameKey.String(val) -} - -// K8SReplicaSetUID returns an attribute KeyValue conforming to the -// "k8s.replicaset.uid" semantic conventions. It represents the UID of the -// ReplicaSet. -func K8SReplicaSetUID(val string) attribute.KeyValue { - return K8SReplicaSetUIDKey.String(val) -} - -// K8SStatefulSetName returns an attribute KeyValue conforming to the -// "k8s.statefulset.name" semantic conventions. It represents the name of the -// StatefulSet. -func K8SStatefulSetName(val string) attribute.KeyValue { - return K8SStatefulSetNameKey.String(val) -} - -// K8SStatefulSetUID returns an attribute KeyValue conforming to the -// "k8s.statefulset.uid" semantic conventions. It represents the UID of the -// StatefulSet. -func K8SStatefulSetUID(val string) attribute.KeyValue { - return K8SStatefulSetUIDKey.String(val) -} - -// K8SVolumeName returns an attribute KeyValue conforming to the -// "k8s.volume.name" semantic conventions. It represents the name of the K8s -// volume. -func K8SVolumeName(val string) attribute.KeyValue { - return K8SVolumeNameKey.String(val) -} - -// Enum values for k8s.namespace.phase -var ( - // Active namespace phase as described by [K8s API] - // Stability: development - // - // [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase - K8SNamespacePhaseActive = K8SNamespacePhaseKey.String("active") - // Terminating namespace phase as described by [K8s API] - // Stability: development - // - // [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase - K8SNamespacePhaseTerminating = K8SNamespacePhaseKey.String("terminating") -) - -// Enum values for k8s.volume.type -var ( - // A [persistentVolumeClaim] volume - // Stability: development - // - // [persistentVolumeClaim]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim - K8SVolumeTypePersistentVolumeClaim = K8SVolumeTypeKey.String("persistentVolumeClaim") - // A [configMap] volume - // Stability: development - // - // [configMap]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#configmap - K8SVolumeTypeConfigMap = K8SVolumeTypeKey.String("configMap") - // A [downwardAPI] volume - // Stability: development - // - // [downwardAPI]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#downwardapi - K8SVolumeTypeDownwardAPI = K8SVolumeTypeKey.String("downwardAPI") - // An [emptyDir] volume - // Stability: development - // - // [emptyDir]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#emptydir - K8SVolumeTypeEmptyDir = K8SVolumeTypeKey.String("emptyDir") - // A [secret] volume - // Stability: development - // - // [secret]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#secret - K8SVolumeTypeSecret = K8SVolumeTypeKey.String("secret") - // A [local] volume - // Stability: development - // - // [local]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#local - K8SVolumeTypeLocal = K8SVolumeTypeKey.String("local") -) - -// Namespace: linux -const ( - // LinuxMemorySlabStateKey is the attribute Key conforming to the - // "linux.memory.slab.state" semantic conventions. It represents the Linux Slab - // memory state. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "reclaimable", "unreclaimable" - LinuxMemorySlabStateKey = attribute.Key("linux.memory.slab.state") -) - -// Enum values for linux.memory.slab.state -var ( - // reclaimable - // Stability: development - LinuxMemorySlabStateReclaimable = LinuxMemorySlabStateKey.String("reclaimable") - // unreclaimable - // Stability: development - LinuxMemorySlabStateUnreclaimable = LinuxMemorySlabStateKey.String("unreclaimable") -) - -// Namespace: log -const ( - // LogFileNameKey is the attribute Key conforming to the "log.file.name" - // semantic conventions. It represents the basename of the file. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "audit.log" - LogFileNameKey = attribute.Key("log.file.name") - - // LogFileNameResolvedKey is the attribute Key conforming to the - // "log.file.name_resolved" semantic conventions. It represents the basename of - // the file, with symlinks resolved. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "uuid.log" - LogFileNameResolvedKey = attribute.Key("log.file.name_resolved") - - // LogFilePathKey is the attribute Key conforming to the "log.file.path" - // semantic conventions. It represents the full path to the file. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/var/log/mysql/audit.log" - LogFilePathKey = attribute.Key("log.file.path") - - // LogFilePathResolvedKey is the attribute Key conforming to the - // "log.file.path_resolved" semantic conventions. It represents the full path to - // the file, with symlinks resolved. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/var/lib/docker/uuid.log" - LogFilePathResolvedKey = attribute.Key("log.file.path_resolved") - - // LogIostreamKey is the attribute Key conforming to the "log.iostream" semantic - // conventions. It represents the stream associated with the log. See below for - // a list of well-known values. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - LogIostreamKey = attribute.Key("log.iostream") - - // LogRecordOriginalKey is the attribute Key conforming to the - // "log.record.original" semantic conventions. It represents the complete - // original Log Record. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "77 <86>1 2015-08-06T21:58:59.694Z 192.168.2.133 inactive - - - - // Something happened", "[INFO] 8/3/24 12:34:56 Something happened" - // Note: This value MAY be added when processing a Log Record which was - // originally transmitted as a string or equivalent data type AND the Body field - // of the Log Record does not contain the same value. (e.g. a syslog or a log - // record read from a file.) - LogRecordOriginalKey = attribute.Key("log.record.original") - - // LogRecordUIDKey is the attribute Key conforming to the "log.record.uid" - // semantic conventions. It represents a unique identifier for the Log Record. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "01ARZ3NDEKTSV4RRFFQ69G5FAV" - // Note: If an id is provided, other log records with the same id will be - // considered duplicates and can be removed safely. This means, that two - // distinguishable log records MUST have different values. - // The id MAY be an - // [Universally Unique Lexicographically Sortable Identifier (ULID)], but other - // identifiers (e.g. UUID) may be used as needed. - // - // [Universally Unique Lexicographically Sortable Identifier (ULID)]: https://github.com/ulid/spec - LogRecordUIDKey = attribute.Key("log.record.uid") -) - -// LogFileName returns an attribute KeyValue conforming to the "log.file.name" -// semantic conventions. It represents the basename of the file. -func LogFileName(val string) attribute.KeyValue { - return LogFileNameKey.String(val) -} - -// LogFileNameResolved returns an attribute KeyValue conforming to the -// "log.file.name_resolved" semantic conventions. It represents the basename of -// the file, with symlinks resolved. -func LogFileNameResolved(val string) attribute.KeyValue { - return LogFileNameResolvedKey.String(val) -} - -// LogFilePath returns an attribute KeyValue conforming to the "log.file.path" -// semantic conventions. It represents the full path to the file. -func LogFilePath(val string) attribute.KeyValue { - return LogFilePathKey.String(val) -} - -// LogFilePathResolved returns an attribute KeyValue conforming to the -// "log.file.path_resolved" semantic conventions. It represents the full path to -// the file, with symlinks resolved. -func LogFilePathResolved(val string) attribute.KeyValue { - return LogFilePathResolvedKey.String(val) -} - -// LogRecordOriginal returns an attribute KeyValue conforming to the -// "log.record.original" semantic conventions. It represents the complete -// original Log Record. -func LogRecordOriginal(val string) attribute.KeyValue { - return LogRecordOriginalKey.String(val) -} - -// LogRecordUID returns an attribute KeyValue conforming to the "log.record.uid" -// semantic conventions. It represents a unique identifier for the Log Record. -func LogRecordUID(val string) attribute.KeyValue { - return LogRecordUIDKey.String(val) -} - -// Enum values for log.iostream -var ( - // Logs from stdout stream - // Stability: development - LogIostreamStdout = LogIostreamKey.String("stdout") - // Events from stderr stream - // Stability: development - LogIostreamStderr = LogIostreamKey.String("stderr") -) - -// Namespace: messaging -const ( - // MessagingBatchMessageCountKey is the attribute Key conforming to the - // "messaging.batch.message_count" semantic conventions. It represents the - // number of messages sent, received, or processed in the scope of the batching - // operation. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0, 1, 2 - // Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on - // spans that operate with a single message. When a messaging client library - // supports both batch and single-message API for the same operation, - // instrumentations SHOULD use `messaging.batch.message_count` for batching APIs - // and SHOULD NOT use it for single-message APIs. - MessagingBatchMessageCountKey = attribute.Key("messaging.batch.message_count") - - // MessagingClientIDKey is the attribute Key conforming to the - // "messaging.client.id" semantic conventions. It represents a unique identifier - // for the client that consumes or produces a message. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "client-5", "myhost@8742@s8083jm" - MessagingClientIDKey = attribute.Key("messaging.client.id") - - // MessagingConsumerGroupNameKey is the attribute Key conforming to the - // "messaging.consumer.group.name" semantic conventions. It represents the name - // of the consumer group with which a consumer is associated. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-group", "indexer" - // Note: Semantic conventions for individual messaging systems SHOULD document - // whether `messaging.consumer.group.name` is applicable and what it means in - // the context of that system. - MessagingConsumerGroupNameKey = attribute.Key("messaging.consumer.group.name") - - // MessagingDestinationAnonymousKey is the attribute Key conforming to the - // "messaging.destination.anonymous" semantic conventions. It represents a - // boolean that is true if the message destination is anonymous (could be - // unnamed or have auto-generated name). - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - MessagingDestinationAnonymousKey = attribute.Key("messaging.destination.anonymous") - - // MessagingDestinationNameKey is the attribute Key conforming to the - // "messaging.destination.name" semantic conventions. It represents the message - // destination name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "MyQueue", "MyTopic" - // Note: Destination name SHOULD uniquely identify a specific queue, topic or - // other entity within the broker. If - // the broker doesn't have such notion, the destination name SHOULD uniquely - // identify the broker. - MessagingDestinationNameKey = attribute.Key("messaging.destination.name") - - // MessagingDestinationPartitionIDKey is the attribute Key conforming to the - // "messaging.destination.partition.id" semantic conventions. It represents the - // identifier of the partition messages are sent to or received from, unique - // within the `messaging.destination.name`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1 - MessagingDestinationPartitionIDKey = attribute.Key("messaging.destination.partition.id") - - // MessagingDestinationSubscriptionNameKey is the attribute Key conforming to - // the "messaging.destination.subscription.name" semantic conventions. It - // represents the name of the destination subscription from which a message is - // consumed. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "subscription-a" - // Note: Semantic conventions for individual messaging systems SHOULD document - // whether `messaging.destination.subscription.name` is applicable and what it - // means in the context of that system. - MessagingDestinationSubscriptionNameKey = attribute.Key("messaging.destination.subscription.name") - - // MessagingDestinationTemplateKey is the attribute Key conforming to the - // "messaging.destination.template" semantic conventions. It represents the low - // cardinality representation of the messaging destination name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/customers/{customerId}" - // Note: Destination names could be constructed from templates. An example would - // be a destination name involving a user name or product id. Although the - // destination name in this case is of high cardinality, the underlying template - // is of low cardinality and can be effectively used for grouping and - // aggregation. - MessagingDestinationTemplateKey = attribute.Key("messaging.destination.template") - - // MessagingDestinationTemporaryKey is the attribute Key conforming to the - // "messaging.destination.temporary" semantic conventions. It represents a - // boolean that is true if the message destination is temporary and might not - // exist anymore after messages are processed. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - MessagingDestinationTemporaryKey = attribute.Key("messaging.destination.temporary") - - // MessagingEventhubsMessageEnqueuedTimeKey is the attribute Key conforming to - // the "messaging.eventhubs.message.enqueued_time" semantic conventions. It - // represents the UTC epoch seconds at which the message has been accepted and - // stored in the entity. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingEventhubsMessageEnqueuedTimeKey = attribute.Key("messaging.eventhubs.message.enqueued_time") - - // MessagingGCPPubsubMessageAckDeadlineKey is the attribute Key conforming to - // the "messaging.gcp_pubsub.message.ack_deadline" semantic conventions. It - // represents the ack deadline in seconds set for the modify ack deadline - // request. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingGCPPubsubMessageAckDeadlineKey = attribute.Key("messaging.gcp_pubsub.message.ack_deadline") - - // MessagingGCPPubsubMessageAckIDKey is the attribute Key conforming to the - // "messaging.gcp_pubsub.message.ack_id" semantic conventions. It represents the - // ack id for a given message. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: ack_id - MessagingGCPPubsubMessageAckIDKey = attribute.Key("messaging.gcp_pubsub.message.ack_id") - - // MessagingGCPPubsubMessageDeliveryAttemptKey is the attribute Key conforming - // to the "messaging.gcp_pubsub.message.delivery_attempt" semantic conventions. - // It represents the delivery attempt for a given message. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingGCPPubsubMessageDeliveryAttemptKey = attribute.Key("messaging.gcp_pubsub.message.delivery_attempt") - - // MessagingGCPPubsubMessageOrderingKeyKey is the attribute Key conforming to - // the "messaging.gcp_pubsub.message.ordering_key" semantic conventions. It - // represents the ordering key for a given message. If the attribute is not - // present, the message does not have an ordering key. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: ordering_key - MessagingGCPPubsubMessageOrderingKeyKey = attribute.Key("messaging.gcp_pubsub.message.ordering_key") - - // MessagingKafkaMessageKeyKey is the attribute Key conforming to the - // "messaging.kafka.message.key" semantic conventions. It represents the message - // keys in Kafka are used for grouping alike messages to ensure they're - // processed on the same partition. They differ from `messaging.message.id` in - // that they're not unique. If the key is `null`, the attribute MUST NOT be set. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: myKey - // Note: If the key type is not string, it's string representation has to be - // supplied for the attribute. If the key has no unambiguous, canonical string - // form, don't include its value. - MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message.key") - - // MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the - // "messaging.kafka.message.tombstone" semantic conventions. It represents a - // boolean that is true if the message is a tombstone. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - MessagingKafkaMessageTombstoneKey = attribute.Key("messaging.kafka.message.tombstone") - - // MessagingKafkaOffsetKey is the attribute Key conforming to the - // "messaging.kafka.offset" semantic conventions. It represents the offset of a - // record in the corresponding Kafka partition. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingKafkaOffsetKey = attribute.Key("messaging.kafka.offset") - - // MessagingMessageBodySizeKey is the attribute Key conforming to the - // "messaging.message.body.size" semantic conventions. It represents the size of - // the message body in bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Note: This can refer to both the compressed or uncompressed body size. If - // both sizes are known, the uncompressed - // body size should be used. - MessagingMessageBodySizeKey = attribute.Key("messaging.message.body.size") - - // MessagingMessageConversationIDKey is the attribute Key conforming to the - // "messaging.message.conversation_id" semantic conventions. It represents the - // conversation ID identifying the conversation to which the message belongs, - // represented as a string. Sometimes called "Correlation ID". - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: MyConversationId - MessagingMessageConversationIDKey = attribute.Key("messaging.message.conversation_id") - - // MessagingMessageEnvelopeSizeKey is the attribute Key conforming to the - // "messaging.message.envelope.size" semantic conventions. It represents the - // size of the message body and metadata in bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Note: This can refer to both the compressed or uncompressed size. If both - // sizes are known, the uncompressed - // size should be used. - MessagingMessageEnvelopeSizeKey = attribute.Key("messaging.message.envelope.size") - - // MessagingMessageIDKey is the attribute Key conforming to the - // "messaging.message.id" semantic conventions. It represents a value used by - // the messaging system as an identifier for the message, represented as a - // string. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 452a7c7c7c7048c2f887f61572b18fc2 - MessagingMessageIDKey = attribute.Key("messaging.message.id") - - // MessagingOperationNameKey is the attribute Key conforming to the - // "messaging.operation.name" semantic conventions. It represents the - // system-specific name of the messaging operation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "ack", "nack", "send" - MessagingOperationNameKey = attribute.Key("messaging.operation.name") - - // MessagingOperationTypeKey is the attribute Key conforming to the - // "messaging.operation.type" semantic conventions. It represents a string - // identifying the type of the messaging operation. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: If a custom value is used, it MUST be of low cardinality. - MessagingOperationTypeKey = attribute.Key("messaging.operation.type") - - // MessagingRabbitmqDestinationRoutingKeyKey is the attribute Key conforming to - // the "messaging.rabbitmq.destination.routing_key" semantic conventions. It - // represents the rabbitMQ message routing key. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: myKey - MessagingRabbitmqDestinationRoutingKeyKey = attribute.Key("messaging.rabbitmq.destination.routing_key") - - // MessagingRabbitmqMessageDeliveryTagKey is the attribute Key conforming to the - // "messaging.rabbitmq.message.delivery_tag" semantic conventions. It represents - // the rabbitMQ message delivery tag. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingRabbitmqMessageDeliveryTagKey = attribute.Key("messaging.rabbitmq.message.delivery_tag") - - // MessagingRocketmqConsumptionModelKey is the attribute Key conforming to the - // "messaging.rocketmq.consumption_model" semantic conventions. It represents - // the model of message consumption. This only applies to consumer spans. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - MessagingRocketmqConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model") - - // MessagingRocketmqMessageDelayTimeLevelKey is the attribute Key conforming to - // the "messaging.rocketmq.message.delay_time_level" semantic conventions. It - // represents the delay time level for delay message, which determines the - // message delay time. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingRocketmqMessageDelayTimeLevelKey = attribute.Key("messaging.rocketmq.message.delay_time_level") - - // MessagingRocketmqMessageDeliveryTimestampKey is the attribute Key conforming - // to the "messaging.rocketmq.message.delivery_timestamp" semantic conventions. - // It represents the timestamp in milliseconds that the delay message is - // expected to be delivered to consumer. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingRocketmqMessageDeliveryTimestampKey = attribute.Key("messaging.rocketmq.message.delivery_timestamp") - - // MessagingRocketmqMessageGroupKey is the attribute Key conforming to the - // "messaging.rocketmq.message.group" semantic conventions. It represents the it - // is essential for FIFO message. Messages that belong to the same message group - // are always processed one by one within the same consumer group. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: myMessageGroup - MessagingRocketmqMessageGroupKey = attribute.Key("messaging.rocketmq.message.group") - - // MessagingRocketmqMessageKeysKey is the attribute Key conforming to the - // "messaging.rocketmq.message.keys" semantic conventions. It represents the - // key(s) of message, another way to mark message besides message id. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "keyA", "keyB" - MessagingRocketmqMessageKeysKey = attribute.Key("messaging.rocketmq.message.keys") - - // MessagingRocketmqMessageTagKey is the attribute Key conforming to the - // "messaging.rocketmq.message.tag" semantic conventions. It represents the - // secondary classifier of message besides topic. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: tagA - MessagingRocketmqMessageTagKey = attribute.Key("messaging.rocketmq.message.tag") - - // MessagingRocketmqMessageTypeKey is the attribute Key conforming to the - // "messaging.rocketmq.message.type" semantic conventions. It represents the - // type of message. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - MessagingRocketmqMessageTypeKey = attribute.Key("messaging.rocketmq.message.type") - - // MessagingRocketmqNamespaceKey is the attribute Key conforming to the - // "messaging.rocketmq.namespace" semantic conventions. It represents the - // namespace of RocketMQ resources, resources in different namespaces are - // individual. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: myNamespace - MessagingRocketmqNamespaceKey = attribute.Key("messaging.rocketmq.namespace") - - // MessagingServicebusDispositionStatusKey is the attribute Key conforming to - // the "messaging.servicebus.disposition_status" semantic conventions. It - // represents the describes the [settlement type]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // - // [settlement type]: https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock - MessagingServicebusDispositionStatusKey = attribute.Key("messaging.servicebus.disposition_status") - - // MessagingServicebusMessageDeliveryCountKey is the attribute Key conforming to - // the "messaging.servicebus.message.delivery_count" semantic conventions. It - // represents the number of deliveries that have been attempted for this - // message. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingServicebusMessageDeliveryCountKey = attribute.Key("messaging.servicebus.message.delivery_count") - - // MessagingServicebusMessageEnqueuedTimeKey is the attribute Key conforming to - // the "messaging.servicebus.message.enqueued_time" semantic conventions. It - // represents the UTC epoch seconds at which the message has been accepted and - // stored in the entity. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - MessagingServicebusMessageEnqueuedTimeKey = attribute.Key("messaging.servicebus.message.enqueued_time") - - // MessagingSystemKey is the attribute Key conforming to the "messaging.system" - // semantic conventions. It represents the messaging system as identified by the - // client instrumentation. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: The actual messaging system may differ from the one known by the - // client. For example, when using Kafka client libraries to communicate with - // Azure Event Hubs, the `messaging.system` is set to `kafka` based on the - // instrumentation's best knowledge. - MessagingSystemKey = attribute.Key("messaging.system") -) - -// MessagingBatchMessageCount returns an attribute KeyValue conforming to the -// "messaging.batch.message_count" semantic conventions. It represents the number -// of messages sent, received, or processed in the scope of the batching -// operation. -func MessagingBatchMessageCount(val int) attribute.KeyValue { - return MessagingBatchMessageCountKey.Int(val) -} - -// MessagingClientID returns an attribute KeyValue conforming to the -// "messaging.client.id" semantic conventions. It represents a unique identifier -// for the client that consumes or produces a message. -func MessagingClientID(val string) attribute.KeyValue { - return MessagingClientIDKey.String(val) -} - -// MessagingConsumerGroupName returns an attribute KeyValue conforming to the -// "messaging.consumer.group.name" semantic conventions. It represents the name -// of the consumer group with which a consumer is associated. -func MessagingConsumerGroupName(val string) attribute.KeyValue { - return MessagingConsumerGroupNameKey.String(val) -} - -// MessagingDestinationAnonymous returns an attribute KeyValue conforming to the -// "messaging.destination.anonymous" semantic conventions. It represents a -// boolean that is true if the message destination is anonymous (could be unnamed -// or have auto-generated name). -func MessagingDestinationAnonymous(val bool) attribute.KeyValue { - return MessagingDestinationAnonymousKey.Bool(val) -} - -// MessagingDestinationName returns an attribute KeyValue conforming to the -// "messaging.destination.name" semantic conventions. It represents the message -// destination name. -func MessagingDestinationName(val string) attribute.KeyValue { - return MessagingDestinationNameKey.String(val) -} - -// MessagingDestinationPartitionID returns an attribute KeyValue conforming to -// the "messaging.destination.partition.id" semantic conventions. It represents -// the identifier of the partition messages are sent to or received from, unique -// within the `messaging.destination.name`. -func MessagingDestinationPartitionID(val string) attribute.KeyValue { - return MessagingDestinationPartitionIDKey.String(val) -} - -// MessagingDestinationSubscriptionName returns an attribute KeyValue conforming -// to the "messaging.destination.subscription.name" semantic conventions. It -// represents the name of the destination subscription from which a message is -// consumed. -func MessagingDestinationSubscriptionName(val string) attribute.KeyValue { - return MessagingDestinationSubscriptionNameKey.String(val) -} - -// MessagingDestinationTemplate returns an attribute KeyValue conforming to the -// "messaging.destination.template" semantic conventions. It represents the low -// cardinality representation of the messaging destination name. -func MessagingDestinationTemplate(val string) attribute.KeyValue { - return MessagingDestinationTemplateKey.String(val) -} - -// MessagingDestinationTemporary returns an attribute KeyValue conforming to the -// "messaging.destination.temporary" semantic conventions. It represents a -// boolean that is true if the message destination is temporary and might not -// exist anymore after messages are processed. -func MessagingDestinationTemporary(val bool) attribute.KeyValue { - return MessagingDestinationTemporaryKey.Bool(val) -} - -// MessagingEventhubsMessageEnqueuedTime returns an attribute KeyValue conforming -// to the "messaging.eventhubs.message.enqueued_time" semantic conventions. It -// represents the UTC epoch seconds at which the message has been accepted and -// stored in the entity. -func MessagingEventhubsMessageEnqueuedTime(val int) attribute.KeyValue { - return MessagingEventhubsMessageEnqueuedTimeKey.Int(val) -} - -// MessagingGCPPubsubMessageAckDeadline returns an attribute KeyValue conforming -// to the "messaging.gcp_pubsub.message.ack_deadline" semantic conventions. It -// represents the ack deadline in seconds set for the modify ack deadline -// request. -func MessagingGCPPubsubMessageAckDeadline(val int) attribute.KeyValue { - return MessagingGCPPubsubMessageAckDeadlineKey.Int(val) -} - -// MessagingGCPPubsubMessageAckID returns an attribute KeyValue conforming to the -// "messaging.gcp_pubsub.message.ack_id" semantic conventions. It represents the -// ack id for a given message. -func MessagingGCPPubsubMessageAckID(val string) attribute.KeyValue { - return MessagingGCPPubsubMessageAckIDKey.String(val) -} - -// MessagingGCPPubsubMessageDeliveryAttempt returns an attribute KeyValue -// conforming to the "messaging.gcp_pubsub.message.delivery_attempt" semantic -// conventions. It represents the delivery attempt for a given message. -func MessagingGCPPubsubMessageDeliveryAttempt(val int) attribute.KeyValue { - return MessagingGCPPubsubMessageDeliveryAttemptKey.Int(val) -} - -// MessagingGCPPubsubMessageOrderingKey returns an attribute KeyValue conforming -// to the "messaging.gcp_pubsub.message.ordering_key" semantic conventions. It -// represents the ordering key for a given message. If the attribute is not -// present, the message does not have an ordering key. -func MessagingGCPPubsubMessageOrderingKey(val string) attribute.KeyValue { - return MessagingGCPPubsubMessageOrderingKeyKey.String(val) -} - -// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the -// "messaging.kafka.message.key" semantic conventions. It represents the message -// keys in Kafka are used for grouping alike messages to ensure they're processed -// on the same partition. They differ from `messaging.message.id` in that they're -// not unique. If the key is `null`, the attribute MUST NOT be set. -func MessagingKafkaMessageKey(val string) attribute.KeyValue { - return MessagingKafkaMessageKeyKey.String(val) -} - -// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming to the -// "messaging.kafka.message.tombstone" semantic conventions. It represents a -// boolean that is true if the message is a tombstone. -func MessagingKafkaMessageTombstone(val bool) attribute.KeyValue { - return MessagingKafkaMessageTombstoneKey.Bool(val) -} - -// MessagingKafkaOffset returns an attribute KeyValue conforming to the -// "messaging.kafka.offset" semantic conventions. It represents the offset of a -// record in the corresponding Kafka partition. -func MessagingKafkaOffset(val int) attribute.KeyValue { - return MessagingKafkaOffsetKey.Int(val) -} - -// MessagingMessageBodySize returns an attribute KeyValue conforming to the -// "messaging.message.body.size" semantic conventions. It represents the size of -// the message body in bytes. -func MessagingMessageBodySize(val int) attribute.KeyValue { - return MessagingMessageBodySizeKey.Int(val) -} - -// MessagingMessageConversationID returns an attribute KeyValue conforming to the -// "messaging.message.conversation_id" semantic conventions. It represents the -// conversation ID identifying the conversation to which the message belongs, -// represented as a string. Sometimes called "Correlation ID". -func MessagingMessageConversationID(val string) attribute.KeyValue { - return MessagingMessageConversationIDKey.String(val) -} - -// MessagingMessageEnvelopeSize returns an attribute KeyValue conforming to the -// "messaging.message.envelope.size" semantic conventions. It represents the size -// of the message body and metadata in bytes. -func MessagingMessageEnvelopeSize(val int) attribute.KeyValue { - return MessagingMessageEnvelopeSizeKey.Int(val) -} - -// MessagingMessageID returns an attribute KeyValue conforming to the -// "messaging.message.id" semantic conventions. It represents a value used by the -// messaging system as an identifier for the message, represented as a string. -func MessagingMessageID(val string) attribute.KeyValue { - return MessagingMessageIDKey.String(val) -} - -// MessagingOperationName returns an attribute KeyValue conforming to the -// "messaging.operation.name" semantic conventions. It represents the -// system-specific name of the messaging operation. -func MessagingOperationName(val string) attribute.KeyValue { - return MessagingOperationNameKey.String(val) -} - -// MessagingRabbitmqDestinationRoutingKey returns an attribute KeyValue -// conforming to the "messaging.rabbitmq.destination.routing_key" semantic -// conventions. It represents the rabbitMQ message routing key. -func MessagingRabbitmqDestinationRoutingKey(val string) attribute.KeyValue { - return MessagingRabbitmqDestinationRoutingKeyKey.String(val) -} - -// MessagingRabbitmqMessageDeliveryTag returns an attribute KeyValue conforming -// to the "messaging.rabbitmq.message.delivery_tag" semantic conventions. It -// represents the rabbitMQ message delivery tag. -func MessagingRabbitmqMessageDeliveryTag(val int) attribute.KeyValue { - return MessagingRabbitmqMessageDeliveryTagKey.Int(val) -} - -// MessagingRocketmqMessageDelayTimeLevel returns an attribute KeyValue -// conforming to the "messaging.rocketmq.message.delay_time_level" semantic -// conventions. It represents the delay time level for delay message, which -// determines the message delay time. -func MessagingRocketmqMessageDelayTimeLevel(val int) attribute.KeyValue { - return MessagingRocketmqMessageDelayTimeLevelKey.Int(val) -} - -// MessagingRocketmqMessageDeliveryTimestamp returns an attribute KeyValue -// conforming to the "messaging.rocketmq.message.delivery_timestamp" semantic -// conventions. It represents the timestamp in milliseconds that the delay -// message is expected to be delivered to consumer. -func MessagingRocketmqMessageDeliveryTimestamp(val int) attribute.KeyValue { - return MessagingRocketmqMessageDeliveryTimestampKey.Int(val) -} - -// MessagingRocketmqMessageGroup returns an attribute KeyValue conforming to the -// "messaging.rocketmq.message.group" semantic conventions. It represents the it -// is essential for FIFO message. Messages that belong to the same message group -// are always processed one by one within the same consumer group. -func MessagingRocketmqMessageGroup(val string) attribute.KeyValue { - return MessagingRocketmqMessageGroupKey.String(val) -} - -// MessagingRocketmqMessageKeys returns an attribute KeyValue conforming to the -// "messaging.rocketmq.message.keys" semantic conventions. It represents the -// key(s) of message, another way to mark message besides message id. -func MessagingRocketmqMessageKeys(val ...string) attribute.KeyValue { - return MessagingRocketmqMessageKeysKey.StringSlice(val) -} - -// MessagingRocketmqMessageTag returns an attribute KeyValue conforming to the -// "messaging.rocketmq.message.tag" semantic conventions. It represents the -// secondary classifier of message besides topic. -func MessagingRocketmqMessageTag(val string) attribute.KeyValue { - return MessagingRocketmqMessageTagKey.String(val) -} - -// MessagingRocketmqNamespace returns an attribute KeyValue conforming to the -// "messaging.rocketmq.namespace" semantic conventions. It represents the -// namespace of RocketMQ resources, resources in different namespaces are -// individual. -func MessagingRocketmqNamespace(val string) attribute.KeyValue { - return MessagingRocketmqNamespaceKey.String(val) -} - -// MessagingServicebusMessageDeliveryCount returns an attribute KeyValue -// conforming to the "messaging.servicebus.message.delivery_count" semantic -// conventions. It represents the number of deliveries that have been attempted -// for this message. -func MessagingServicebusMessageDeliveryCount(val int) attribute.KeyValue { - return MessagingServicebusMessageDeliveryCountKey.Int(val) -} - -// MessagingServicebusMessageEnqueuedTime returns an attribute KeyValue -// conforming to the "messaging.servicebus.message.enqueued_time" semantic -// conventions. It represents the UTC epoch seconds at which the message has been -// accepted and stored in the entity. -func MessagingServicebusMessageEnqueuedTime(val int) attribute.KeyValue { - return MessagingServicebusMessageEnqueuedTimeKey.Int(val) -} - -// Enum values for messaging.operation.type -var ( - // A message is created. "Create" spans always refer to a single message and are - // used to provide a unique creation context for messages in batch sending - // scenarios. - // - // Stability: development - MessagingOperationTypeCreate = MessagingOperationTypeKey.String("create") - // One or more messages are provided for sending to an intermediary. If a single - // message is sent, the context of the "Send" span can be used as the creation - // context and no "Create" span needs to be created. - // - // Stability: development - MessagingOperationTypeSend = MessagingOperationTypeKey.String("send") - // One or more messages are requested by a consumer. This operation refers to - // pull-based scenarios, where consumers explicitly call methods of messaging - // SDKs to receive messages. - // - // Stability: development - MessagingOperationTypeReceive = MessagingOperationTypeKey.String("receive") - // One or more messages are processed by a consumer. - // - // Stability: development - MessagingOperationTypeProcess = MessagingOperationTypeKey.String("process") - // One or more messages are settled. - // - // Stability: development - MessagingOperationTypeSettle = MessagingOperationTypeKey.String("settle") - // Deprecated: Replaced by `process`. - MessagingOperationTypeDeliver = MessagingOperationTypeKey.String("deliver") - // Deprecated: Replaced by `send`. - MessagingOperationTypePublish = MessagingOperationTypeKey.String("publish") -) - -// Enum values for messaging.rocketmq.consumption_model -var ( - // Clustering consumption model - // Stability: development - MessagingRocketmqConsumptionModelClustering = MessagingRocketmqConsumptionModelKey.String("clustering") - // Broadcasting consumption model - // Stability: development - MessagingRocketmqConsumptionModelBroadcasting = MessagingRocketmqConsumptionModelKey.String("broadcasting") -) - -// Enum values for messaging.rocketmq.message.type -var ( - // Normal message - // Stability: development - MessagingRocketmqMessageTypeNormal = MessagingRocketmqMessageTypeKey.String("normal") - // FIFO message - // Stability: development - MessagingRocketmqMessageTypeFifo = MessagingRocketmqMessageTypeKey.String("fifo") - // Delay message - // Stability: development - MessagingRocketmqMessageTypeDelay = MessagingRocketmqMessageTypeKey.String("delay") - // Transaction message - // Stability: development - MessagingRocketmqMessageTypeTransaction = MessagingRocketmqMessageTypeKey.String("transaction") -) - -// Enum values for messaging.servicebus.disposition_status -var ( - // Message is completed - // Stability: development - MessagingServicebusDispositionStatusComplete = MessagingServicebusDispositionStatusKey.String("complete") - // Message is abandoned - // Stability: development - MessagingServicebusDispositionStatusAbandon = MessagingServicebusDispositionStatusKey.String("abandon") - // Message is sent to dead letter queue - // Stability: development - MessagingServicebusDispositionStatusDeadLetter = MessagingServicebusDispositionStatusKey.String("dead_letter") - // Message is deferred - // Stability: development - MessagingServicebusDispositionStatusDefer = MessagingServicebusDispositionStatusKey.String("defer") -) - -// Enum values for messaging.system -var ( - // Apache ActiveMQ - // Stability: development - MessagingSystemActivemq = MessagingSystemKey.String("activemq") - // Amazon Simple Queue Service (SQS) - // Stability: development - MessagingSystemAWSSqs = MessagingSystemKey.String("aws_sqs") - // Azure Event Grid - // Stability: development - MessagingSystemEventgrid = MessagingSystemKey.String("eventgrid") - // Azure Event Hubs - // Stability: development - MessagingSystemEventhubs = MessagingSystemKey.String("eventhubs") - // Azure Service Bus - // Stability: development - MessagingSystemServicebus = MessagingSystemKey.String("servicebus") - // Google Cloud Pub/Sub - // Stability: development - MessagingSystemGCPPubsub = MessagingSystemKey.String("gcp_pubsub") - // Java Message Service - // Stability: development - MessagingSystemJms = MessagingSystemKey.String("jms") - // Apache Kafka - // Stability: development - MessagingSystemKafka = MessagingSystemKey.String("kafka") - // RabbitMQ - // Stability: development - MessagingSystemRabbitmq = MessagingSystemKey.String("rabbitmq") - // Apache RocketMQ - // Stability: development - MessagingSystemRocketmq = MessagingSystemKey.String("rocketmq") - // Apache Pulsar - // Stability: development - MessagingSystemPulsar = MessagingSystemKey.String("pulsar") -) - -// Namespace: network -const ( - // NetworkCarrierIccKey is the attribute Key conforming to the - // "network.carrier.icc" semantic conventions. It represents the ISO 3166-1 - // alpha-2 2-character country code associated with the mobile carrier network. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: DE - NetworkCarrierIccKey = attribute.Key("network.carrier.icc") - - // NetworkCarrierMccKey is the attribute Key conforming to the - // "network.carrier.mcc" semantic conventions. It represents the mobile carrier - // country code. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 310 - NetworkCarrierMccKey = attribute.Key("network.carrier.mcc") - - // NetworkCarrierMncKey is the attribute Key conforming to the - // "network.carrier.mnc" semantic conventions. It represents the mobile carrier - // network code. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 001 - NetworkCarrierMncKey = attribute.Key("network.carrier.mnc") - - // NetworkCarrierNameKey is the attribute Key conforming to the - // "network.carrier.name" semantic conventions. It represents the name of the - // mobile carrier. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: sprint - NetworkCarrierNameKey = attribute.Key("network.carrier.name") - - // NetworkConnectionStateKey is the attribute Key conforming to the - // "network.connection.state" semantic conventions. It represents the state of - // network connection. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "close_wait" - // Note: Connection states are defined as part of the [rfc9293] - // - // [rfc9293]: https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2 - NetworkConnectionStateKey = attribute.Key("network.connection.state") - - // NetworkConnectionSubtypeKey is the attribute Key conforming to the - // "network.connection.subtype" semantic conventions. It represents the this - // describes more details regarding the connection.type. It may be the type of - // cell technology connection, but it could be used for describing details about - // a wifi connection. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: LTE - NetworkConnectionSubtypeKey = attribute.Key("network.connection.subtype") - - // NetworkConnectionTypeKey is the attribute Key conforming to the - // "network.connection.type" semantic conventions. It represents the internet - // connection type. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: wifi - NetworkConnectionTypeKey = attribute.Key("network.connection.type") - - // NetworkInterfaceNameKey is the attribute Key conforming to the - // "network.interface.name" semantic conventions. It represents the network - // interface name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "lo", "eth0" - NetworkInterfaceNameKey = attribute.Key("network.interface.name") - - // NetworkIoDirectionKey is the attribute Key conforming to the - // "network.io.direction" semantic conventions. It represents the network IO - // operation direction. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "transmit" - NetworkIoDirectionKey = attribute.Key("network.io.direction") - - // NetworkLocalAddressKey is the attribute Key conforming to the - // "network.local.address" semantic conventions. It represents the local address - // of the network connection - IP address or Unix domain socket name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "10.1.2.80", "/tmp/my.sock" - NetworkLocalAddressKey = attribute.Key("network.local.address") - - // NetworkLocalPortKey is the attribute Key conforming to the - // "network.local.port" semantic conventions. It represents the local port - // number of the network connection. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: 65123 - NetworkLocalPortKey = attribute.Key("network.local.port") - - // NetworkPeerAddressKey is the attribute Key conforming to the - // "network.peer.address" semantic conventions. It represents the peer address - // of the network connection - IP address or Unix domain socket name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "10.1.2.80", "/tmp/my.sock" - NetworkPeerAddressKey = attribute.Key("network.peer.address") - - // NetworkPeerPortKey is the attribute Key conforming to the "network.peer.port" - // semantic conventions. It represents the peer port number of the network - // connection. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: 65123 - NetworkPeerPortKey = attribute.Key("network.peer.port") - - // NetworkProtocolNameKey is the attribute Key conforming to the - // "network.protocol.name" semantic conventions. It represents the - // [OSI application layer] or non-OSI equivalent. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "amqp", "http", "mqtt" - // Note: The value SHOULD be normalized to lowercase. - // - // [OSI application layer]: https://wikipedia.org/wiki/Application_layer - NetworkProtocolNameKey = attribute.Key("network.protocol.name") - - // NetworkProtocolVersionKey is the attribute Key conforming to the - // "network.protocol.version" semantic conventions. It represents the actual - // version of the protocol used for network communication. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "1.1", "2" - // Note: If protocol version is subject to negotiation (for example using [ALPN] - // ), this attribute SHOULD be set to the negotiated version. If the actual - // protocol version is not known, this attribute SHOULD NOT be set. - // - // [ALPN]: https://www.rfc-editor.org/rfc/rfc7301.html - NetworkProtocolVersionKey = attribute.Key("network.protocol.version") - - // NetworkTransportKey is the attribute Key conforming to the - // "network.transport" semantic conventions. It represents the - // [OSI transport layer] or [inter-process communication method]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "tcp", "udp" - // Note: The value SHOULD be normalized to lowercase. - // - // Consider always setting the transport when setting a port number, since - // a port number is ambiguous without knowing the transport. For example - // different processes could be listening on TCP port 12345 and UDP port 12345. - // - // [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer - // [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication - NetworkTransportKey = attribute.Key("network.transport") - - // NetworkTypeKey is the attribute Key conforming to the "network.type" semantic - // conventions. It represents the [OSI network layer] or non-OSI equivalent. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "ipv4", "ipv6" - // Note: The value SHOULD be normalized to lowercase. - // - // [OSI network layer]: https://wikipedia.org/wiki/Network_layer - NetworkTypeKey = attribute.Key("network.type") -) - -// NetworkCarrierIcc returns an attribute KeyValue conforming to the -// "network.carrier.icc" semantic conventions. It represents the ISO 3166-1 -// alpha-2 2-character country code associated with the mobile carrier network. -func NetworkCarrierIcc(val string) attribute.KeyValue { - return NetworkCarrierIccKey.String(val) -} - -// NetworkCarrierMcc returns an attribute KeyValue conforming to the -// "network.carrier.mcc" semantic conventions. It represents the mobile carrier -// country code. -func NetworkCarrierMcc(val string) attribute.KeyValue { - return NetworkCarrierMccKey.String(val) -} - -// NetworkCarrierMnc returns an attribute KeyValue conforming to the -// "network.carrier.mnc" semantic conventions. It represents the mobile carrier -// network code. -func NetworkCarrierMnc(val string) attribute.KeyValue { - return NetworkCarrierMncKey.String(val) -} - -// NetworkCarrierName returns an attribute KeyValue conforming to the -// "network.carrier.name" semantic conventions. It represents the name of the -// mobile carrier. -func NetworkCarrierName(val string) attribute.KeyValue { - return NetworkCarrierNameKey.String(val) -} - -// NetworkInterfaceName returns an attribute KeyValue conforming to the -// "network.interface.name" semantic conventions. It represents the network -// interface name. -func NetworkInterfaceName(val string) attribute.KeyValue { - return NetworkInterfaceNameKey.String(val) -} - -// NetworkLocalAddress returns an attribute KeyValue conforming to the -// "network.local.address" semantic conventions. It represents the local address -// of the network connection - IP address or Unix domain socket name. -func NetworkLocalAddress(val string) attribute.KeyValue { - return NetworkLocalAddressKey.String(val) -} - -// NetworkLocalPort returns an attribute KeyValue conforming to the -// "network.local.port" semantic conventions. It represents the local port number -// of the network connection. -func NetworkLocalPort(val int) attribute.KeyValue { - return NetworkLocalPortKey.Int(val) -} - -// NetworkPeerAddress returns an attribute KeyValue conforming to the -// "network.peer.address" semantic conventions. It represents the peer address of -// the network connection - IP address or Unix domain socket name. -func NetworkPeerAddress(val string) attribute.KeyValue { - return NetworkPeerAddressKey.String(val) -} - -// NetworkPeerPort returns an attribute KeyValue conforming to the -// "network.peer.port" semantic conventions. It represents the peer port number -// of the network connection. -func NetworkPeerPort(val int) attribute.KeyValue { - return NetworkPeerPortKey.Int(val) -} - -// NetworkProtocolName returns an attribute KeyValue conforming to the -// "network.protocol.name" semantic conventions. It represents the -// [OSI application layer] or non-OSI equivalent. -// -// [OSI application layer]: https://wikipedia.org/wiki/Application_layer -func NetworkProtocolName(val string) attribute.KeyValue { - return NetworkProtocolNameKey.String(val) -} - -// NetworkProtocolVersion returns an attribute KeyValue conforming to the -// "network.protocol.version" semantic conventions. It represents the actual -// version of the protocol used for network communication. -func NetworkProtocolVersion(val string) attribute.KeyValue { - return NetworkProtocolVersionKey.String(val) -} - -// Enum values for network.connection.state -var ( - // closed - // Stability: development - NetworkConnectionStateClosed = NetworkConnectionStateKey.String("closed") - // close_wait - // Stability: development - NetworkConnectionStateCloseWait = NetworkConnectionStateKey.String("close_wait") - // closing - // Stability: development - NetworkConnectionStateClosing = NetworkConnectionStateKey.String("closing") - // established - // Stability: development - NetworkConnectionStateEstablished = NetworkConnectionStateKey.String("established") - // fin_wait_1 - // Stability: development - NetworkConnectionStateFinWait1 = NetworkConnectionStateKey.String("fin_wait_1") - // fin_wait_2 - // Stability: development - NetworkConnectionStateFinWait2 = NetworkConnectionStateKey.String("fin_wait_2") - // last_ack - // Stability: development - NetworkConnectionStateLastAck = NetworkConnectionStateKey.String("last_ack") - // listen - // Stability: development - NetworkConnectionStateListen = NetworkConnectionStateKey.String("listen") - // syn_received - // Stability: development - NetworkConnectionStateSynReceived = NetworkConnectionStateKey.String("syn_received") - // syn_sent - // Stability: development - NetworkConnectionStateSynSent = NetworkConnectionStateKey.String("syn_sent") - // time_wait - // Stability: development - NetworkConnectionStateTimeWait = NetworkConnectionStateKey.String("time_wait") -) - -// Enum values for network.connection.subtype -var ( - // GPRS - // Stability: development - NetworkConnectionSubtypeGprs = NetworkConnectionSubtypeKey.String("gprs") - // EDGE - // Stability: development - NetworkConnectionSubtypeEdge = NetworkConnectionSubtypeKey.String("edge") - // UMTS - // Stability: development - NetworkConnectionSubtypeUmts = NetworkConnectionSubtypeKey.String("umts") - // CDMA - // Stability: development - NetworkConnectionSubtypeCdma = NetworkConnectionSubtypeKey.String("cdma") - // EVDO Rel. 0 - // Stability: development - NetworkConnectionSubtypeEvdo0 = NetworkConnectionSubtypeKey.String("evdo_0") - // EVDO Rev. A - // Stability: development - NetworkConnectionSubtypeEvdoA = NetworkConnectionSubtypeKey.String("evdo_a") - // CDMA2000 1XRTT - // Stability: development - NetworkConnectionSubtypeCdma20001xrtt = NetworkConnectionSubtypeKey.String("cdma2000_1xrtt") - // HSDPA - // Stability: development - NetworkConnectionSubtypeHsdpa = NetworkConnectionSubtypeKey.String("hsdpa") - // HSUPA - // Stability: development - NetworkConnectionSubtypeHsupa = NetworkConnectionSubtypeKey.String("hsupa") - // HSPA - // Stability: development - NetworkConnectionSubtypeHspa = NetworkConnectionSubtypeKey.String("hspa") - // IDEN - // Stability: development - NetworkConnectionSubtypeIden = NetworkConnectionSubtypeKey.String("iden") - // EVDO Rev. B - // Stability: development - NetworkConnectionSubtypeEvdoB = NetworkConnectionSubtypeKey.String("evdo_b") - // LTE - // Stability: development - NetworkConnectionSubtypeLte = NetworkConnectionSubtypeKey.String("lte") - // EHRPD - // Stability: development - NetworkConnectionSubtypeEhrpd = NetworkConnectionSubtypeKey.String("ehrpd") - // HSPAP - // Stability: development - NetworkConnectionSubtypeHspap = NetworkConnectionSubtypeKey.String("hspap") - // GSM - // Stability: development - NetworkConnectionSubtypeGsm = NetworkConnectionSubtypeKey.String("gsm") - // TD-SCDMA - // Stability: development - NetworkConnectionSubtypeTdScdma = NetworkConnectionSubtypeKey.String("td_scdma") - // IWLAN - // Stability: development - NetworkConnectionSubtypeIwlan = NetworkConnectionSubtypeKey.String("iwlan") - // 5G NR (New Radio) - // Stability: development - NetworkConnectionSubtypeNr = NetworkConnectionSubtypeKey.String("nr") - // 5G NRNSA (New Radio Non-Standalone) - // Stability: development - NetworkConnectionSubtypeNrnsa = NetworkConnectionSubtypeKey.String("nrnsa") - // LTE CA - // Stability: development - NetworkConnectionSubtypeLteCa = NetworkConnectionSubtypeKey.String("lte_ca") -) - -// Enum values for network.connection.type -var ( - // wifi - // Stability: development - NetworkConnectionTypeWifi = NetworkConnectionTypeKey.String("wifi") - // wired - // Stability: development - NetworkConnectionTypeWired = NetworkConnectionTypeKey.String("wired") - // cell - // Stability: development - NetworkConnectionTypeCell = NetworkConnectionTypeKey.String("cell") - // unavailable - // Stability: development - NetworkConnectionTypeUnavailable = NetworkConnectionTypeKey.String("unavailable") - // unknown - // Stability: development - NetworkConnectionTypeUnknown = NetworkConnectionTypeKey.String("unknown") -) - -// Enum values for network.io.direction -var ( - // transmit - // Stability: development - NetworkIoDirectionTransmit = NetworkIoDirectionKey.String("transmit") - // receive - // Stability: development - NetworkIoDirectionReceive = NetworkIoDirectionKey.String("receive") -) - -// Enum values for network.transport -var ( - // TCP - // Stability: stable - NetworkTransportTCP = NetworkTransportKey.String("tcp") - // UDP - // Stability: stable - NetworkTransportUDP = NetworkTransportKey.String("udp") - // Named or anonymous pipe. - // Stability: stable - NetworkTransportPipe = NetworkTransportKey.String("pipe") - // Unix domain socket - // Stability: stable - NetworkTransportUnix = NetworkTransportKey.String("unix") - // QUIC - // Stability: development - NetworkTransportQUIC = NetworkTransportKey.String("quic") -) - -// Enum values for network.type -var ( - // IPv4 - // Stability: stable - NetworkTypeIpv4 = NetworkTypeKey.String("ipv4") - // IPv6 - // Stability: stable - NetworkTypeIpv6 = NetworkTypeKey.String("ipv6") -) - -// Namespace: oci -const ( - // OciManifestDigestKey is the attribute Key conforming to the - // "oci.manifest.digest" semantic conventions. It represents the digest of the - // OCI image manifest. For container images specifically is the digest by which - // the container image is known. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4" - // Note: Follows [OCI Image Manifest Specification], and specifically the - // [Digest property]. - // An example can be found in [Example Image Manifest]. - // - // [OCI Image Manifest Specification]: https://github.com/opencontainers/image-spec/blob/main/manifest.md - // [Digest property]: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests - // [Example Image Manifest]: https://docs.docker.com/registry/spec/manifest-v2-2/#example-image-manifest - OciManifestDigestKey = attribute.Key("oci.manifest.digest") -) - -// OciManifestDigest returns an attribute KeyValue conforming to the -// "oci.manifest.digest" semantic conventions. It represents the digest of the -// OCI image manifest. For container images specifically is the digest by which -// the container image is known. -func OciManifestDigest(val string) attribute.KeyValue { - return OciManifestDigestKey.String(val) -} - -// Namespace: opentracing -const ( - // OpentracingRefTypeKey is the attribute Key conforming to the - // "opentracing.ref_type" semantic conventions. It represents the parent-child - // Reference type. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: The causal relationship between a child Span and a parent Span. - OpentracingRefTypeKey = attribute.Key("opentracing.ref_type") -) - -// Enum values for opentracing.ref_type -var ( - // The parent Span depends on the child Span in some capacity - // Stability: development - OpentracingRefTypeChildOf = OpentracingRefTypeKey.String("child_of") - // The parent Span doesn't depend in any way on the result of the child Span - // Stability: development - OpentracingRefTypeFollowsFrom = OpentracingRefTypeKey.String("follows_from") -) - -// Namespace: os -const ( - // OSBuildIDKey is the attribute Key conforming to the "os.build_id" semantic - // conventions. It represents the unique identifier for a particular build or - // compilation of the operating system. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "TQ3C.230805.001.B2", "20E247", "22621" - OSBuildIDKey = attribute.Key("os.build_id") - - // OSDescriptionKey is the attribute Key conforming to the "os.description" - // semantic conventions. It represents the human readable (not intended to be - // parsed) OS version information, like e.g. reported by `ver` or - // `lsb_release -a` commands. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Microsoft Windows [Version 10.0.18363.778]", "Ubuntu 18.04.1 LTS" - OSDescriptionKey = attribute.Key("os.description") - - // OSNameKey is the attribute Key conforming to the "os.name" semantic - // conventions. It represents the human readable operating system name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "iOS", "Android", "Ubuntu" - OSNameKey = attribute.Key("os.name") - - // OSTypeKey is the attribute Key conforming to the "os.type" semantic - // conventions. It represents the operating system type. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - OSTypeKey = attribute.Key("os.type") - - // OSVersionKey is the attribute Key conforming to the "os.version" semantic - // conventions. It represents the version string of the operating system as - // defined in [Version Attributes]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "14.2.1", "18.04.1" - // - // [Version Attributes]: /docs/resource/README.md#version-attributes - OSVersionKey = attribute.Key("os.version") -) - -// OSBuildID returns an attribute KeyValue conforming to the "os.build_id" -// semantic conventions. It represents the unique identifier for a particular -// build or compilation of the operating system. -func OSBuildID(val string) attribute.KeyValue { - return OSBuildIDKey.String(val) -} - -// OSDescription returns an attribute KeyValue conforming to the "os.description" -// semantic conventions. It represents the human readable (not intended to be -// parsed) OS version information, like e.g. reported by `ver` or -// `lsb_release -a` commands. -func OSDescription(val string) attribute.KeyValue { - return OSDescriptionKey.String(val) -} - -// OSName returns an attribute KeyValue conforming to the "os.name" semantic -// conventions. It represents the human readable operating system name. -func OSName(val string) attribute.KeyValue { - return OSNameKey.String(val) -} - -// OSVersion returns an attribute KeyValue conforming to the "os.version" -// semantic conventions. It represents the version string of the operating system -// as defined in [Version Attributes]. -// -// [Version Attributes]: /docs/resource/README.md#version-attributes -func OSVersion(val string) attribute.KeyValue { - return OSVersionKey.String(val) -} - -// Enum values for os.type -var ( - // Microsoft Windows - // Stability: development - OSTypeWindows = OSTypeKey.String("windows") - // Linux - // Stability: development - OSTypeLinux = OSTypeKey.String("linux") - // Apple Darwin - // Stability: development - OSTypeDarwin = OSTypeKey.String("darwin") - // FreeBSD - // Stability: development - OSTypeFreeBSD = OSTypeKey.String("freebsd") - // NetBSD - // Stability: development - OSTypeNetBSD = OSTypeKey.String("netbsd") - // OpenBSD - // Stability: development - OSTypeOpenBSD = OSTypeKey.String("openbsd") - // DragonFly BSD - // Stability: development - OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd") - // HP-UX (Hewlett Packard Unix) - // Stability: development - OSTypeHPUX = OSTypeKey.String("hpux") - // AIX (Advanced Interactive eXecutive) - // Stability: development - OSTypeAIX = OSTypeKey.String("aix") - // SunOS, Oracle Solaris - // Stability: development - OSTypeSolaris = OSTypeKey.String("solaris") - // IBM z/OS - // Stability: development - OSTypeZOS = OSTypeKey.String("z_os") -) - -// Namespace: otel -const ( - // OTelScopeNameKey is the attribute Key conforming to the "otel.scope.name" - // semantic conventions. It represents the name of the instrumentation scope - ( - // `InstrumentationScope.Name` in OTLP). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "io.opentelemetry.contrib.mongodb" - OTelScopeNameKey = attribute.Key("otel.scope.name") - - // OTelScopeVersionKey is the attribute Key conforming to the - // "otel.scope.version" semantic conventions. It represents the version of the - // instrumentation scope - (`InstrumentationScope.Version` in OTLP). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "1.0.0" - OTelScopeVersionKey = attribute.Key("otel.scope.version") - - // OTelStatusCodeKey is the attribute Key conforming to the "otel.status_code" - // semantic conventions. It represents the name of the code, either "OK" or - // "ERROR". MUST NOT be set if the status code is UNSET. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: - OTelStatusCodeKey = attribute.Key("otel.status_code") - - // OTelStatusDescriptionKey is the attribute Key conforming to the - // "otel.status_description" semantic conventions. It represents the description - // of the Status if it has a value, otherwise not set. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "resource not found" - OTelStatusDescriptionKey = attribute.Key("otel.status_description") -) - -// OTelScopeName returns an attribute KeyValue conforming to the -// "otel.scope.name" semantic conventions. It represents the name of the -// instrumentation scope - (`InstrumentationScope.Name` in OTLP). -func OTelScopeName(val string) attribute.KeyValue { - return OTelScopeNameKey.String(val) -} - -// OTelScopeVersion returns an attribute KeyValue conforming to the -// "otel.scope.version" semantic conventions. It represents the version of the -// instrumentation scope - (`InstrumentationScope.Version` in OTLP). -func OTelScopeVersion(val string) attribute.KeyValue { - return OTelScopeVersionKey.String(val) -} - -// OTelStatusDescription returns an attribute KeyValue conforming to the -// "otel.status_description" semantic conventions. It represents the description -// of the Status if it has a value, otherwise not set. -func OTelStatusDescription(val string) attribute.KeyValue { - return OTelStatusDescriptionKey.String(val) -} - -// Enum values for otel.status_code -var ( - // The operation has been validated by an Application developer or Operator to - // have completed successfully. - // Stability: stable - OTelStatusCodeOk = OTelStatusCodeKey.String("OK") - // The operation contains an error. - // Stability: stable - OTelStatusCodeError = OTelStatusCodeKey.String("ERROR") -) - -// Namespace: peer -const ( - // PeerServiceKey is the attribute Key conforming to the "peer.service" semantic - // conventions. It represents the [`service.name`] of the remote service. SHOULD - // be equal to the actual `service.name` resource attribute of the remote - // service if any. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: AuthTokenCache - // - // [`service.name`]: /docs/resource/README.md#service - PeerServiceKey = attribute.Key("peer.service") -) - -// PeerService returns an attribute KeyValue conforming to the "peer.service" -// semantic conventions. It represents the [`service.name`] of the remote -// service. SHOULD be equal to the actual `service.name` resource attribute of -// the remote service if any. -// -// [`service.name`]: /docs/resource/README.md#service -func PeerService(val string) attribute.KeyValue { - return PeerServiceKey.String(val) -} - -// Namespace: process -const ( - // ProcessArgsCountKey is the attribute Key conforming to the - // "process.args_count" semantic conventions. It represents the length of the - // process.command_args array. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 4 - // Note: This field can be useful for querying or performing bucket analysis on - // how many arguments were provided to start a process. More arguments may be an - // indication of suspicious activity. - ProcessArgsCountKey = attribute.Key("process.args_count") - - // ProcessCommandKey is the attribute Key conforming to the "process.command" - // semantic conventions. It represents the command used to launch the process - // (i.e. the command name). On Linux based systems, can be set to the zeroth - // string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter - // extracted from `GetCommandLineW`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "cmd/otelcol" - ProcessCommandKey = attribute.Key("process.command") - - // ProcessCommandArgsKey is the attribute Key conforming to the - // "process.command_args" semantic conventions. It represents the all the - // command arguments (including the command/executable itself) as received by - // the process. On Linux-based systems (and some other Unixoid systems - // supporting procfs), can be set according to the list of null-delimited - // strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this - // would be the full argv vector passed to `main`. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "cmd/otecol", "--config=config.yaml" - ProcessCommandArgsKey = attribute.Key("process.command_args") - - // ProcessCommandLineKey is the attribute Key conforming to the - // "process.command_line" semantic conventions. It represents the full command - // used to launch the process as a single string representing the full command. - // On Windows, can be set to the result of `GetCommandLineW`. Do not set this if - // you have to assemble it just for monitoring; use `process.command_args` - // instead. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "C:\cmd\otecol --config="my directory\config.yaml"" - ProcessCommandLineKey = attribute.Key("process.command_line") - - // ProcessContextSwitchTypeKey is the attribute Key conforming to the - // "process.context_switch_type" semantic conventions. It represents the - // specifies whether the context switches for this data point were voluntary or - // involuntary. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - ProcessContextSwitchTypeKey = attribute.Key("process.context_switch_type") - - // ProcessCreationTimeKey is the attribute Key conforming to the - // "process.creation.time" semantic conventions. It represents the date and time - // the process was created, in ISO 8601 format. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2023-11-21T09:25:34.853Z" - ProcessCreationTimeKey = attribute.Key("process.creation.time") - - // ProcessExecutableBuildIDGnuKey is the attribute Key conforming to the - // "process.executable.build_id.gnu" semantic conventions. It represents the GNU - // build ID as found in the `.note.gnu.build-id` ELF section (hex string). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "c89b11207f6479603b0d49bf291c092c2b719293" - ProcessExecutableBuildIDGnuKey = attribute.Key("process.executable.build_id.gnu") - - // ProcessExecutableBuildIDGoKey is the attribute Key conforming to the - // "process.executable.build_id.go" semantic conventions. It represents the Go - // build ID as retrieved by `go tool buildid `. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY" - ProcessExecutableBuildIDGoKey = attribute.Key("process.executable.build_id.go") - - // ProcessExecutableBuildIDHtlhashKey is the attribute Key conforming to the - // "process.executable.build_id.htlhash" semantic conventions. It represents the - // profiling specific build ID for executables. See the OTel specification for - // Profiles for more information. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "600DCAFE4A110000F2BF38C493F5FB92" - ProcessExecutableBuildIDHtlhashKey = attribute.Key("process.executable.build_id.htlhash") - - // ProcessExecutableNameKey is the attribute Key conforming to the - // "process.executable.name" semantic conventions. It represents the name of the - // process executable. On Linux based systems, can be set to the `Name` in - // `proc/[pid]/status`. On Windows, can be set to the base name of - // `GetProcessImageFileNameW`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "otelcol" - ProcessExecutableNameKey = attribute.Key("process.executable.name") - - // ProcessExecutablePathKey is the attribute Key conforming to the - // "process.executable.path" semantic conventions. It represents the full path - // to the process executable. On Linux based systems, can be set to the target - // of `proc/[pid]/exe`. On Windows, can be set to the result of - // `GetProcessImageFileNameW`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/usr/bin/cmd/otelcol" - ProcessExecutablePathKey = attribute.Key("process.executable.path") - - // ProcessExitCodeKey is the attribute Key conforming to the "process.exit.code" - // semantic conventions. It represents the exit code of the process. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 127 - ProcessExitCodeKey = attribute.Key("process.exit.code") - - // ProcessExitTimeKey is the attribute Key conforming to the "process.exit.time" - // semantic conventions. It represents the date and time the process exited, in - // ISO 8601 format. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2023-11-21T09:26:12.315Z" - ProcessExitTimeKey = attribute.Key("process.exit.time") - - // ProcessGroupLeaderPIDKey is the attribute Key conforming to the - // "process.group_leader.pid" semantic conventions. It represents the PID of the - // process's group leader. This is also the process group ID (PGID) of the - // process. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 23 - ProcessGroupLeaderPIDKey = attribute.Key("process.group_leader.pid") - - // ProcessInteractiveKey is the attribute Key conforming to the - // "process.interactive" semantic conventions. It represents the whether the - // process is connected to an interactive shell. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - ProcessInteractiveKey = attribute.Key("process.interactive") - - // ProcessLinuxCgroupKey is the attribute Key conforming to the - // "process.linux.cgroup" semantic conventions. It represents the control group - // associated with the process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1:name=systemd:/user.slice/user-1000.slice/session-3.scope", - // "0::/user.slice/user-1000.slice/user@1000.service/tmux-spawn-0267755b-4639-4a27-90ed-f19f88e53748.scope" - // Note: Control groups (cgroups) are a kernel feature used to organize and - // manage process resources. This attribute provides the path(s) to the - // cgroup(s) associated with the process, which should match the contents of the - // [/proc/[PID]/cgroup] file. - // - // [/proc/[PID]/cgroup]: https://man7.org/linux/man-pages/man7/cgroups.7.html - ProcessLinuxCgroupKey = attribute.Key("process.linux.cgroup") - - // ProcessOwnerKey is the attribute Key conforming to the "process.owner" - // semantic conventions. It represents the username of the user that owns the - // process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "root" - ProcessOwnerKey = attribute.Key("process.owner") - - // ProcessPagingFaultTypeKey is the attribute Key conforming to the - // "process.paging.fault_type" semantic conventions. It represents the type of - // page fault for this data point. Type `major` is for major/hard page faults, - // and `minor` is for minor/soft page faults. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - ProcessPagingFaultTypeKey = attribute.Key("process.paging.fault_type") - - // ProcessParentPIDKey is the attribute Key conforming to the - // "process.parent_pid" semantic conventions. It represents the parent Process - // identifier (PPID). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 111 - ProcessParentPIDKey = attribute.Key("process.parent_pid") - - // ProcessPIDKey is the attribute Key conforming to the "process.pid" semantic - // conventions. It represents the process identifier (PID). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1234 - ProcessPIDKey = attribute.Key("process.pid") - - // ProcessRealUserIDKey is the attribute Key conforming to the - // "process.real_user.id" semantic conventions. It represents the real user ID - // (RUID) of the process. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1000 - ProcessRealUserIDKey = attribute.Key("process.real_user.id") - - // ProcessRealUserNameKey is the attribute Key conforming to the - // "process.real_user.name" semantic conventions. It represents the username of - // the real user of the process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "operator" - ProcessRealUserNameKey = attribute.Key("process.real_user.name") - - // ProcessRuntimeDescriptionKey is the attribute Key conforming to the - // "process.runtime.description" semantic conventions. It represents an - // additional description about the runtime of the process, for example a - // specific vendor customization of the runtime environment. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0 - ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") - - // ProcessRuntimeNameKey is the attribute Key conforming to the - // "process.runtime.name" semantic conventions. It represents the name of the - // runtime of this process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "OpenJDK Runtime Environment" - ProcessRuntimeNameKey = attribute.Key("process.runtime.name") - - // ProcessRuntimeVersionKey is the attribute Key conforming to the - // "process.runtime.version" semantic conventions. It represents the version of - // the runtime of this process, as returned by the runtime without modification. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 14.0.2 - ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") - - // ProcessSavedUserIDKey is the attribute Key conforming to the - // "process.saved_user.id" semantic conventions. It represents the saved user ID - // (SUID) of the process. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1002 - ProcessSavedUserIDKey = attribute.Key("process.saved_user.id") - - // ProcessSavedUserNameKey is the attribute Key conforming to the - // "process.saved_user.name" semantic conventions. It represents the username of - // the saved user. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "operator" - ProcessSavedUserNameKey = attribute.Key("process.saved_user.name") - - // ProcessSessionLeaderPIDKey is the attribute Key conforming to the - // "process.session_leader.pid" semantic conventions. It represents the PID of - // the process's session leader. This is also the session ID (SID) of the - // process. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 14 - ProcessSessionLeaderPIDKey = attribute.Key("process.session_leader.pid") - - // ProcessTitleKey is the attribute Key conforming to the "process.title" - // semantic conventions. It represents the process title (proctitle). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "cat /etc/hostname", "xfce4-session", "bash" - // Note: In many Unix-like systems, process title (proctitle), is the string - // that represents the name or command line of a running process, displayed by - // system monitoring tools like ps, top, and htop. - ProcessTitleKey = attribute.Key("process.title") - - // ProcessUserIDKey is the attribute Key conforming to the "process.user.id" - // semantic conventions. It represents the effective user ID (EUID) of the - // process. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1001 - ProcessUserIDKey = attribute.Key("process.user.id") - - // ProcessUserNameKey is the attribute Key conforming to the "process.user.name" - // semantic conventions. It represents the username of the effective user of the - // process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "root" - ProcessUserNameKey = attribute.Key("process.user.name") - - // ProcessVpidKey is the attribute Key conforming to the "process.vpid" semantic - // conventions. It represents the virtual process identifier. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 12 - // Note: The process ID within a PID namespace. This is not necessarily unique - // across all processes on the host but it is unique within the process - // namespace that the process exists within. - ProcessVpidKey = attribute.Key("process.vpid") - - // ProcessWorkingDirectoryKey is the attribute Key conforming to the - // "process.working_directory" semantic conventions. It represents the working - // directory of the process. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/root" - ProcessWorkingDirectoryKey = attribute.Key("process.working_directory") -) - -// ProcessArgsCount returns an attribute KeyValue conforming to the -// "process.args_count" semantic conventions. It represents the length of the -// process.command_args array. -func ProcessArgsCount(val int) attribute.KeyValue { - return ProcessArgsCountKey.Int(val) -} - -// ProcessCommand returns an attribute KeyValue conforming to the -// "process.command" semantic conventions. It represents the command used to -// launch the process (i.e. the command name). On Linux based systems, can be set -// to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the -// first parameter extracted from `GetCommandLineW`. -func ProcessCommand(val string) attribute.KeyValue { - return ProcessCommandKey.String(val) -} - -// ProcessCommandArgs returns an attribute KeyValue conforming to the -// "process.command_args" semantic conventions. It represents the all the command -// arguments (including the command/executable itself) as received by the -// process. On Linux-based systems (and some other Unixoid systems supporting -// procfs), can be set according to the list of null-delimited strings extracted -// from `proc/[pid]/cmdline`. For libc-based executables, this would be the full -// argv vector passed to `main`. -func ProcessCommandArgs(val ...string) attribute.KeyValue { - return ProcessCommandArgsKey.StringSlice(val) -} - -// ProcessCommandLine returns an attribute KeyValue conforming to the -// "process.command_line" semantic conventions. It represents the full command -// used to launch the process as a single string representing the full command. -// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if -// you have to assemble it just for monitoring; use `process.command_args` -// instead. -func ProcessCommandLine(val string) attribute.KeyValue { - return ProcessCommandLineKey.String(val) -} - -// ProcessCreationTime returns an attribute KeyValue conforming to the -// "process.creation.time" semantic conventions. It represents the date and time -// the process was created, in ISO 8601 format. -func ProcessCreationTime(val string) attribute.KeyValue { - return ProcessCreationTimeKey.String(val) -} - -// ProcessExecutableBuildIDGnu returns an attribute KeyValue conforming to the -// "process.executable.build_id.gnu" semantic conventions. It represents the GNU -// build ID as found in the `.note.gnu.build-id` ELF section (hex string). -func ProcessExecutableBuildIDGnu(val string) attribute.KeyValue { - return ProcessExecutableBuildIDGnuKey.String(val) -} - -// ProcessExecutableBuildIDGo returns an attribute KeyValue conforming to the -// "process.executable.build_id.go" semantic conventions. It represents the Go -// build ID as retrieved by `go tool buildid `. -func ProcessExecutableBuildIDGo(val string) attribute.KeyValue { - return ProcessExecutableBuildIDGoKey.String(val) -} - -// ProcessExecutableBuildIDHtlhash returns an attribute KeyValue conforming to -// the "process.executable.build_id.htlhash" semantic conventions. It represents -// the profiling specific build ID for executables. See the OTel specification -// for Profiles for more information. -func ProcessExecutableBuildIDHtlhash(val string) attribute.KeyValue { - return ProcessExecutableBuildIDHtlhashKey.String(val) -} - -// ProcessExecutableName returns an attribute KeyValue conforming to the -// "process.executable.name" semantic conventions. It represents the name of the -// process executable. On Linux based systems, can be set to the `Name` in -// `proc/[pid]/status`. On Windows, can be set to the base name of -// `GetProcessImageFileNameW`. -func ProcessExecutableName(val string) attribute.KeyValue { - return ProcessExecutableNameKey.String(val) -} - -// ProcessExecutablePath returns an attribute KeyValue conforming to the -// "process.executable.path" semantic conventions. It represents the full path to -// the process executable. On Linux based systems, can be set to the target of -// `proc/[pid]/exe`. On Windows, can be set to the result of -// `GetProcessImageFileNameW`. -func ProcessExecutablePath(val string) attribute.KeyValue { - return ProcessExecutablePathKey.String(val) -} - -// ProcessExitCode returns an attribute KeyValue conforming to the -// "process.exit.code" semantic conventions. It represents the exit code of the -// process. -func ProcessExitCode(val int) attribute.KeyValue { - return ProcessExitCodeKey.Int(val) -} - -// ProcessExitTime returns an attribute KeyValue conforming to the -// "process.exit.time" semantic conventions. It represents the date and time the -// process exited, in ISO 8601 format. -func ProcessExitTime(val string) attribute.KeyValue { - return ProcessExitTimeKey.String(val) -} - -// ProcessGroupLeaderPID returns an attribute KeyValue conforming to the -// "process.group_leader.pid" semantic conventions. It represents the PID of the -// process's group leader. This is also the process group ID (PGID) of the -// process. -func ProcessGroupLeaderPID(val int) attribute.KeyValue { - return ProcessGroupLeaderPIDKey.Int(val) -} - -// ProcessInteractive returns an attribute KeyValue conforming to the -// "process.interactive" semantic conventions. It represents the whether the -// process is connected to an interactive shell. -func ProcessInteractive(val bool) attribute.KeyValue { - return ProcessInteractiveKey.Bool(val) -} - -// ProcessLinuxCgroup returns an attribute KeyValue conforming to the -// "process.linux.cgroup" semantic conventions. It represents the control group -// associated with the process. -func ProcessLinuxCgroup(val string) attribute.KeyValue { - return ProcessLinuxCgroupKey.String(val) -} - -// ProcessOwner returns an attribute KeyValue conforming to the "process.owner" -// semantic conventions. It represents the username of the user that owns the -// process. -func ProcessOwner(val string) attribute.KeyValue { - return ProcessOwnerKey.String(val) -} - -// ProcessParentPID returns an attribute KeyValue conforming to the -// "process.parent_pid" semantic conventions. It represents the parent Process -// identifier (PPID). -func ProcessParentPID(val int) attribute.KeyValue { - return ProcessParentPIDKey.Int(val) -} - -// ProcessPID returns an attribute KeyValue conforming to the "process.pid" -// semantic conventions. It represents the process identifier (PID). -func ProcessPID(val int) attribute.KeyValue { - return ProcessPIDKey.Int(val) -} - -// ProcessRealUserID returns an attribute KeyValue conforming to the -// "process.real_user.id" semantic conventions. It represents the real user ID -// (RUID) of the process. -func ProcessRealUserID(val int) attribute.KeyValue { - return ProcessRealUserIDKey.Int(val) -} - -// ProcessRealUserName returns an attribute KeyValue conforming to the -// "process.real_user.name" semantic conventions. It represents the username of -// the real user of the process. -func ProcessRealUserName(val string) attribute.KeyValue { - return ProcessRealUserNameKey.String(val) -} - -// ProcessRuntimeDescription returns an attribute KeyValue conforming to the -// "process.runtime.description" semantic conventions. It represents an -// additional description about the runtime of the process, for example a -// specific vendor customization of the runtime environment. -func ProcessRuntimeDescription(val string) attribute.KeyValue { - return ProcessRuntimeDescriptionKey.String(val) -} - -// ProcessRuntimeName returns an attribute KeyValue conforming to the -// "process.runtime.name" semantic conventions. It represents the name of the -// runtime of this process. -func ProcessRuntimeName(val string) attribute.KeyValue { - return ProcessRuntimeNameKey.String(val) -} - -// ProcessRuntimeVersion returns an attribute KeyValue conforming to the -// "process.runtime.version" semantic conventions. It represents the version of -// the runtime of this process, as returned by the runtime without modification. -func ProcessRuntimeVersion(val string) attribute.KeyValue { - return ProcessRuntimeVersionKey.String(val) -} - -// ProcessSavedUserID returns an attribute KeyValue conforming to the -// "process.saved_user.id" semantic conventions. It represents the saved user ID -// (SUID) of the process. -func ProcessSavedUserID(val int) attribute.KeyValue { - return ProcessSavedUserIDKey.Int(val) -} - -// ProcessSavedUserName returns an attribute KeyValue conforming to the -// "process.saved_user.name" semantic conventions. It represents the username of -// the saved user. -func ProcessSavedUserName(val string) attribute.KeyValue { - return ProcessSavedUserNameKey.String(val) -} - -// ProcessSessionLeaderPID returns an attribute KeyValue conforming to the -// "process.session_leader.pid" semantic conventions. It represents the PID of -// the process's session leader. This is also the session ID (SID) of the -// process. -func ProcessSessionLeaderPID(val int) attribute.KeyValue { - return ProcessSessionLeaderPIDKey.Int(val) -} - -// ProcessTitle returns an attribute KeyValue conforming to the "process.title" -// semantic conventions. It represents the process title (proctitle). -func ProcessTitle(val string) attribute.KeyValue { - return ProcessTitleKey.String(val) -} - -// ProcessUserID returns an attribute KeyValue conforming to the -// "process.user.id" semantic conventions. It represents the effective user ID -// (EUID) of the process. -func ProcessUserID(val int) attribute.KeyValue { - return ProcessUserIDKey.Int(val) -} - -// ProcessUserName returns an attribute KeyValue conforming to the -// "process.user.name" semantic conventions. It represents the username of the -// effective user of the process. -func ProcessUserName(val string) attribute.KeyValue { - return ProcessUserNameKey.String(val) -} - -// ProcessVpid returns an attribute KeyValue conforming to the "process.vpid" -// semantic conventions. It represents the virtual process identifier. -func ProcessVpid(val int) attribute.KeyValue { - return ProcessVpidKey.Int(val) -} - -// ProcessWorkingDirectory returns an attribute KeyValue conforming to the -// "process.working_directory" semantic conventions. It represents the working -// directory of the process. -func ProcessWorkingDirectory(val string) attribute.KeyValue { - return ProcessWorkingDirectoryKey.String(val) -} - -// Enum values for process.context_switch_type -var ( - // voluntary - // Stability: development - ProcessContextSwitchTypeVoluntary = ProcessContextSwitchTypeKey.String("voluntary") - // involuntary - // Stability: development - ProcessContextSwitchTypeInvoluntary = ProcessContextSwitchTypeKey.String("involuntary") -) - -// Enum values for process.paging.fault_type -var ( - // major - // Stability: development - ProcessPagingFaultTypeMajor = ProcessPagingFaultTypeKey.String("major") - // minor - // Stability: development - ProcessPagingFaultTypeMinor = ProcessPagingFaultTypeKey.String("minor") -) - -// Namespace: profile -const ( - // ProfileFrameTypeKey is the attribute Key conforming to the - // "profile.frame.type" semantic conventions. It represents the describes the - // interpreter or compiler of a single frame. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "cpython" - ProfileFrameTypeKey = attribute.Key("profile.frame.type") -) - -// Enum values for profile.frame.type -var ( - // [.NET] - // - // Stability: development - // - // [.NET]: https://wikipedia.org/wiki/.NET - ProfileFrameTypeDotnet = ProfileFrameTypeKey.String("dotnet") - // [JVM] - // - // Stability: development - // - // [JVM]: https://wikipedia.org/wiki/Java_virtual_machine - ProfileFrameTypeJVM = ProfileFrameTypeKey.String("jvm") - // [Kernel] - // - // Stability: development - // - // [Kernel]: https://wikipedia.org/wiki/Kernel_(operating_system) - ProfileFrameTypeKernel = ProfileFrameTypeKey.String("kernel") - // [C], [C++], [Go], [Rust] - // - // Stability: development - // - // [C]: https://wikipedia.org/wiki/C_(programming_language) - // [C++]: https://wikipedia.org/wiki/C%2B%2B - // [Go]: https://wikipedia.org/wiki/Go_(programming_language) - // [Rust]: https://wikipedia.org/wiki/Rust_(programming_language) - ProfileFrameTypeNative = ProfileFrameTypeKey.String("native") - // [Perl] - // - // Stability: development - // - // [Perl]: https://wikipedia.org/wiki/Perl - ProfileFrameTypePerl = ProfileFrameTypeKey.String("perl") - // [PHP] - // - // Stability: development - // - // [PHP]: https://wikipedia.org/wiki/PHP - ProfileFrameTypePHP = ProfileFrameTypeKey.String("php") - // [Python] - // - // Stability: development - // - // [Python]: https://wikipedia.org/wiki/Python_(programming_language) - ProfileFrameTypeCpython = ProfileFrameTypeKey.String("cpython") - // [Ruby] - // - // Stability: development - // - // [Ruby]: https://wikipedia.org/wiki/Ruby_(programming_language) - ProfileFrameTypeRuby = ProfileFrameTypeKey.String("ruby") - // [V8JS] - // - // Stability: development - // - // [V8JS]: https://wikipedia.org/wiki/V8_(JavaScript_engine) - ProfileFrameTypeV8JS = ProfileFrameTypeKey.String("v8js") - // [Erlang] - // - // Stability: development - // - // [Erlang]: https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine) - ProfileFrameTypeBeam = ProfileFrameTypeKey.String("beam") -) - -// Namespace: rpc -const ( - // RPCConnectRPCErrorCodeKey is the attribute Key conforming to the - // "rpc.connect_rpc.error_code" semantic conventions. It represents the - // [error codes] of the Connect request. Error codes are always string values. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // - // [error codes]: https://connect.build/docs/protocol/#error-codes - RPCConnectRPCErrorCodeKey = attribute.Key("rpc.connect_rpc.error_code") - - // RPCGRPCStatusCodeKey is the attribute Key conforming to the - // "rpc.grpc.status_code" semantic conventions. It represents the - // [numeric status code] of the gRPC request. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // - // [numeric status code]: https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md - RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code") - - // RPCJsonrpcErrorCodeKey is the attribute Key conforming to the - // "rpc.jsonrpc.error_code" semantic conventions. It represents the `error.code` - // property of response if it is an error response. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: -32700, 100 - RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code") - - // RPCJsonrpcErrorMessageKey is the attribute Key conforming to the - // "rpc.jsonrpc.error_message" semantic conventions. It represents the - // `error.message` property of response if it is an error response. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Parse error", "User already exists" - RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message") - - // RPCJsonrpcRequestIDKey is the attribute Key conforming to the - // "rpc.jsonrpc.request_id" semantic conventions. It represents the `id` - // property of request or response. Since protocol allows id to be int, string, - // `null` or missing (for notifications), value is expected to be cast to string - // for simplicity. Use empty string in case of `null` value. Omit entirely if - // this is a notification. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "10", "request-7", "" - RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id") - - // RPCJsonrpcVersionKey is the attribute Key conforming to the - // "rpc.jsonrpc.version" semantic conventions. It represents the protocol - // version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 - // doesn't specify this, the value can be omitted. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2.0", "1.0" - RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version") - - // RPCMessageCompressedSizeKey is the attribute Key conforming to the - // "rpc.message.compressed_size" semantic conventions. It represents the - // compressed size of the message in bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - RPCMessageCompressedSizeKey = attribute.Key("rpc.message.compressed_size") - - // RPCMessageIDKey is the attribute Key conforming to the "rpc.message.id" - // semantic conventions. It represents the mUST be calculated as two different - // counters starting from `1` one for sent messages and one for received - // message. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: This way we guarantee that the values will be consistent between - // different implementations. - RPCMessageIDKey = attribute.Key("rpc.message.id") - - // RPCMessageTypeKey is the attribute Key conforming to the "rpc.message.type" - // semantic conventions. It represents the whether this is a received or sent - // message. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - RPCMessageTypeKey = attribute.Key("rpc.message.type") - - // RPCMessageUncompressedSizeKey is the attribute Key conforming to the - // "rpc.message.uncompressed_size" semantic conventions. It represents the - // uncompressed size of the message in bytes. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - RPCMessageUncompressedSizeKey = attribute.Key("rpc.message.uncompressed_size") - - // RPCMethodKey is the attribute Key conforming to the "rpc.method" semantic - // conventions. It represents the name of the (logical) method being called, - // must be equal to the $method part in the span name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: exampleMethod - // Note: This is the logical name of the method from the RPC interface - // perspective, which can be different from the name of any implementing - // method/function. The `code.function.name` attribute may be used to store the - // latter (e.g., method actually executing the call on the server side, RPC - // client stub method on the client side). - RPCMethodKey = attribute.Key("rpc.method") - - // RPCServiceKey is the attribute Key conforming to the "rpc.service" semantic - // conventions. It represents the full (logical) name of the service being - // called, including its package name, if applicable. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: myservice.EchoService - // Note: This is the logical name of the service from the RPC interface - // perspective, which can be different from the name of any implementing class. - // The `code.namespace` attribute may be used to store the latter (despite the - // attribute name, it may include a class name; e.g., class with method actually - // executing the call on the server side, RPC client stub class on the client - // side). - RPCServiceKey = attribute.Key("rpc.service") - - // RPCSystemKey is the attribute Key conforming to the "rpc.system" semantic - // conventions. It represents a string identifying the remoting system. See - // below for a list of well-known identifiers. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - RPCSystemKey = attribute.Key("rpc.system") -) - -// RPCJsonrpcErrorCode returns an attribute KeyValue conforming to the -// "rpc.jsonrpc.error_code" semantic conventions. It represents the `error.code` -// property of response if it is an error response. -func RPCJsonrpcErrorCode(val int) attribute.KeyValue { - return RPCJsonrpcErrorCodeKey.Int(val) -} - -// RPCJsonrpcErrorMessage returns an attribute KeyValue conforming to the -// "rpc.jsonrpc.error_message" semantic conventions. It represents the -// `error.message` property of response if it is an error response. -func RPCJsonrpcErrorMessage(val string) attribute.KeyValue { - return RPCJsonrpcErrorMessageKey.String(val) -} - -// RPCJsonrpcRequestID returns an attribute KeyValue conforming to the -// "rpc.jsonrpc.request_id" semantic conventions. It represents the `id` property -// of request or response. Since protocol allows id to be int, string, `null` or -// missing (for notifications), value is expected to be cast to string for -// simplicity. Use empty string in case of `null` value. Omit entirely if this is -// a notification. -func RPCJsonrpcRequestID(val string) attribute.KeyValue { - return RPCJsonrpcRequestIDKey.String(val) -} - -// RPCJsonrpcVersion returns an attribute KeyValue conforming to the -// "rpc.jsonrpc.version" semantic conventions. It represents the protocol version -// as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't -// specify this, the value can be omitted. -func RPCJsonrpcVersion(val string) attribute.KeyValue { - return RPCJsonrpcVersionKey.String(val) -} - -// RPCMessageCompressedSize returns an attribute KeyValue conforming to the -// "rpc.message.compressed_size" semantic conventions. It represents the -// compressed size of the message in bytes. -func RPCMessageCompressedSize(val int) attribute.KeyValue { - return RPCMessageCompressedSizeKey.Int(val) -} - -// RPCMessageID returns an attribute KeyValue conforming to the "rpc.message.id" -// semantic conventions. It represents the mUST be calculated as two different -// counters starting from `1` one for sent messages and one for received message. -func RPCMessageID(val int) attribute.KeyValue { - return RPCMessageIDKey.Int(val) -} - -// RPCMessageUncompressedSize returns an attribute KeyValue conforming to the -// "rpc.message.uncompressed_size" semantic conventions. It represents the -// uncompressed size of the message in bytes. -func RPCMessageUncompressedSize(val int) attribute.KeyValue { - return RPCMessageUncompressedSizeKey.Int(val) -} - -// RPCMethod returns an attribute KeyValue conforming to the "rpc.method" -// semantic conventions. It represents the name of the (logical) method being -// called, must be equal to the $method part in the span name. -func RPCMethod(val string) attribute.KeyValue { - return RPCMethodKey.String(val) -} - -// RPCService returns an attribute KeyValue conforming to the "rpc.service" -// semantic conventions. It represents the full (logical) name of the service -// being called, including its package name, if applicable. -func RPCService(val string) attribute.KeyValue { - return RPCServiceKey.String(val) -} - -// Enum values for rpc.connect_rpc.error_code -var ( - // cancelled - // Stability: development - RPCConnectRPCErrorCodeCancelled = RPCConnectRPCErrorCodeKey.String("cancelled") - // unknown - // Stability: development - RPCConnectRPCErrorCodeUnknown = RPCConnectRPCErrorCodeKey.String("unknown") - // invalid_argument - // Stability: development - RPCConnectRPCErrorCodeInvalidArgument = RPCConnectRPCErrorCodeKey.String("invalid_argument") - // deadline_exceeded - // Stability: development - RPCConnectRPCErrorCodeDeadlineExceeded = RPCConnectRPCErrorCodeKey.String("deadline_exceeded") - // not_found - // Stability: development - RPCConnectRPCErrorCodeNotFound = RPCConnectRPCErrorCodeKey.String("not_found") - // already_exists - // Stability: development - RPCConnectRPCErrorCodeAlreadyExists = RPCConnectRPCErrorCodeKey.String("already_exists") - // permission_denied - // Stability: development - RPCConnectRPCErrorCodePermissionDenied = RPCConnectRPCErrorCodeKey.String("permission_denied") - // resource_exhausted - // Stability: development - RPCConnectRPCErrorCodeResourceExhausted = RPCConnectRPCErrorCodeKey.String("resource_exhausted") - // failed_precondition - // Stability: development - RPCConnectRPCErrorCodeFailedPrecondition = RPCConnectRPCErrorCodeKey.String("failed_precondition") - // aborted - // Stability: development - RPCConnectRPCErrorCodeAborted = RPCConnectRPCErrorCodeKey.String("aborted") - // out_of_range - // Stability: development - RPCConnectRPCErrorCodeOutOfRange = RPCConnectRPCErrorCodeKey.String("out_of_range") - // unimplemented - // Stability: development - RPCConnectRPCErrorCodeUnimplemented = RPCConnectRPCErrorCodeKey.String("unimplemented") - // internal - // Stability: development - RPCConnectRPCErrorCodeInternal = RPCConnectRPCErrorCodeKey.String("internal") - // unavailable - // Stability: development - RPCConnectRPCErrorCodeUnavailable = RPCConnectRPCErrorCodeKey.String("unavailable") - // data_loss - // Stability: development - RPCConnectRPCErrorCodeDataLoss = RPCConnectRPCErrorCodeKey.String("data_loss") - // unauthenticated - // Stability: development - RPCConnectRPCErrorCodeUnauthenticated = RPCConnectRPCErrorCodeKey.String("unauthenticated") -) - -// Enum values for rpc.grpc.status_code -var ( - // OK - // Stability: development - RPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0) - // CANCELLED - // Stability: development - RPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1) - // UNKNOWN - // Stability: development - RPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2) - // INVALID_ARGUMENT - // Stability: development - RPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3) - // DEADLINE_EXCEEDED - // Stability: development - RPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4) - // NOT_FOUND - // Stability: development - RPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5) - // ALREADY_EXISTS - // Stability: development - RPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6) - // PERMISSION_DENIED - // Stability: development - RPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7) - // RESOURCE_EXHAUSTED - // Stability: development - RPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8) - // FAILED_PRECONDITION - // Stability: development - RPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9) - // ABORTED - // Stability: development - RPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10) - // OUT_OF_RANGE - // Stability: development - RPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11) - // UNIMPLEMENTED - // Stability: development - RPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12) - // INTERNAL - // Stability: development - RPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13) - // UNAVAILABLE - // Stability: development - RPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14) - // DATA_LOSS - // Stability: development - RPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15) - // UNAUTHENTICATED - // Stability: development - RPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16) -) - -// Enum values for rpc.message.type -var ( - // sent - // Stability: development - RPCMessageTypeSent = RPCMessageTypeKey.String("SENT") - // received - // Stability: development - RPCMessageTypeReceived = RPCMessageTypeKey.String("RECEIVED") -) - -// Enum values for rpc.system -var ( - // gRPC - // Stability: development - RPCSystemGRPC = RPCSystemKey.String("grpc") - // Java RMI - // Stability: development - RPCSystemJavaRmi = RPCSystemKey.String("java_rmi") - // .NET WCF - // Stability: development - RPCSystemDotnetWcf = RPCSystemKey.String("dotnet_wcf") - // Apache Dubbo - // Stability: development - RPCSystemApacheDubbo = RPCSystemKey.String("apache_dubbo") - // Connect RPC - // Stability: development - RPCSystemConnectRPC = RPCSystemKey.String("connect_rpc") -) - -// Namespace: security_rule -const ( - // SecurityRuleCategoryKey is the attribute Key conforming to the - // "security_rule.category" semantic conventions. It represents a categorization - // value keyword used by the entity using the rule for detection of this event. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Attempted Information Leak" - SecurityRuleCategoryKey = attribute.Key("security_rule.category") - - // SecurityRuleDescriptionKey is the attribute Key conforming to the - // "security_rule.description" semantic conventions. It represents the - // description of the rule generating the event. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Block requests to public DNS over HTTPS / TLS protocols" - SecurityRuleDescriptionKey = attribute.Key("security_rule.description") - - // SecurityRuleLicenseKey is the attribute Key conforming to the - // "security_rule.license" semantic conventions. It represents the name of the - // license under which the rule used to generate this event is made available. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Apache 2.0" - SecurityRuleLicenseKey = attribute.Key("security_rule.license") - - // SecurityRuleNameKey is the attribute Key conforming to the - // "security_rule.name" semantic conventions. It represents the name of the rule - // or signature generating the event. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "BLOCK_DNS_over_TLS" - SecurityRuleNameKey = attribute.Key("security_rule.name") - - // SecurityRuleReferenceKey is the attribute Key conforming to the - // "security_rule.reference" semantic conventions. It represents the reference - // URL to additional information about the rule used to generate this event. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "https://en.wikipedia.org/wiki/DNS_over_TLS" - // Note: The URL can point to the vendor’s documentation about the rule. If - // that’s not available, it can also be a link to a more general page - // describing this type of alert. - SecurityRuleReferenceKey = attribute.Key("security_rule.reference") - - // SecurityRuleRulesetNameKey is the attribute Key conforming to the - // "security_rule.ruleset.name" semantic conventions. It represents the name of - // the ruleset, policy, group, or parent category in which the rule used to - // generate this event is a member. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Standard_Protocol_Filters" - SecurityRuleRulesetNameKey = attribute.Key("security_rule.ruleset.name") - - // SecurityRuleUUIDKey is the attribute Key conforming to the - // "security_rule.uuid" semantic conventions. It represents a rule ID that is - // unique within the scope of a set or group of agents, observers, or other - // entities using the rule for detection of this event. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "550e8400-e29b-41d4-a716-446655440000", "1100110011" - SecurityRuleUUIDKey = attribute.Key("security_rule.uuid") - - // SecurityRuleVersionKey is the attribute Key conforming to the - // "security_rule.version" semantic conventions. It represents the version / - // revision of the rule being used for analysis. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1.0.0" - SecurityRuleVersionKey = attribute.Key("security_rule.version") -) - -// SecurityRuleCategory returns an attribute KeyValue conforming to the -// "security_rule.category" semantic conventions. It represents a categorization -// value keyword used by the entity using the rule for detection of this event. -func SecurityRuleCategory(val string) attribute.KeyValue { - return SecurityRuleCategoryKey.String(val) -} - -// SecurityRuleDescription returns an attribute KeyValue conforming to the -// "security_rule.description" semantic conventions. It represents the -// description of the rule generating the event. -func SecurityRuleDescription(val string) attribute.KeyValue { - return SecurityRuleDescriptionKey.String(val) -} - -// SecurityRuleLicense returns an attribute KeyValue conforming to the -// "security_rule.license" semantic conventions. It represents the name of the -// license under which the rule used to generate this event is made available. -func SecurityRuleLicense(val string) attribute.KeyValue { - return SecurityRuleLicenseKey.String(val) -} - -// SecurityRuleName returns an attribute KeyValue conforming to the -// "security_rule.name" semantic conventions. It represents the name of the rule -// or signature generating the event. -func SecurityRuleName(val string) attribute.KeyValue { - return SecurityRuleNameKey.String(val) -} - -// SecurityRuleReference returns an attribute KeyValue conforming to the -// "security_rule.reference" semantic conventions. It represents the reference -// URL to additional information about the rule used to generate this event. -func SecurityRuleReference(val string) attribute.KeyValue { - return SecurityRuleReferenceKey.String(val) -} - -// SecurityRuleRulesetName returns an attribute KeyValue conforming to the -// "security_rule.ruleset.name" semantic conventions. It represents the name of -// the ruleset, policy, group, or parent category in which the rule used to -// generate this event is a member. -func SecurityRuleRulesetName(val string) attribute.KeyValue { - return SecurityRuleRulesetNameKey.String(val) -} - -// SecurityRuleUUID returns an attribute KeyValue conforming to the -// "security_rule.uuid" semantic conventions. It represents a rule ID that is -// unique within the scope of a set or group of agents, observers, or other -// entities using the rule for detection of this event. -func SecurityRuleUUID(val string) attribute.KeyValue { - return SecurityRuleUUIDKey.String(val) -} - -// SecurityRuleVersion returns an attribute KeyValue conforming to the -// "security_rule.version" semantic conventions. It represents the version / -// revision of the rule being used for analysis. -func SecurityRuleVersion(val string) attribute.KeyValue { - return SecurityRuleVersionKey.String(val) -} - -// Namespace: server -const ( - // ServerAddressKey is the attribute Key conforming to the "server.address" - // semantic conventions. It represents the server domain name if available - // without reverse DNS lookup; otherwise, IP address or Unix domain socket name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "example.com", "10.1.2.80", "/tmp/my.sock" - // Note: When observed from the client side, and when communicating through an - // intermediary, `server.address` SHOULD represent the server address behind any - // intermediaries, for example proxies, if it's available. - ServerAddressKey = attribute.Key("server.address") - - // ServerPortKey is the attribute Key conforming to the "server.port" semantic - // conventions. It represents the server port number. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: 80, 8080, 443 - // Note: When observed from the client side, and when communicating through an - // intermediary, `server.port` SHOULD represent the server port behind any - // intermediaries, for example proxies, if it's available. - ServerPortKey = attribute.Key("server.port") -) - -// ServerAddress returns an attribute KeyValue conforming to the "server.address" -// semantic conventions. It represents the server domain name if available -// without reverse DNS lookup; otherwise, IP address or Unix domain socket name. -func ServerAddress(val string) attribute.KeyValue { - return ServerAddressKey.String(val) -} - -// ServerPort returns an attribute KeyValue conforming to the "server.port" -// semantic conventions. It represents the server port number. -func ServerPort(val int) attribute.KeyValue { - return ServerPortKey.Int(val) -} - -// Namespace: service -const ( - // ServiceInstanceIDKey is the attribute Key conforming to the - // "service.instance.id" semantic conventions. It represents the string ID of - // the service instance. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "627cc493-f310-47de-96bd-71410b7dec09" - // Note: MUST be unique for each instance of the same - // `service.namespace,service.name` pair (in other words - // `service.namespace,service.name,service.instance.id` triplet MUST be globally - // unique). The ID helps to - // distinguish instances of the same service that exist at the same time (e.g. - // instances of a horizontally scaled - // service). - // - // Implementations, such as SDKs, are recommended to generate a random Version 1 - // or Version 4 [RFC - // 4122] UUID, but are free to use an inherent unique ID as - // the source of - // this value if stability is desirable. In that case, the ID SHOULD be used as - // source of a UUID Version 5 and - // SHOULD use the following UUID as the namespace: - // `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. - // - // UUIDs are typically recommended, as only an opaque value for the purposes of - // identifying a service instance is - // needed. Similar to what can be seen in the man page for the - // [`/etc/machine-id`] file, the underlying - // data, such as pod name and namespace should be treated as confidential, being - // the user's choice to expose it - // or not via another resource attribute. - // - // For applications running behind an application server (like unicorn), we do - // not recommend using one identifier - // for all processes participating in the application. Instead, it's recommended - // each division (e.g. a worker - // thread in unicorn) to have its own instance.id. - // - // It's not recommended for a Collector to set `service.instance.id` if it can't - // unambiguously determine the - // service instance that is generating that telemetry. For instance, creating an - // UUID based on `pod.name` will - // likely be wrong, as the Collector might not know from which container within - // that pod the telemetry originated. - // However, Collectors can set the `service.instance.id` if they can - // unambiguously determine the service instance - // for that telemetry. This is typically the case for scraping receivers, as - // they know the target address and - // port. - // - // [RFC - // 4122]: https://www.ietf.org/rfc/rfc4122.txt - // [`/etc/machine-id`]: https://www.freedesktop.org/software/systemd/man/latest/machine-id.html - ServiceInstanceIDKey = attribute.Key("service.instance.id") - - // ServiceNameKey is the attribute Key conforming to the "service.name" semantic - // conventions. It represents the logical name of the service. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "shoppingcart" - // Note: MUST be the same for all instances of horizontally scaled services. If - // the value was not specified, SDKs MUST fallback to `unknown_service:` - // concatenated with [`process.executable.name`], e.g. `unknown_service:bash`. - // If `process.executable.name` is not available, the value MUST be set to - // `unknown_service`. - // - // [`process.executable.name`]: process.md - ServiceNameKey = attribute.Key("service.name") - - // ServiceNamespaceKey is the attribute Key conforming to the - // "service.namespace" semantic conventions. It represents a namespace for - // `service.name`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Shop" - // Note: A string value having a meaning that helps to distinguish a group of - // services, for example the team name that owns a group of services. - // `service.name` is expected to be unique within the same namespace. If - // `service.namespace` is not specified in the Resource then `service.name` is - // expected to be unique for all services that have no explicit namespace - // defined (so the empty/unspecified namespace is simply one more valid - // namespace). Zero-length namespace string is assumed equal to unspecified - // namespace. - ServiceNamespaceKey = attribute.Key("service.namespace") - - // ServiceVersionKey is the attribute Key conforming to the "service.version" - // semantic conventions. It represents the version string of the service API or - // implementation. The format is not defined by these conventions. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "2.0.0", "a01dbef8a" - ServiceVersionKey = attribute.Key("service.version") -) - -// ServiceInstanceID returns an attribute KeyValue conforming to the -// "service.instance.id" semantic conventions. It represents the string ID of the -// service instance. -func ServiceInstanceID(val string) attribute.KeyValue { - return ServiceInstanceIDKey.String(val) -} - -// ServiceName returns an attribute KeyValue conforming to the "service.name" -// semantic conventions. It represents the logical name of the service. -func ServiceName(val string) attribute.KeyValue { - return ServiceNameKey.String(val) -} - -// ServiceNamespace returns an attribute KeyValue conforming to the -// "service.namespace" semantic conventions. It represents a namespace for -// `service.name`. -func ServiceNamespace(val string) attribute.KeyValue { - return ServiceNamespaceKey.String(val) -} - -// ServiceVersion returns an attribute KeyValue conforming to the -// "service.version" semantic conventions. It represents the version string of -// the service API or implementation. The format is not defined by these -// conventions. -func ServiceVersion(val string) attribute.KeyValue { - return ServiceVersionKey.String(val) -} - -// Namespace: session -const ( - // SessionIDKey is the attribute Key conforming to the "session.id" semantic - // conventions. It represents a unique id to identify a session. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 00112233-4455-6677-8899-aabbccddeeff - SessionIDKey = attribute.Key("session.id") - - // SessionPreviousIDKey is the attribute Key conforming to the - // "session.previous_id" semantic conventions. It represents the previous - // `session.id` for this user, when known. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 00112233-4455-6677-8899-aabbccddeeff - SessionPreviousIDKey = attribute.Key("session.previous_id") -) - -// SessionID returns an attribute KeyValue conforming to the "session.id" -// semantic conventions. It represents a unique id to identify a session. -func SessionID(val string) attribute.KeyValue { - return SessionIDKey.String(val) -} - -// SessionPreviousID returns an attribute KeyValue conforming to the -// "session.previous_id" semantic conventions. It represents the previous -// `session.id` for this user, when known. -func SessionPreviousID(val string) attribute.KeyValue { - return SessionPreviousIDKey.String(val) -} - -// Namespace: signalr -const ( - // SignalrConnectionStatusKey is the attribute Key conforming to the - // "signalr.connection.status" semantic conventions. It represents the signalR - // HTTP connection closure status. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "app_shutdown", "timeout" - SignalrConnectionStatusKey = attribute.Key("signalr.connection.status") - - // SignalrTransportKey is the attribute Key conforming to the - // "signalr.transport" semantic conventions. It represents the - // [SignalR transport type]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "web_sockets", "long_polling" - // - // [SignalR transport type]: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md - SignalrTransportKey = attribute.Key("signalr.transport") -) - -// Enum values for signalr.connection.status -var ( - // The connection was closed normally. - // Stability: stable - SignalrConnectionStatusNormalClosure = SignalrConnectionStatusKey.String("normal_closure") - // The connection was closed due to a timeout. - // Stability: stable - SignalrConnectionStatusTimeout = SignalrConnectionStatusKey.String("timeout") - // The connection was closed because the app is shutting down. - // Stability: stable - SignalrConnectionStatusAppShutdown = SignalrConnectionStatusKey.String("app_shutdown") -) - -// Enum values for signalr.transport -var ( - // ServerSentEvents protocol - // Stability: stable - SignalrTransportServerSentEvents = SignalrTransportKey.String("server_sent_events") - // LongPolling protocol - // Stability: stable - SignalrTransportLongPolling = SignalrTransportKey.String("long_polling") - // WebSockets protocol - // Stability: stable - SignalrTransportWebSockets = SignalrTransportKey.String("web_sockets") -) - -// Namespace: source -const ( - // SourceAddressKey is the attribute Key conforming to the "source.address" - // semantic conventions. It represents the source address - domain name if - // available without reverse DNS lookup; otherwise, IP address or Unix domain - // socket name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "source.example.com", "10.1.2.80", "/tmp/my.sock" - // Note: When observed from the destination side, and when communicating through - // an intermediary, `source.address` SHOULD represent the source address behind - // any intermediaries, for example proxies, if it's available. - SourceAddressKey = attribute.Key("source.address") - - // SourcePortKey is the attribute Key conforming to the "source.port" semantic - // conventions. It represents the source port number. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 3389, 2888 - SourcePortKey = attribute.Key("source.port") -) - -// SourceAddress returns an attribute KeyValue conforming to the "source.address" -// semantic conventions. It represents the source address - domain name if -// available without reverse DNS lookup; otherwise, IP address or Unix domain -// socket name. -func SourceAddress(val string) attribute.KeyValue { - return SourceAddressKey.String(val) -} - -// SourcePort returns an attribute KeyValue conforming to the "source.port" -// semantic conventions. It represents the source port number. -func SourcePort(val int) attribute.KeyValue { - return SourcePortKey.Int(val) -} - -// Namespace: system -const ( - // SystemCPULogicalNumberKey is the attribute Key conforming to the - // "system.cpu.logical_number" semantic conventions. It represents the logical - // CPU number [0..n-1]. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 1 - SystemCPULogicalNumberKey = attribute.Key("system.cpu.logical_number") - - // SystemDeviceKey is the attribute Key conforming to the "system.device" - // semantic conventions. It represents the device identifier. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "(identifier)" - SystemDeviceKey = attribute.Key("system.device") - - // SystemFilesystemModeKey is the attribute Key conforming to the - // "system.filesystem.mode" semantic conventions. It represents the filesystem - // mode. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "rw, ro" - SystemFilesystemModeKey = attribute.Key("system.filesystem.mode") - - // SystemFilesystemMountpointKey is the attribute Key conforming to the - // "system.filesystem.mountpoint" semantic conventions. It represents the - // filesystem mount path. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/mnt/data" - SystemFilesystemMountpointKey = attribute.Key("system.filesystem.mountpoint") - - // SystemFilesystemStateKey is the attribute Key conforming to the - // "system.filesystem.state" semantic conventions. It represents the filesystem - // state. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "used" - SystemFilesystemStateKey = attribute.Key("system.filesystem.state") - - // SystemFilesystemTypeKey is the attribute Key conforming to the - // "system.filesystem.type" semantic conventions. It represents the filesystem - // type. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "ext4" - SystemFilesystemTypeKey = attribute.Key("system.filesystem.type") - - // SystemMemoryStateKey is the attribute Key conforming to the - // "system.memory.state" semantic conventions. It represents the memory state. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "free", "cached" - SystemMemoryStateKey = attribute.Key("system.memory.state") - - // SystemPagingDirectionKey is the attribute Key conforming to the - // "system.paging.direction" semantic conventions. It represents the paging - // access direction. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "in" - SystemPagingDirectionKey = attribute.Key("system.paging.direction") - - // SystemPagingStateKey is the attribute Key conforming to the - // "system.paging.state" semantic conventions. It represents the memory paging - // state. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "free" - SystemPagingStateKey = attribute.Key("system.paging.state") - - // SystemPagingTypeKey is the attribute Key conforming to the - // "system.paging.type" semantic conventions. It represents the memory paging - // type. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "minor" - SystemPagingTypeKey = attribute.Key("system.paging.type") - - // SystemProcessStatusKey is the attribute Key conforming to the - // "system.process.status" semantic conventions. It represents the process - // state, e.g., [Linux Process State Codes]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "running" - // - // [Linux Process State Codes]: https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES - SystemProcessStatusKey = attribute.Key("system.process.status") -) - -// SystemCPULogicalNumber returns an attribute KeyValue conforming to the -// "system.cpu.logical_number" semantic conventions. It represents the logical -// CPU number [0..n-1]. -func SystemCPULogicalNumber(val int) attribute.KeyValue { - return SystemCPULogicalNumberKey.Int(val) -} - -// SystemDevice returns an attribute KeyValue conforming to the "system.device" -// semantic conventions. It represents the device identifier. -func SystemDevice(val string) attribute.KeyValue { - return SystemDeviceKey.String(val) -} - -// SystemFilesystemMode returns an attribute KeyValue conforming to the -// "system.filesystem.mode" semantic conventions. It represents the filesystem -// mode. -func SystemFilesystemMode(val string) attribute.KeyValue { - return SystemFilesystemModeKey.String(val) -} - -// SystemFilesystemMountpoint returns an attribute KeyValue conforming to the -// "system.filesystem.mountpoint" semantic conventions. It represents the -// filesystem mount path. -func SystemFilesystemMountpoint(val string) attribute.KeyValue { - return SystemFilesystemMountpointKey.String(val) -} - -// Enum values for system.filesystem.state -var ( - // used - // Stability: development - SystemFilesystemStateUsed = SystemFilesystemStateKey.String("used") - // free - // Stability: development - SystemFilesystemStateFree = SystemFilesystemStateKey.String("free") - // reserved - // Stability: development - SystemFilesystemStateReserved = SystemFilesystemStateKey.String("reserved") -) - -// Enum values for system.filesystem.type -var ( - // fat32 - // Stability: development - SystemFilesystemTypeFat32 = SystemFilesystemTypeKey.String("fat32") - // exfat - // Stability: development - SystemFilesystemTypeExfat = SystemFilesystemTypeKey.String("exfat") - // ntfs - // Stability: development - SystemFilesystemTypeNtfs = SystemFilesystemTypeKey.String("ntfs") - // refs - // Stability: development - SystemFilesystemTypeRefs = SystemFilesystemTypeKey.String("refs") - // hfsplus - // Stability: development - SystemFilesystemTypeHfsplus = SystemFilesystemTypeKey.String("hfsplus") - // ext4 - // Stability: development - SystemFilesystemTypeExt4 = SystemFilesystemTypeKey.String("ext4") -) - -// Enum values for system.memory.state -var ( - // used - // Stability: development - SystemMemoryStateUsed = SystemMemoryStateKey.String("used") - // free - // Stability: development - SystemMemoryStateFree = SystemMemoryStateKey.String("free") - // Deprecated: Removed, report shared memory usage with - // `metric.system.memory.shared` metric. - SystemMemoryStateShared = SystemMemoryStateKey.String("shared") - // buffers - // Stability: development - SystemMemoryStateBuffers = SystemMemoryStateKey.String("buffers") - // cached - // Stability: development - SystemMemoryStateCached = SystemMemoryStateKey.String("cached") -) - -// Enum values for system.paging.direction -var ( - // in - // Stability: development - SystemPagingDirectionIn = SystemPagingDirectionKey.String("in") - // out - // Stability: development - SystemPagingDirectionOut = SystemPagingDirectionKey.String("out") -) - -// Enum values for system.paging.state -var ( - // used - // Stability: development - SystemPagingStateUsed = SystemPagingStateKey.String("used") - // free - // Stability: development - SystemPagingStateFree = SystemPagingStateKey.String("free") -) - -// Enum values for system.paging.type -var ( - // major - // Stability: development - SystemPagingTypeMajor = SystemPagingTypeKey.String("major") - // minor - // Stability: development - SystemPagingTypeMinor = SystemPagingTypeKey.String("minor") -) - -// Enum values for system.process.status -var ( - // running - // Stability: development - SystemProcessStatusRunning = SystemProcessStatusKey.String("running") - // sleeping - // Stability: development - SystemProcessStatusSleeping = SystemProcessStatusKey.String("sleeping") - // stopped - // Stability: development - SystemProcessStatusStopped = SystemProcessStatusKey.String("stopped") - // defunct - // Stability: development - SystemProcessStatusDefunct = SystemProcessStatusKey.String("defunct") -) - -// Namespace: telemetry -const ( - // TelemetryDistroNameKey is the attribute Key conforming to the - // "telemetry.distro.name" semantic conventions. It represents the name of the - // auto instrumentation agent or distribution, if used. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "parts-unlimited-java" - // Note: Official auto instrumentation agents and distributions SHOULD set the - // `telemetry.distro.name` attribute to - // a string starting with `opentelemetry-`, e.g. - // `opentelemetry-java-instrumentation`. - TelemetryDistroNameKey = attribute.Key("telemetry.distro.name") - - // TelemetryDistroVersionKey is the attribute Key conforming to the - // "telemetry.distro.version" semantic conventions. It represents the version - // string of the auto instrumentation agent or distribution, if used. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1.2.3" - TelemetryDistroVersionKey = attribute.Key("telemetry.distro.version") - - // TelemetrySDKLanguageKey is the attribute Key conforming to the - // "telemetry.sdk.language" semantic conventions. It represents the language of - // the telemetry SDK. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: - TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language") - - // TelemetrySDKNameKey is the attribute Key conforming to the - // "telemetry.sdk.name" semantic conventions. It represents the name of the - // telemetry SDK as defined above. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "opentelemetry" - // Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to - // `opentelemetry`. - // If another SDK, like a fork or a vendor-provided implementation, is used, - // this SDK MUST set the - // `telemetry.sdk.name` attribute to the fully-qualified class or module name of - // this SDK's main entry point - // or another suitable identifier depending on the language. - // The identifier `opentelemetry` is reserved and MUST NOT be used in this case. - // All custom identifiers SHOULD be stable across different versions of an - // implementation. - TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name") - - // TelemetrySDKVersionKey is the attribute Key conforming to the - // "telemetry.sdk.version" semantic conventions. It represents the version - // string of the telemetry SDK. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "1.2.3" - TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version") -) - -// TelemetryDistroName returns an attribute KeyValue conforming to the -// "telemetry.distro.name" semantic conventions. It represents the name of the -// auto instrumentation agent or distribution, if used. -func TelemetryDistroName(val string) attribute.KeyValue { - return TelemetryDistroNameKey.String(val) -} - -// TelemetryDistroVersion returns an attribute KeyValue conforming to the -// "telemetry.distro.version" semantic conventions. It represents the version -// string of the auto instrumentation agent or distribution, if used. -func TelemetryDistroVersion(val string) attribute.KeyValue { - return TelemetryDistroVersionKey.String(val) -} - -// TelemetrySDKName returns an attribute KeyValue conforming to the -// "telemetry.sdk.name" semantic conventions. It represents the name of the -// telemetry SDK as defined above. -func TelemetrySDKName(val string) attribute.KeyValue { - return TelemetrySDKNameKey.String(val) -} - -// TelemetrySDKVersion returns an attribute KeyValue conforming to the -// "telemetry.sdk.version" semantic conventions. It represents the version string -// of the telemetry SDK. -func TelemetrySDKVersion(val string) attribute.KeyValue { - return TelemetrySDKVersionKey.String(val) -} - -// Enum values for telemetry.sdk.language -var ( - // cpp - // Stability: stable - TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp") - // dotnet - // Stability: stable - TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet") - // erlang - // Stability: stable - TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang") - // go - // Stability: stable - TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go") - // java - // Stability: stable - TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java") - // nodejs - // Stability: stable - TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs") - // php - // Stability: stable - TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php") - // python - // Stability: stable - TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python") - // ruby - // Stability: stable - TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby") - // rust - // Stability: stable - TelemetrySDKLanguageRust = TelemetrySDKLanguageKey.String("rust") - // swift - // Stability: stable - TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift") - // webjs - // Stability: stable - TelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String("webjs") -) - -// Namespace: test -const ( - // TestCaseNameKey is the attribute Key conforming to the "test.case.name" - // semantic conventions. It represents the fully qualified human readable name - // of the [test case]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "org.example.TestCase1.test1", "example/tests/TestCase1.test1", - // "ExampleTestCase1_test1" - // - // [test case]: https://wikipedia.org/wiki/Test_case - TestCaseNameKey = attribute.Key("test.case.name") - - // TestCaseResultStatusKey is the attribute Key conforming to the - // "test.case.result.status" semantic conventions. It represents the status of - // the actual test case result from test execution. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "pass", "fail" - TestCaseResultStatusKey = attribute.Key("test.case.result.status") - - // TestSuiteNameKey is the attribute Key conforming to the "test.suite.name" - // semantic conventions. It represents the human readable name of a [test suite] - // . - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "TestSuite1" - // - // [test suite]: https://wikipedia.org/wiki/Test_suite - TestSuiteNameKey = attribute.Key("test.suite.name") - - // TestSuiteRunStatusKey is the attribute Key conforming to the - // "test.suite.run.status" semantic conventions. It represents the status of the - // test suite run. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "success", "failure", "skipped", "aborted", "timed_out", - // "in_progress" - TestSuiteRunStatusKey = attribute.Key("test.suite.run.status") -) - -// TestCaseName returns an attribute KeyValue conforming to the "test.case.name" -// semantic conventions. It represents the fully qualified human readable name of -// the [test case]. -// -// [test case]: https://wikipedia.org/wiki/Test_case -func TestCaseName(val string) attribute.KeyValue { - return TestCaseNameKey.String(val) -} - -// TestSuiteName returns an attribute KeyValue conforming to the -// "test.suite.name" semantic conventions. It represents the human readable name -// of a [test suite]. -// -// [test suite]: https://wikipedia.org/wiki/Test_suite -func TestSuiteName(val string) attribute.KeyValue { - return TestSuiteNameKey.String(val) -} - -// Enum values for test.case.result.status -var ( - // pass - // Stability: development - TestCaseResultStatusPass = TestCaseResultStatusKey.String("pass") - // fail - // Stability: development - TestCaseResultStatusFail = TestCaseResultStatusKey.String("fail") -) - -// Enum values for test.suite.run.status -var ( - // success - // Stability: development - TestSuiteRunStatusSuccess = TestSuiteRunStatusKey.String("success") - // failure - // Stability: development - TestSuiteRunStatusFailure = TestSuiteRunStatusKey.String("failure") - // skipped - // Stability: development - TestSuiteRunStatusSkipped = TestSuiteRunStatusKey.String("skipped") - // aborted - // Stability: development - TestSuiteRunStatusAborted = TestSuiteRunStatusKey.String("aborted") - // timed_out - // Stability: development - TestSuiteRunStatusTimedOut = TestSuiteRunStatusKey.String("timed_out") - // in_progress - // Stability: development - TestSuiteRunStatusInProgress = TestSuiteRunStatusKey.String("in_progress") -) - -// Namespace: thread -const ( - // ThreadIDKey is the attribute Key conforming to the "thread.id" semantic - // conventions. It represents the current "managed" thread ID (as opposed to OS - // thread ID). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - ThreadIDKey = attribute.Key("thread.id") - - // ThreadNameKey is the attribute Key conforming to the "thread.name" semantic - // conventions. It represents the current thread name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: main - ThreadNameKey = attribute.Key("thread.name") -) - -// ThreadID returns an attribute KeyValue conforming to the "thread.id" semantic -// conventions. It represents the current "managed" thread ID (as opposed to OS -// thread ID). -func ThreadID(val int) attribute.KeyValue { - return ThreadIDKey.Int(val) -} - -// ThreadName returns an attribute KeyValue conforming to the "thread.name" -// semantic conventions. It represents the current thread name. -func ThreadName(val string) attribute.KeyValue { - return ThreadNameKey.String(val) -} - -// Namespace: tls -const ( - // TLSCipherKey is the attribute Key conforming to the "tls.cipher" semantic - // conventions. It represents the string indicating the [cipher] used during the - // current connection. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "TLS_RSA_WITH_3DES_EDE_CBC_SHA", - // "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" - // Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions` - // of the [registered TLS Cipher Suits]. - // - // [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5 - // [registered TLS Cipher Suits]: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4 - TLSCipherKey = attribute.Key("tls.cipher") - - // TLSClientCertificateKey is the attribute Key conforming to the - // "tls.client.certificate" semantic conventions. It represents the pEM-encoded - // stand-alone certificate offered by the client. This is usually - // mutually-exclusive of `client.certificate_chain` since this value also exists - // in that list. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "MII..." - TLSClientCertificateKey = attribute.Key("tls.client.certificate") - - // TLSClientCertificateChainKey is the attribute Key conforming to the - // "tls.client.certificate_chain" semantic conventions. It represents the array - // of PEM-encoded certificates that make up the certificate chain offered by the - // client. This is usually mutually-exclusive of `client.certificate` since that - // value should be the first certificate in the chain. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "MII...", "MI..." - TLSClientCertificateChainKey = attribute.Key("tls.client.certificate_chain") - - // TLSClientHashMd5Key is the attribute Key conforming to the - // "tls.client.hash.md5" semantic conventions. It represents the certificate - // fingerprint using the MD5 digest of DER-encoded version of certificate - // offered by the client. For consistency with other hash values, this value - // should be formatted as an uppercase hash. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC" - TLSClientHashMd5Key = attribute.Key("tls.client.hash.md5") - - // TLSClientHashSha1Key is the attribute Key conforming to the - // "tls.client.hash.sha1" semantic conventions. It represents the certificate - // fingerprint using the SHA1 digest of DER-encoded version of certificate - // offered by the client. For consistency with other hash values, this value - // should be formatted as an uppercase hash. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "9E393D93138888D288266C2D915214D1D1CCEB2A" - TLSClientHashSha1Key = attribute.Key("tls.client.hash.sha1") - - // TLSClientHashSha256Key is the attribute Key conforming to the - // "tls.client.hash.sha256" semantic conventions. It represents the certificate - // fingerprint using the SHA256 digest of DER-encoded version of certificate - // offered by the client. For consistency with other hash values, this value - // should be formatted as an uppercase hash. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0" - TLSClientHashSha256Key = attribute.Key("tls.client.hash.sha256") - - // TLSClientIssuerKey is the attribute Key conforming to the "tls.client.issuer" - // semantic conventions. It represents the distinguished name of [subject] of - // the issuer of the x.509 certificate presented by the client. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com" - // - // [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6 - TLSClientIssuerKey = attribute.Key("tls.client.issuer") - - // TLSClientJa3Key is the attribute Key conforming to the "tls.client.ja3" - // semantic conventions. It represents a hash that identifies clients based on - // how they perform an SSL/TLS handshake. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "d4e5b18d6b55c71272893221c96ba240" - TLSClientJa3Key = attribute.Key("tls.client.ja3") - - // TLSClientNotAfterKey is the attribute Key conforming to the - // "tls.client.not_after" semantic conventions. It represents the date/Time - // indicating when client certificate is no longer considered valid. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021-01-01T00:00:00.000Z" - TLSClientNotAfterKey = attribute.Key("tls.client.not_after") - - // TLSClientNotBeforeKey is the attribute Key conforming to the - // "tls.client.not_before" semantic conventions. It represents the date/Time - // indicating when client certificate is first considered valid. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1970-01-01T00:00:00.000Z" - TLSClientNotBeforeKey = attribute.Key("tls.client.not_before") - - // TLSClientSubjectKey is the attribute Key conforming to the - // "tls.client.subject" semantic conventions. It represents the distinguished - // name of subject of the x.509 certificate presented by the client. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "CN=myclient, OU=Documentation Team, DC=example, DC=com" - TLSClientSubjectKey = attribute.Key("tls.client.subject") - - // TLSClientSupportedCiphersKey is the attribute Key conforming to the - // "tls.client.supported_ciphers" semantic conventions. It represents the array - // of ciphers offered by the client during the client hello. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - // "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" - TLSClientSupportedCiphersKey = attribute.Key("tls.client.supported_ciphers") - - // TLSCurveKey is the attribute Key conforming to the "tls.curve" semantic - // conventions. It represents the string indicating the curve used for the given - // cipher, when applicable. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "secp256r1" - TLSCurveKey = attribute.Key("tls.curve") - - // TLSEstablishedKey is the attribute Key conforming to the "tls.established" - // semantic conventions. It represents the boolean flag indicating if the TLS - // negotiation was successful and transitioned to an encrypted tunnel. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: true - TLSEstablishedKey = attribute.Key("tls.established") - - // TLSNextProtocolKey is the attribute Key conforming to the "tls.next_protocol" - // semantic conventions. It represents the string indicating the protocol being - // tunneled. Per the values in the [IANA registry], this string should be lower - // case. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "http/1.1" - // - // [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids - TLSNextProtocolKey = attribute.Key("tls.next_protocol") - - // TLSProtocolNameKey is the attribute Key conforming to the "tls.protocol.name" - // semantic conventions. It represents the normalized lowercase protocol name - // parsed from original string of the negotiated [SSL/TLS protocol version]. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // - // [SSL/TLS protocol version]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES - TLSProtocolNameKey = attribute.Key("tls.protocol.name") - - // TLSProtocolVersionKey is the attribute Key conforming to the - // "tls.protocol.version" semantic conventions. It represents the numeric part - // of the version parsed from the original string of the negotiated - // [SSL/TLS protocol version]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1.2", "3" - // - // [SSL/TLS protocol version]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES - TLSProtocolVersionKey = attribute.Key("tls.protocol.version") - - // TLSResumedKey is the attribute Key conforming to the "tls.resumed" semantic - // conventions. It represents the boolean flag indicating if this TLS connection - // was resumed from an existing TLS negotiation. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: true - TLSResumedKey = attribute.Key("tls.resumed") - - // TLSServerCertificateKey is the attribute Key conforming to the - // "tls.server.certificate" semantic conventions. It represents the pEM-encoded - // stand-alone certificate offered by the server. This is usually - // mutually-exclusive of `server.certificate_chain` since this value also exists - // in that list. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "MII..." - TLSServerCertificateKey = attribute.Key("tls.server.certificate") - - // TLSServerCertificateChainKey is the attribute Key conforming to the - // "tls.server.certificate_chain" semantic conventions. It represents the array - // of PEM-encoded certificates that make up the certificate chain offered by the - // server. This is usually mutually-exclusive of `server.certificate` since that - // value should be the first certificate in the chain. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "MII...", "MI..." - TLSServerCertificateChainKey = attribute.Key("tls.server.certificate_chain") - - // TLSServerHashMd5Key is the attribute Key conforming to the - // "tls.server.hash.md5" semantic conventions. It represents the certificate - // fingerprint using the MD5 digest of DER-encoded version of certificate - // offered by the server. For consistency with other hash values, this value - // should be formatted as an uppercase hash. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC" - TLSServerHashMd5Key = attribute.Key("tls.server.hash.md5") - - // TLSServerHashSha1Key is the attribute Key conforming to the - // "tls.server.hash.sha1" semantic conventions. It represents the certificate - // fingerprint using the SHA1 digest of DER-encoded version of certificate - // offered by the server. For consistency with other hash values, this value - // should be formatted as an uppercase hash. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "9E393D93138888D288266C2D915214D1D1CCEB2A" - TLSServerHashSha1Key = attribute.Key("tls.server.hash.sha1") - - // TLSServerHashSha256Key is the attribute Key conforming to the - // "tls.server.hash.sha256" semantic conventions. It represents the certificate - // fingerprint using the SHA256 digest of DER-encoded version of certificate - // offered by the server. For consistency with other hash values, this value - // should be formatted as an uppercase hash. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0" - TLSServerHashSha256Key = attribute.Key("tls.server.hash.sha256") - - // TLSServerIssuerKey is the attribute Key conforming to the "tls.server.issuer" - // semantic conventions. It represents the distinguished name of [subject] of - // the issuer of the x.509 certificate presented by the client. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com" - // - // [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6 - TLSServerIssuerKey = attribute.Key("tls.server.issuer") - - // TLSServerJa3sKey is the attribute Key conforming to the "tls.server.ja3s" - // semantic conventions. It represents a hash that identifies servers based on - // how they perform an SSL/TLS handshake. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "d4e5b18d6b55c71272893221c96ba240" - TLSServerJa3sKey = attribute.Key("tls.server.ja3s") - - // TLSServerNotAfterKey is the attribute Key conforming to the - // "tls.server.not_after" semantic conventions. It represents the date/Time - // indicating when server certificate is no longer considered valid. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2021-01-01T00:00:00.000Z" - TLSServerNotAfterKey = attribute.Key("tls.server.not_after") - - // TLSServerNotBeforeKey is the attribute Key conforming to the - // "tls.server.not_before" semantic conventions. It represents the date/Time - // indicating when server certificate is first considered valid. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1970-01-01T00:00:00.000Z" - TLSServerNotBeforeKey = attribute.Key("tls.server.not_before") - - // TLSServerSubjectKey is the attribute Key conforming to the - // "tls.server.subject" semantic conventions. It represents the distinguished - // name of subject of the x.509 certificate presented by the server. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "CN=myserver, OU=Documentation Team, DC=example, DC=com" - TLSServerSubjectKey = attribute.Key("tls.server.subject") -) - -// TLSCipher returns an attribute KeyValue conforming to the "tls.cipher" -// semantic conventions. It represents the string indicating the [cipher] used -// during the current connection. -// -// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5 -func TLSCipher(val string) attribute.KeyValue { - return TLSCipherKey.String(val) -} - -// TLSClientCertificate returns an attribute KeyValue conforming to the -// "tls.client.certificate" semantic conventions. It represents the pEM-encoded -// stand-alone certificate offered by the client. This is usually -// mutually-exclusive of `client.certificate_chain` since this value also exists -// in that list. -func TLSClientCertificate(val string) attribute.KeyValue { - return TLSClientCertificateKey.String(val) -} - -// TLSClientCertificateChain returns an attribute KeyValue conforming to the -// "tls.client.certificate_chain" semantic conventions. It represents the array -// of PEM-encoded certificates that make up the certificate chain offered by the -// client. This is usually mutually-exclusive of `client.certificate` since that -// value should be the first certificate in the chain. -func TLSClientCertificateChain(val ...string) attribute.KeyValue { - return TLSClientCertificateChainKey.StringSlice(val) -} - -// TLSClientHashMd5 returns an attribute KeyValue conforming to the -// "tls.client.hash.md5" semantic conventions. It represents the certificate -// fingerprint using the MD5 digest of DER-encoded version of certificate offered -// by the client. For consistency with other hash values, this value should be -// formatted as an uppercase hash. -func TLSClientHashMd5(val string) attribute.KeyValue { - return TLSClientHashMd5Key.String(val) -} - -// TLSClientHashSha1 returns an attribute KeyValue conforming to the -// "tls.client.hash.sha1" semantic conventions. It represents the certificate -// fingerprint using the SHA1 digest of DER-encoded version of certificate -// offered by the client. For consistency with other hash values, this value -// should be formatted as an uppercase hash. -func TLSClientHashSha1(val string) attribute.KeyValue { - return TLSClientHashSha1Key.String(val) -} - -// TLSClientHashSha256 returns an attribute KeyValue conforming to the -// "tls.client.hash.sha256" semantic conventions. It represents the certificate -// fingerprint using the SHA256 digest of DER-encoded version of certificate -// offered by the client. For consistency with other hash values, this value -// should be formatted as an uppercase hash. -func TLSClientHashSha256(val string) attribute.KeyValue { - return TLSClientHashSha256Key.String(val) -} - -// TLSClientIssuer returns an attribute KeyValue conforming to the -// "tls.client.issuer" semantic conventions. It represents the distinguished name -// of [subject] of the issuer of the x.509 certificate presented by the client. -// -// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6 -func TLSClientIssuer(val string) attribute.KeyValue { - return TLSClientIssuerKey.String(val) -} - -// TLSClientJa3 returns an attribute KeyValue conforming to the "tls.client.ja3" -// semantic conventions. It represents a hash that identifies clients based on -// how they perform an SSL/TLS handshake. -func TLSClientJa3(val string) attribute.KeyValue { - return TLSClientJa3Key.String(val) -} - -// TLSClientNotAfter returns an attribute KeyValue conforming to the -// "tls.client.not_after" semantic conventions. It represents the date/Time -// indicating when client certificate is no longer considered valid. -func TLSClientNotAfter(val string) attribute.KeyValue { - return TLSClientNotAfterKey.String(val) -} - -// TLSClientNotBefore returns an attribute KeyValue conforming to the -// "tls.client.not_before" semantic conventions. It represents the date/Time -// indicating when client certificate is first considered valid. -func TLSClientNotBefore(val string) attribute.KeyValue { - return TLSClientNotBeforeKey.String(val) -} - -// TLSClientSubject returns an attribute KeyValue conforming to the -// "tls.client.subject" semantic conventions. It represents the distinguished -// name of subject of the x.509 certificate presented by the client. -func TLSClientSubject(val string) attribute.KeyValue { - return TLSClientSubjectKey.String(val) -} - -// TLSClientSupportedCiphers returns an attribute KeyValue conforming to the -// "tls.client.supported_ciphers" semantic conventions. It represents the array -// of ciphers offered by the client during the client hello. -func TLSClientSupportedCiphers(val ...string) attribute.KeyValue { - return TLSClientSupportedCiphersKey.StringSlice(val) -} - -// TLSCurve returns an attribute KeyValue conforming to the "tls.curve" semantic -// conventions. It represents the string indicating the curve used for the given -// cipher, when applicable. -func TLSCurve(val string) attribute.KeyValue { - return TLSCurveKey.String(val) -} - -// TLSEstablished returns an attribute KeyValue conforming to the -// "tls.established" semantic conventions. It represents the boolean flag -// indicating if the TLS negotiation was successful and transitioned to an -// encrypted tunnel. -func TLSEstablished(val bool) attribute.KeyValue { - return TLSEstablishedKey.Bool(val) -} - -// TLSNextProtocol returns an attribute KeyValue conforming to the -// "tls.next_protocol" semantic conventions. It represents the string indicating -// the protocol being tunneled. Per the values in the [IANA registry], this -// string should be lower case. -// -// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids -func TLSNextProtocol(val string) attribute.KeyValue { - return TLSNextProtocolKey.String(val) -} - -// TLSProtocolVersion returns an attribute KeyValue conforming to the -// "tls.protocol.version" semantic conventions. It represents the numeric part of -// the version parsed from the original string of the negotiated -// [SSL/TLS protocol version]. -// -// [SSL/TLS protocol version]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES -func TLSProtocolVersion(val string) attribute.KeyValue { - return TLSProtocolVersionKey.String(val) -} - -// TLSResumed returns an attribute KeyValue conforming to the "tls.resumed" -// semantic conventions. It represents the boolean flag indicating if this TLS -// connection was resumed from an existing TLS negotiation. -func TLSResumed(val bool) attribute.KeyValue { - return TLSResumedKey.Bool(val) -} - -// TLSServerCertificate returns an attribute KeyValue conforming to the -// "tls.server.certificate" semantic conventions. It represents the pEM-encoded -// stand-alone certificate offered by the server. This is usually -// mutually-exclusive of `server.certificate_chain` since this value also exists -// in that list. -func TLSServerCertificate(val string) attribute.KeyValue { - return TLSServerCertificateKey.String(val) -} - -// TLSServerCertificateChain returns an attribute KeyValue conforming to the -// "tls.server.certificate_chain" semantic conventions. It represents the array -// of PEM-encoded certificates that make up the certificate chain offered by the -// server. This is usually mutually-exclusive of `server.certificate` since that -// value should be the first certificate in the chain. -func TLSServerCertificateChain(val ...string) attribute.KeyValue { - return TLSServerCertificateChainKey.StringSlice(val) -} - -// TLSServerHashMd5 returns an attribute KeyValue conforming to the -// "tls.server.hash.md5" semantic conventions. It represents the certificate -// fingerprint using the MD5 digest of DER-encoded version of certificate offered -// by the server. For consistency with other hash values, this value should be -// formatted as an uppercase hash. -func TLSServerHashMd5(val string) attribute.KeyValue { - return TLSServerHashMd5Key.String(val) -} - -// TLSServerHashSha1 returns an attribute KeyValue conforming to the -// "tls.server.hash.sha1" semantic conventions. It represents the certificate -// fingerprint using the SHA1 digest of DER-encoded version of certificate -// offered by the server. For consistency with other hash values, this value -// should be formatted as an uppercase hash. -func TLSServerHashSha1(val string) attribute.KeyValue { - return TLSServerHashSha1Key.String(val) -} - -// TLSServerHashSha256 returns an attribute KeyValue conforming to the -// "tls.server.hash.sha256" semantic conventions. It represents the certificate -// fingerprint using the SHA256 digest of DER-encoded version of certificate -// offered by the server. For consistency with other hash values, this value -// should be formatted as an uppercase hash. -func TLSServerHashSha256(val string) attribute.KeyValue { - return TLSServerHashSha256Key.String(val) -} - -// TLSServerIssuer returns an attribute KeyValue conforming to the -// "tls.server.issuer" semantic conventions. It represents the distinguished name -// of [subject] of the issuer of the x.509 certificate presented by the client. -// -// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6 -func TLSServerIssuer(val string) attribute.KeyValue { - return TLSServerIssuerKey.String(val) -} - -// TLSServerJa3s returns an attribute KeyValue conforming to the -// "tls.server.ja3s" semantic conventions. It represents a hash that identifies -// servers based on how they perform an SSL/TLS handshake. -func TLSServerJa3s(val string) attribute.KeyValue { - return TLSServerJa3sKey.String(val) -} - -// TLSServerNotAfter returns an attribute KeyValue conforming to the -// "tls.server.not_after" semantic conventions. It represents the date/Time -// indicating when server certificate is no longer considered valid. -func TLSServerNotAfter(val string) attribute.KeyValue { - return TLSServerNotAfterKey.String(val) -} - -// TLSServerNotBefore returns an attribute KeyValue conforming to the -// "tls.server.not_before" semantic conventions. It represents the date/Time -// indicating when server certificate is first considered valid. -func TLSServerNotBefore(val string) attribute.KeyValue { - return TLSServerNotBeforeKey.String(val) -} - -// TLSServerSubject returns an attribute KeyValue conforming to the -// "tls.server.subject" semantic conventions. It represents the distinguished -// name of subject of the x.509 certificate presented by the server. -func TLSServerSubject(val string) attribute.KeyValue { - return TLSServerSubjectKey.String(val) -} - -// Enum values for tls.protocol.name -var ( - // ssl - // Stability: development - TLSProtocolNameSsl = TLSProtocolNameKey.String("ssl") - // tls - // Stability: development - TLSProtocolNameTLS = TLSProtocolNameKey.String("tls") -) - -// Namespace: url -const ( - // URLDomainKey is the attribute Key conforming to the "url.domain" semantic - // conventions. It represents the domain extracted from the `url.full`, such as - // "opentelemetry.io". - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "www.foo.bar", "opentelemetry.io", "3.12.167.2", - // "[1080:0:0:0:8:800:200C:417A]" - // Note: In some cases a URL may refer to an IP and/or port directly, without a - // domain name. In this case, the IP address would go to the domain field. If - // the URL contains a [literal IPv6 address] enclosed by `[` and `]`, the `[` - // and `]` characters should also be captured in the domain field. - // - // [literal IPv6 address]: https://www.rfc-editor.org/rfc/rfc2732#section-2 - URLDomainKey = attribute.Key("url.domain") - - // URLExtensionKey is the attribute Key conforming to the "url.extension" - // semantic conventions. It represents the file extension extracted from the - // `url.full`, excluding the leading dot. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "png", "gz" - // Note: The file extension is only set if it exists, as not every url has a - // file extension. When the file name has multiple extensions `example.tar.gz`, - // only the last one should be captured `gz`, not `tar.gz`. - URLExtensionKey = attribute.Key("url.extension") - - // URLFragmentKey is the attribute Key conforming to the "url.fragment" semantic - // conventions. It represents the [URI fragment] component. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "SemConv" - // - // [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5 - URLFragmentKey = attribute.Key("url.fragment") - - // URLFullKey is the attribute Key conforming to the "url.full" semantic - // conventions. It represents the absolute URL describing a network resource - // according to [RFC3986]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "https://www.foo.bar/search?q=OpenTelemetry#SemConv", "//localhost" - // Note: For network calls, URL usually has - // `scheme://host[:port][path][?query][#fragment]` format, where the fragment - // is not transmitted over HTTP, but if it is known, it SHOULD be included - // nevertheless. - // - // `url.full` MUST NOT contain credentials passed via URL in form of - // `https://username:password@www.example.com/`. - // In such case username and password SHOULD be redacted and attribute's value - // SHOULD be `https://REDACTED:REDACTED@www.example.com/`. - // - // `url.full` SHOULD capture the absolute URL when it is available (or can be - // reconstructed). - // - // Sensitive content provided in `url.full` SHOULD be scrubbed when - // instrumentations can identify it. - // - // - // Query string values for the following keys SHOULD be redacted by default and - // replaced by the - // value `REDACTED`: - // - // - [`AWSAccessKeyId`] - // - [`Signature`] - // - [`sig`] - // - [`X-Goog-Signature`] - // - // This list is subject to change over time. - // - // When a query string value is redacted, the query string key SHOULD still be - // preserved, e.g. - // `https://www.example.com/path?color=blue&sig=REDACTED`. - // - // [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986 - // [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth - // [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth - // [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token - // [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls - URLFullKey = attribute.Key("url.full") - - // URLOriginalKey is the attribute Key conforming to the "url.original" semantic - // conventions. It represents the unmodified original URL as seen in the event - // source. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "https://www.foo.bar/search?q=OpenTelemetry#SemConv", - // "search?q=OpenTelemetry" - // Note: In network monitoring, the observed URL may be a full URL, whereas in - // access logs, the URL is often just represented as a path. This field is meant - // to represent the URL as it was observed, complete or not. - // `url.original` might contain credentials passed via URL in form of - // `https://username:password@www.example.com/`. In such case password and - // username SHOULD NOT be redacted and attribute's value SHOULD remain the same. - URLOriginalKey = attribute.Key("url.original") - - // URLPathKey is the attribute Key conforming to the "url.path" semantic - // conventions. It represents the [URI path] component. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "/search" - // Note: Sensitive content provided in `url.path` SHOULD be scrubbed when - // instrumentations can identify it. - // - // [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3 - URLPathKey = attribute.Key("url.path") - - // URLPortKey is the attribute Key conforming to the "url.port" semantic - // conventions. It represents the port extracted from the `url.full`. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 443 - URLPortKey = attribute.Key("url.port") - - // URLQueryKey is the attribute Key conforming to the "url.query" semantic - // conventions. It represents the [URI query] component. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "q=OpenTelemetry" - // Note: Sensitive content provided in `url.query` SHOULD be scrubbed when - // instrumentations can identify it. - // - // - // Query string values for the following keys SHOULD be redacted by default and - // replaced by the value `REDACTED`: - // - // - [`AWSAccessKeyId`] - // - [`Signature`] - // - [`sig`] - // - [`X-Goog-Signature`] - // - // This list is subject to change over time. - // - // When a query string value is redacted, the query string key SHOULD still be - // preserved, e.g. - // `q=OpenTelemetry&sig=REDACTED`. - // - // [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4 - // [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth - // [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth - // [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token - // [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls - URLQueryKey = attribute.Key("url.query") - - // URLRegisteredDomainKey is the attribute Key conforming to the - // "url.registered_domain" semantic conventions. It represents the highest - // registered url domain, stripped of the subdomain. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "example.com", "foo.co.uk" - // Note: This value can be determined precisely with the [public suffix list]. - // For example, the registered domain for `foo.example.com` is `example.com`. - // Trying to approximate this by simply taking the last two labels will not work - // well for TLDs such as `co.uk`. - // - // [public suffix list]: http://publicsuffix.org - URLRegisteredDomainKey = attribute.Key("url.registered_domain") - - // URLSchemeKey is the attribute Key conforming to the "url.scheme" semantic - // conventions. It represents the [URI scheme] component identifying the used - // protocol. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "https", "ftp", "telnet" - // - // [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 - URLSchemeKey = attribute.Key("url.scheme") - - // URLSubdomainKey is the attribute Key conforming to the "url.subdomain" - // semantic conventions. It represents the subdomain portion of a fully - // qualified domain name includes all of the names except the host name under - // the registered_domain. In a partially qualified domain, or if the - // qualification level of the full name cannot be determined, subdomain contains - // all of the names below the registered domain. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "east", "sub2.sub1" - // Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the - // domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the - // subdomain field should contain `sub2.sub1`, with no trailing period. - URLSubdomainKey = attribute.Key("url.subdomain") - - // URLTemplateKey is the attribute Key conforming to the "url.template" semantic - // conventions. It represents the low-cardinality template of an - // [absolute path reference]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "/users/{id}", "/users/:id", "/users?id={id}" - // - // [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 - URLTemplateKey = attribute.Key("url.template") - - // URLTopLevelDomainKey is the attribute Key conforming to the - // "url.top_level_domain" semantic conventions. It represents the effective top - // level domain (eTLD), also known as the domain suffix, is the last part of the - // domain name. For example, the top level domain for example.com is `com`. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "com", "co.uk" - // Note: This value can be determined precisely with the [public suffix list]. - // - // [public suffix list]: http://publicsuffix.org - URLTopLevelDomainKey = attribute.Key("url.top_level_domain") -) - -// URLDomain returns an attribute KeyValue conforming to the "url.domain" -// semantic conventions. It represents the domain extracted from the `url.full`, -// such as "opentelemetry.io". -func URLDomain(val string) attribute.KeyValue { - return URLDomainKey.String(val) -} - -// URLExtension returns an attribute KeyValue conforming to the "url.extension" -// semantic conventions. It represents the file extension extracted from the -// `url.full`, excluding the leading dot. -func URLExtension(val string) attribute.KeyValue { - return URLExtensionKey.String(val) -} - -// URLFragment returns an attribute KeyValue conforming to the "url.fragment" -// semantic conventions. It represents the [URI fragment] component. -// -// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5 -func URLFragment(val string) attribute.KeyValue { - return URLFragmentKey.String(val) -} - -// URLFull returns an attribute KeyValue conforming to the "url.full" semantic -// conventions. It represents the absolute URL describing a network resource -// according to [RFC3986]. -// -// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986 -func URLFull(val string) attribute.KeyValue { - return URLFullKey.String(val) -} - -// URLOriginal returns an attribute KeyValue conforming to the "url.original" -// semantic conventions. It represents the unmodified original URL as seen in the -// event source. -func URLOriginal(val string) attribute.KeyValue { - return URLOriginalKey.String(val) -} - -// URLPath returns an attribute KeyValue conforming to the "url.path" semantic -// conventions. It represents the [URI path] component. -// -// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3 -func URLPath(val string) attribute.KeyValue { - return URLPathKey.String(val) -} - -// URLPort returns an attribute KeyValue conforming to the "url.port" semantic -// conventions. It represents the port extracted from the `url.full`. -func URLPort(val int) attribute.KeyValue { - return URLPortKey.Int(val) -} - -// URLQuery returns an attribute KeyValue conforming to the "url.query" semantic -// conventions. It represents the [URI query] component. -// -// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4 -func URLQuery(val string) attribute.KeyValue { - return URLQueryKey.String(val) -} - -// URLRegisteredDomain returns an attribute KeyValue conforming to the -// "url.registered_domain" semantic conventions. It represents the highest -// registered url domain, stripped of the subdomain. -func URLRegisteredDomain(val string) attribute.KeyValue { - return URLRegisteredDomainKey.String(val) -} - -// URLScheme returns an attribute KeyValue conforming to the "url.scheme" -// semantic conventions. It represents the [URI scheme] component identifying the -// used protocol. -// -// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 -func URLScheme(val string) attribute.KeyValue { - return URLSchemeKey.String(val) -} - -// URLSubdomain returns an attribute KeyValue conforming to the "url.subdomain" -// semantic conventions. It represents the subdomain portion of a fully qualified -// domain name includes all of the names except the host name under the -// registered_domain. In a partially qualified domain, or if the qualification -// level of the full name cannot be determined, subdomain contains all of the -// names below the registered domain. -func URLSubdomain(val string) attribute.KeyValue { - return URLSubdomainKey.String(val) -} - -// URLTemplate returns an attribute KeyValue conforming to the "url.template" -// semantic conventions. It represents the low-cardinality template of an -// [absolute path reference]. -// -// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 -func URLTemplate(val string) attribute.KeyValue { - return URLTemplateKey.String(val) -} - -// URLTopLevelDomain returns an attribute KeyValue conforming to the -// "url.top_level_domain" semantic conventions. It represents the effective top -// level domain (eTLD), also known as the domain suffix, is the last part of the -// domain name. For example, the top level domain for example.com is `com`. -func URLTopLevelDomain(val string) attribute.KeyValue { - return URLTopLevelDomainKey.String(val) -} - -// Namespace: user -const ( - // UserEmailKey is the attribute Key conforming to the "user.email" semantic - // conventions. It represents the user email address. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "a.einstein@example.com" - UserEmailKey = attribute.Key("user.email") - - // UserFullNameKey is the attribute Key conforming to the "user.full_name" - // semantic conventions. It represents the user's full name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Albert Einstein" - UserFullNameKey = attribute.Key("user.full_name") - - // UserHashKey is the attribute Key conforming to the "user.hash" semantic - // conventions. It represents the unique user hash to correlate information for - // a user in anonymized form. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "364fc68eaf4c8acec74a4e52d7d1feaa" - // Note: Useful if `user.id` or `user.name` contain confidential information and - // cannot be used. - UserHashKey = attribute.Key("user.hash") - - // UserIDKey is the attribute Key conforming to the "user.id" semantic - // conventions. It represents the unique identifier of the user. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "S-1-5-21-202424912787-2692429404-2351956786-1000" - UserIDKey = attribute.Key("user.id") - - // UserNameKey is the attribute Key conforming to the "user.name" semantic - // conventions. It represents the short name or login/username of the user. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "a.einstein" - UserNameKey = attribute.Key("user.name") - - // UserRolesKey is the attribute Key conforming to the "user.roles" semantic - // conventions. It represents the array of user roles at the time of the event. - // - // Type: string[] - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "admin", "reporting_user" - UserRolesKey = attribute.Key("user.roles") -) - -// UserEmail returns an attribute KeyValue conforming to the "user.email" -// semantic conventions. It represents the user email address. -func UserEmail(val string) attribute.KeyValue { - return UserEmailKey.String(val) -} - -// UserFullName returns an attribute KeyValue conforming to the "user.full_name" -// semantic conventions. It represents the user's full name. -func UserFullName(val string) attribute.KeyValue { - return UserFullNameKey.String(val) -} - -// UserHash returns an attribute KeyValue conforming to the "user.hash" semantic -// conventions. It represents the unique user hash to correlate information for a -// user in anonymized form. -func UserHash(val string) attribute.KeyValue { - return UserHashKey.String(val) -} - -// UserID returns an attribute KeyValue conforming to the "user.id" semantic -// conventions. It represents the unique identifier of the user. -func UserID(val string) attribute.KeyValue { - return UserIDKey.String(val) -} - -// UserName returns an attribute KeyValue conforming to the "user.name" semantic -// conventions. It represents the short name or login/username of the user. -func UserName(val string) attribute.KeyValue { - return UserNameKey.String(val) -} - -// UserRoles returns an attribute KeyValue conforming to the "user.roles" -// semantic conventions. It represents the array of user roles at the time of the -// event. -func UserRoles(val ...string) attribute.KeyValue { - return UserRolesKey.StringSlice(val) -} - -// Namespace: user_agent -const ( - // UserAgentNameKey is the attribute Key conforming to the "user_agent.name" - // semantic conventions. It represents the name of the user-agent extracted from - // original. Usually refers to the browser's name. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Safari", "YourApp" - // Note: [Example] of extracting browser's name from original string. In the - // case of using a user-agent for non-browser products, such as microservices - // with multiple names/versions inside the `user_agent.original`, the most - // significant name SHOULD be selected. In such a scenario it should align with - // `user_agent.version` - // - // [Example]: https://www.whatsmyua.info - UserAgentNameKey = attribute.Key("user_agent.name") - - // UserAgentOriginalKey is the attribute Key conforming to the - // "user_agent.original" semantic conventions. It represents the value of the - // [HTTP User-Agent] header sent by the client. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Stable - // - // Examples: "CERN-LineMode/2.15 libwww/2.17b3", "Mozilla/5.0 (iPhone; CPU - // iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) - // Version/14.1.2 Mobile/15E148 Safari/604.1", "YourApp/1.0.0 - // grpc-java-okhttp/1.27.2" - // - // [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent - UserAgentOriginalKey = attribute.Key("user_agent.original") - - // UserAgentSyntheticTypeKey is the attribute Key conforming to the - // "user_agent.synthetic.type" semantic conventions. It represents the specifies - // the category of synthetic traffic, such as tests or bots. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: This attribute MAY be derived from the contents of the - // `user_agent.original` attribute. Components that populate the attribute are - // responsible for determining what they consider to be synthetic bot or test - // traffic. This attribute can either be set for self-identification purposes, - // or on telemetry detected to be generated as a result of a synthetic request. - // This attribute is useful for distinguishing between genuine client traffic - // and synthetic traffic generated by bots or tests. - UserAgentSyntheticTypeKey = attribute.Key("user_agent.synthetic.type") - - // UserAgentVersionKey is the attribute Key conforming to the - // "user_agent.version" semantic conventions. It represents the version of the - // user-agent extracted from original. Usually refers to the browser's version. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "14.1.2", "1.0.0" - // Note: [Example] of extracting browser's version from original string. In the - // case of using a user-agent for non-browser products, such as microservices - // with multiple names/versions inside the `user_agent.original`, the most - // significant version SHOULD be selected. In such a scenario it should align - // with `user_agent.name` - // - // [Example]: https://www.whatsmyua.info - UserAgentVersionKey = attribute.Key("user_agent.version") -) - -// UserAgentName returns an attribute KeyValue conforming to the -// "user_agent.name" semantic conventions. It represents the name of the -// user-agent extracted from original. Usually refers to the browser's name. -func UserAgentName(val string) attribute.KeyValue { - return UserAgentNameKey.String(val) -} - -// UserAgentOriginal returns an attribute KeyValue conforming to the -// "user_agent.original" semantic conventions. It represents the value of the -// [HTTP User-Agent] header sent by the client. -// -// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent -func UserAgentOriginal(val string) attribute.KeyValue { - return UserAgentOriginalKey.String(val) -} - -// UserAgentVersion returns an attribute KeyValue conforming to the -// "user_agent.version" semantic conventions. It represents the version of the -// user-agent extracted from original. Usually refers to the browser's version. -func UserAgentVersion(val string) attribute.KeyValue { - return UserAgentVersionKey.String(val) -} - -// Enum values for user_agent.synthetic.type -var ( - // Bot source. - // Stability: development - UserAgentSyntheticTypeBot = UserAgentSyntheticTypeKey.String("bot") - // Synthetic test source. - // Stability: development - UserAgentSyntheticTypeTest = UserAgentSyntheticTypeKey.String("test") -) - -// Namespace: vcs -const ( - // VCSChangeIDKey is the attribute Key conforming to the "vcs.change.id" - // semantic conventions. It represents the ID of the change (pull request/merge - // request/changelist) if applicable. This is usually a unique (within - // repository) identifier generated by the VCS system. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "123" - VCSChangeIDKey = attribute.Key("vcs.change.id") - - // VCSChangeStateKey is the attribute Key conforming to the "vcs.change.state" - // semantic conventions. It represents the state of the change (pull - // request/merge request/changelist). - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "open", "closed", "merged" - VCSChangeStateKey = attribute.Key("vcs.change.state") - - // VCSChangeTitleKey is the attribute Key conforming to the "vcs.change.title" - // semantic conventions. It represents the human readable title of the change - // (pull request/merge request/changelist). This title is often a brief summary - // of the change and may get merged in to a ref as the commit summary. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Fixes broken thing", "feat: add my new feature", "[chore] update - // dependency" - VCSChangeTitleKey = attribute.Key("vcs.change.title") - - // VCSLineChangeTypeKey is the attribute Key conforming to the - // "vcs.line_change.type" semantic conventions. It represents the type of line - // change being measured on a branch or change. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "added", "removed" - VCSLineChangeTypeKey = attribute.Key("vcs.line_change.type") - - // VCSRefBaseNameKey is the attribute Key conforming to the "vcs.ref.base.name" - // semantic conventions. It represents the name of the [reference] such as - // **branch** or **tag** in the repository. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-feature-branch", "tag-1-test" - // Note: `base` refers to the starting point of a change. For example, `main` - // would be the base reference of type branch if you've created a new - // reference of type branch from it and created new commits. - // - // [reference]: https://git-scm.com/docs/gitglossary#def_ref - VCSRefBaseNameKey = attribute.Key("vcs.ref.base.name") - - // VCSRefBaseRevisionKey is the attribute Key conforming to the - // "vcs.ref.base.revision" semantic conventions. It represents the revision, - // literally [revised version], The revision most often refers to a commit - // object in Git, or a revision number in SVN. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc", - // "main", "123", "HEAD" - // Note: `base` refers to the starting point of a change. For example, `main` - // would be the base reference of type branch if you've created a new - // reference of type branch from it and created new commits. The - // revision can be a full [hash value (see - // glossary)], - // of the recorded change to a ref within a repository pointing to a - // commit [commit] object. It does - // not necessarily have to be a hash; it can simply define a [revision - // number] - // which is an integer that is monotonically increasing. In cases where - // it is identical to the `ref.base.name`, it SHOULD still be included. - // It is up to the implementer to decide which value to set as the - // revision based on the VCS system and situational context. - // - // [revised version]: https://www.merriam-webster.com/dictionary/revision - // [hash value (see - // glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf - // [commit]: https://git-scm.com/docs/git-commit - // [revision - // number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html - VCSRefBaseRevisionKey = attribute.Key("vcs.ref.base.revision") - - // VCSRefBaseTypeKey is the attribute Key conforming to the "vcs.ref.base.type" - // semantic conventions. It represents the type of the [reference] in the - // repository. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "branch", "tag" - // Note: `base` refers to the starting point of a change. For example, `main` - // would be the base reference of type branch if you've created a new - // reference of type branch from it and created new commits. - // - // [reference]: https://git-scm.com/docs/gitglossary#def_ref - VCSRefBaseTypeKey = attribute.Key("vcs.ref.base.type") - - // VCSRefHeadNameKey is the attribute Key conforming to the "vcs.ref.head.name" - // semantic conventions. It represents the name of the [reference] such as - // **branch** or **tag** in the repository. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "my-feature-branch", "tag-1-test" - // Note: `head` refers to where you are right now; the current reference at a - // given time. - // - // [reference]: https://git-scm.com/docs/gitglossary#def_ref - VCSRefHeadNameKey = attribute.Key("vcs.ref.head.name") - - // VCSRefHeadRevisionKey is the attribute Key conforming to the - // "vcs.ref.head.revision" semantic conventions. It represents the revision, - // literally [revised version], The revision most often refers to a commit - // object in Git, or a revision number in SVN. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc", - // "main", "123", "HEAD" - // Note: `head` refers to where you are right now; the current reference at a - // given time.The revision can be a full [hash value (see - // glossary)], - // of the recorded change to a ref within a repository pointing to a - // commit [commit] object. It does - // not necessarily have to be a hash; it can simply define a [revision - // number] - // which is an integer that is monotonically increasing. In cases where - // it is identical to the `ref.head.name`, it SHOULD still be included. - // It is up to the implementer to decide which value to set as the - // revision based on the VCS system and situational context. - // - // [revised version]: https://www.merriam-webster.com/dictionary/revision - // [hash value (see - // glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf - // [commit]: https://git-scm.com/docs/git-commit - // [revision - // number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html - VCSRefHeadRevisionKey = attribute.Key("vcs.ref.head.revision") - - // VCSRefHeadTypeKey is the attribute Key conforming to the "vcs.ref.head.type" - // semantic conventions. It represents the type of the [reference] in the - // repository. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "branch", "tag" - // Note: `head` refers to where you are right now; the current reference at a - // given time. - // - // [reference]: https://git-scm.com/docs/gitglossary#def_ref - VCSRefHeadTypeKey = attribute.Key("vcs.ref.head.type") - - // VCSRefTypeKey is the attribute Key conforming to the "vcs.ref.type" semantic - // conventions. It represents the type of the [reference] in the repository. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "branch", "tag" - // - // [reference]: https://git-scm.com/docs/gitglossary#def_ref - VCSRefTypeKey = attribute.Key("vcs.ref.type") - - // VCSRepositoryNameKey is the attribute Key conforming to the - // "vcs.repository.name" semantic conventions. It represents the human readable - // name of the repository. It SHOULD NOT include any additional identifier like - // Group/SubGroup in GitLab or organization in GitHub. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "semantic-conventions", "my-cool-repo" - // Note: Due to it only being the name, it can clash with forks of the same - // repository if collecting telemetry across multiple orgs or groups in - // the same backends. - VCSRepositoryNameKey = attribute.Key("vcs.repository.name") - - // VCSRepositoryURLFullKey is the attribute Key conforming to the - // "vcs.repository.url.full" semantic conventions. It represents the - // [canonical URL] of the repository providing the complete HTTP(S) address in - // order to locate and identify the repository through a browser. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // "https://github.com/opentelemetry/open-telemetry-collector-contrib", - // "https://gitlab.com/my-org/my-project/my-projects-project/repo" - // Note: In Git Version Control Systems, the canonical URL SHOULD NOT include - // the `.git` extension. - // - // [canonical URL]: https://support.google.com/webmasters/answer/10347851?hl=en#:~:text=A%20canonical%20URL%20is%20the,Google%20chooses%20one%20as%20canonical. - VCSRepositoryURLFullKey = attribute.Key("vcs.repository.url.full") - - // VCSRevisionDeltaDirectionKey is the attribute Key conforming to the - // "vcs.revision_delta.direction" semantic conventions. It represents the type - // of revision comparison. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "ahead", "behind" - VCSRevisionDeltaDirectionKey = attribute.Key("vcs.revision_delta.direction") -) - -// VCSChangeID returns an attribute KeyValue conforming to the "vcs.change.id" -// semantic conventions. It represents the ID of the change (pull request/merge -// request/changelist) if applicable. This is usually a unique (within -// repository) identifier generated by the VCS system. -func VCSChangeID(val string) attribute.KeyValue { - return VCSChangeIDKey.String(val) -} - -// VCSChangeTitle returns an attribute KeyValue conforming to the -// "vcs.change.title" semantic conventions. It represents the human readable -// title of the change (pull request/merge request/changelist). This title is -// often a brief summary of the change and may get merged in to a ref as the -// commit summary. -func VCSChangeTitle(val string) attribute.KeyValue { - return VCSChangeTitleKey.String(val) -} - -// VCSRefBaseName returns an attribute KeyValue conforming to the -// "vcs.ref.base.name" semantic conventions. It represents the name of the -// [reference] such as **branch** or **tag** in the repository. -// -// [reference]: https://git-scm.com/docs/gitglossary#def_ref -func VCSRefBaseName(val string) attribute.KeyValue { - return VCSRefBaseNameKey.String(val) -} - -// VCSRefBaseRevision returns an attribute KeyValue conforming to the -// "vcs.ref.base.revision" semantic conventions. It represents the revision, -// literally [revised version], The revision most often refers to a commit object -// in Git, or a revision number in SVN. -// -// [revised version]: https://www.merriam-webster.com/dictionary/revision -func VCSRefBaseRevision(val string) attribute.KeyValue { - return VCSRefBaseRevisionKey.String(val) -} - -// VCSRefHeadName returns an attribute KeyValue conforming to the -// "vcs.ref.head.name" semantic conventions. It represents the name of the -// [reference] such as **branch** or **tag** in the repository. -// -// [reference]: https://git-scm.com/docs/gitglossary#def_ref -func VCSRefHeadName(val string) attribute.KeyValue { - return VCSRefHeadNameKey.String(val) -} - -// VCSRefHeadRevision returns an attribute KeyValue conforming to the -// "vcs.ref.head.revision" semantic conventions. It represents the revision, -// literally [revised version], The revision most often refers to a commit object -// in Git, or a revision number in SVN. -// -// [revised version]: https://www.merriam-webster.com/dictionary/revision -func VCSRefHeadRevision(val string) attribute.KeyValue { - return VCSRefHeadRevisionKey.String(val) -} - -// VCSRepositoryName returns an attribute KeyValue conforming to the -// "vcs.repository.name" semantic conventions. It represents the human readable -// name of the repository. It SHOULD NOT include any additional identifier like -// Group/SubGroup in GitLab or organization in GitHub. -func VCSRepositoryName(val string) attribute.KeyValue { - return VCSRepositoryNameKey.String(val) -} - -// VCSRepositoryURLFull returns an attribute KeyValue conforming to the -// "vcs.repository.url.full" semantic conventions. It represents the -// [canonical URL] of the repository providing the complete HTTP(S) address in -// order to locate and identify the repository through a browser. -// -// [canonical URL]: https://support.google.com/webmasters/answer/10347851?hl=en#:~:text=A%20canonical%20URL%20is%20the,Google%20chooses%20one%20as%20canonical. -func VCSRepositoryURLFull(val string) attribute.KeyValue { - return VCSRepositoryURLFullKey.String(val) -} - -// Enum values for vcs.change.state -var ( - // Open means the change is currently active and under review. It hasn't been - // merged into the target branch yet, and it's still possible to make changes or - // add comments. - // Stability: development - VCSChangeStateOpen = VCSChangeStateKey.String("open") - // WIP (work-in-progress, draft) means the change is still in progress and not - // yet ready for a full review. It might still undergo significant changes. - // Stability: development - VCSChangeStateWip = VCSChangeStateKey.String("wip") - // Closed means the merge request has been closed without merging. This can - // happen for various reasons, such as the changes being deemed unnecessary, the - // issue being resolved in another way, or the author deciding to withdraw the - // request. - // Stability: development - VCSChangeStateClosed = VCSChangeStateKey.String("closed") - // Merged indicates that the change has been successfully integrated into the - // target codebase. - // Stability: development - VCSChangeStateMerged = VCSChangeStateKey.String("merged") -) - -// Enum values for vcs.line_change.type -var ( - // How many lines were added. - // Stability: development - VCSLineChangeTypeAdded = VCSLineChangeTypeKey.String("added") - // How many lines were removed. - // Stability: development - VCSLineChangeTypeRemoved = VCSLineChangeTypeKey.String("removed") -) - -// Enum values for vcs.ref.base.type -var ( - // [branch] - // Stability: development - // - // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch - VCSRefBaseTypeBranch = VCSRefBaseTypeKey.String("branch") - // [tag] - // Stability: development - // - // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag - VCSRefBaseTypeTag = VCSRefBaseTypeKey.String("tag") -) - -// Enum values for vcs.ref.head.type -var ( - // [branch] - // Stability: development - // - // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch - VCSRefHeadTypeBranch = VCSRefHeadTypeKey.String("branch") - // [tag] - // Stability: development - // - // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag - VCSRefHeadTypeTag = VCSRefHeadTypeKey.String("tag") -) - -// Enum values for vcs.ref.type -var ( - // [branch] - // Stability: development - // - // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch - VCSRefTypeBranch = VCSRefTypeKey.String("branch") - // [tag] - // Stability: development - // - // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag - VCSRefTypeTag = VCSRefTypeKey.String("tag") -) - -// Enum values for vcs.revision_delta.direction -var ( - // How many revisions the change is behind the target ref. - // Stability: development - VCSRevisionDeltaDirectionBehind = VCSRevisionDeltaDirectionKey.String("behind") - // How many revisions the change is ahead of the target ref. - // Stability: development - VCSRevisionDeltaDirectionAhead = VCSRevisionDeltaDirectionKey.String("ahead") -) - -// Namespace: webengine -const ( - // WebEngineDescriptionKey is the attribute Key conforming to the - // "webengine.description" semantic conventions. It represents the additional - // description of the web engine (e.g. detailed version and edition - // information). - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - - // 2.2.2.Final" - WebEngineDescriptionKey = attribute.Key("webengine.description") - - // WebEngineNameKey is the attribute Key conforming to the "webengine.name" - // semantic conventions. It represents the name of the web engine. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "WildFly" - WebEngineNameKey = attribute.Key("webengine.name") - - // WebEngineVersionKey is the attribute Key conforming to the - // "webengine.version" semantic conventions. It represents the version of the - // web engine. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "21.0.0" - WebEngineVersionKey = attribute.Key("webengine.version") -) - -// WebEngineDescription returns an attribute KeyValue conforming to the -// "webengine.description" semantic conventions. It represents the additional -// description of the web engine (e.g. detailed version and edition information). -func WebEngineDescription(val string) attribute.KeyValue { - return WebEngineDescriptionKey.String(val) -} - -// WebEngineName returns an attribute KeyValue conforming to the "webengine.name" -// semantic conventions. It represents the name of the web engine. -func WebEngineName(val string) attribute.KeyValue { - return WebEngineNameKey.String(val) -} - -// WebEngineVersion returns an attribute KeyValue conforming to the -// "webengine.version" semantic conventions. It represents the version of the web -// engine. -func WebEngineVersion(val string) attribute.KeyValue { - return WebEngineVersionKey.String(val) -} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/doc.go deleted file mode 100644 index 894531c7c74..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// Package semconv implements OpenTelemetry semantic conventions. -// -// OpenTelemetry semantic conventions are agreed standardized naming -// patterns for OpenTelemetry things. This package represents the v1.30.0 -// version of the OpenTelemetry semantic conventions. -package semconv diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/exception.go deleted file mode 100644 index 3fe84aae0a9..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/exception.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package semconv - -const ( - // ExceptionEventName is the name of the Span event representing an exception. - ExceptionEventName = "exception" -) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/metric.go deleted file mode 100644 index 4fcd261a7bb..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/metric.go +++ /dev/null @@ -1,1750 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// Code generated from semantic convention specification. DO NOT EDIT. - -package semconv - -const ( - // AzureCosmosDBClientActiveInstanceCount is the metric conforming to the - // "azure.cosmosdb.client.active_instance.count" semantic conventions. It - // represents the number of active client instances. - // Instrument: updowncounter - // Unit: {instance} - // Stability: development - AzureCosmosDBClientActiveInstanceCountName = "azure.cosmosdb.client.active_instance.count" - AzureCosmosDBClientActiveInstanceCountUnit = "{instance}" - AzureCosmosDBClientActiveInstanceCountDescription = "Number of active client instances" - // AzureCosmosDBClientOperationRequestCharge is the metric conforming to the - // "azure.cosmosdb.client.operation.request_charge" semantic conventions. It - // represents the [Request units] consumed by the operation. - // - // [Request units]: https://learn.microsoft.com/azure/cosmos-db/request-units - // Instrument: histogram - // Unit: {request_unit} - // Stability: development - AzureCosmosDBClientOperationRequestChargeName = "azure.cosmosdb.client.operation.request_charge" - AzureCosmosDBClientOperationRequestChargeUnit = "{request_unit}" - AzureCosmosDBClientOperationRequestChargeDescription = "[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation" - // CICDPipelineRunActive is the metric conforming to the - // "cicd.pipeline.run.active" semantic conventions. It represents the number of - // pipeline runs currently active in the system by state. - // Instrument: updowncounter - // Unit: {run} - // Stability: development - CICDPipelineRunActiveName = "cicd.pipeline.run.active" - CICDPipelineRunActiveUnit = "{run}" - CICDPipelineRunActiveDescription = "The number of pipeline runs currently active in the system by state." - // CICDPipelineRunDuration is the metric conforming to the - // "cicd.pipeline.run.duration" semantic conventions. It represents the - // duration of a pipeline run grouped by pipeline, state and result. - // Instrument: histogram - // Unit: s - // Stability: development - CICDPipelineRunDurationName = "cicd.pipeline.run.duration" - CICDPipelineRunDurationUnit = "s" - CICDPipelineRunDurationDescription = "Duration of a pipeline run grouped by pipeline, state and result." - // CICDPipelineRunErrors is the metric conforming to the - // "cicd.pipeline.run.errors" semantic conventions. It represents the number of - // errors encountered in pipeline runs (eg. compile, test failures). - // Instrument: counter - // Unit: {error} - // Stability: development - CICDPipelineRunErrorsName = "cicd.pipeline.run.errors" - CICDPipelineRunErrorsUnit = "{error}" - CICDPipelineRunErrorsDescription = "The number of errors encountered in pipeline runs (eg. compile, test failures)." - // CICDSystemErrors is the metric conforming to the "cicd.system.errors" - // semantic conventions. It represents the number of errors in a component of - // the CICD system (eg. controller, scheduler, agent). - // Instrument: counter - // Unit: {error} - // Stability: development - CICDSystemErrorsName = "cicd.system.errors" - CICDSystemErrorsUnit = "{error}" - CICDSystemErrorsDescription = "The number of errors in a component of the CICD system (eg. controller, scheduler, agent)." - // CICDWorkerCount is the metric conforming to the "cicd.worker.count" semantic - // conventions. It represents the number of workers on the CICD system by - // state. - // Instrument: updowncounter - // Unit: {count} - // Stability: development - CICDWorkerCountName = "cicd.worker.count" - CICDWorkerCountUnit = "{count}" - CICDWorkerCountDescription = "The number of workers on the CICD system by state." - // ContainerCPUTime is the metric conforming to the "container.cpu.time" - // semantic conventions. It represents the total CPU time consumed. - // Instrument: counter - // Unit: s - // Stability: development - ContainerCPUTimeName = "container.cpu.time" - ContainerCPUTimeUnit = "s" - ContainerCPUTimeDescription = "Total CPU time consumed" - // ContainerCPUUsage is the metric conforming to the "container.cpu.usage" - // semantic conventions. It represents the container's CPU usage, measured in - // cpus. Range from 0 to the number of allocatable CPUs. - // Instrument: gauge - // Unit: {cpu} - // Stability: development - ContainerCPUUsageName = "container.cpu.usage" - ContainerCPUUsageUnit = "{cpu}" - ContainerCPUUsageDescription = "Container's CPU usage, measured in cpus. Range from 0 to the number of allocatable CPUs" - // ContainerDiskIo is the metric conforming to the "container.disk.io" semantic - // conventions. It represents the disk bytes for the container. - // Instrument: counter - // Unit: By - // Stability: development - ContainerDiskIoName = "container.disk.io" - ContainerDiskIoUnit = "By" - ContainerDiskIoDescription = "Disk bytes for the container." - // ContainerMemoryUsage is the metric conforming to the - // "container.memory.usage" semantic conventions. It represents the memory - // usage of the container. - // Instrument: counter - // Unit: By - // Stability: development - ContainerMemoryUsageName = "container.memory.usage" - ContainerMemoryUsageUnit = "By" - ContainerMemoryUsageDescription = "Memory usage of the container." - // ContainerNetworkIo is the metric conforming to the "container.network.io" - // semantic conventions. It represents the network bytes for the container. - // Instrument: counter - // Unit: By - // Stability: development - ContainerNetworkIoName = "container.network.io" - ContainerNetworkIoUnit = "By" - ContainerNetworkIoDescription = "Network bytes for the container." - // ContainerUptime is the metric conforming to the "container.uptime" semantic - // conventions. It represents the time the container has been running. - // Instrument: gauge - // Unit: s - // Stability: development - ContainerUptimeName = "container.uptime" - ContainerUptimeUnit = "s" - ContainerUptimeDescription = "The time the container has been running" - // DBClientConnectionCount is the metric conforming to the - // "db.client.connection.count" semantic conventions. It represents the number - // of connections that are currently in state described by the `state` - // attribute. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - DBClientConnectionCountName = "db.client.connection.count" - DBClientConnectionCountUnit = "{connection}" - DBClientConnectionCountDescription = "The number of connections that are currently in state described by the `state` attribute" - // DBClientConnectionCreateTime is the metric conforming to the - // "db.client.connection.create_time" semantic conventions. It represents the - // time it took to create a new connection. - // Instrument: histogram - // Unit: s - // Stability: development - DBClientConnectionCreateTimeName = "db.client.connection.create_time" - DBClientConnectionCreateTimeUnit = "s" - DBClientConnectionCreateTimeDescription = "The time it took to create a new connection" - // DBClientConnectionIdleMax is the metric conforming to the - // "db.client.connection.idle.max" semantic conventions. It represents the - // maximum number of idle open connections allowed. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - DBClientConnectionIdleMaxName = "db.client.connection.idle.max" - DBClientConnectionIdleMaxUnit = "{connection}" - DBClientConnectionIdleMaxDescription = "The maximum number of idle open connections allowed" - // DBClientConnectionIdleMin is the metric conforming to the - // "db.client.connection.idle.min" semantic conventions. It represents the - // minimum number of idle open connections allowed. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - DBClientConnectionIdleMinName = "db.client.connection.idle.min" - DBClientConnectionIdleMinUnit = "{connection}" - DBClientConnectionIdleMinDescription = "The minimum number of idle open connections allowed" - // DBClientConnectionMax is the metric conforming to the - // "db.client.connection.max" semantic conventions. It represents the maximum - // number of open connections allowed. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - DBClientConnectionMaxName = "db.client.connection.max" - DBClientConnectionMaxUnit = "{connection}" - DBClientConnectionMaxDescription = "The maximum number of open connections allowed" - // DBClientConnectionPendingRequests is the metric conforming to the - // "db.client.connection.pending_requests" semantic conventions. It represents - // the number of current pending requests for an open connection. - // Instrument: updowncounter - // Unit: {request} - // Stability: development - DBClientConnectionPendingRequestsName = "db.client.connection.pending_requests" - DBClientConnectionPendingRequestsUnit = "{request}" - DBClientConnectionPendingRequestsDescription = "The number of current pending requests for an open connection" - // DBClientConnectionTimeouts is the metric conforming to the - // "db.client.connection.timeouts" semantic conventions. It represents the - // number of connection timeouts that have occurred trying to obtain a - // connection from the pool. - // Instrument: counter - // Unit: {timeout} - // Stability: development - DBClientConnectionTimeoutsName = "db.client.connection.timeouts" - DBClientConnectionTimeoutsUnit = "{timeout}" - DBClientConnectionTimeoutsDescription = "The number of connection timeouts that have occurred trying to obtain a connection from the pool" - // DBClientConnectionUseTime is the metric conforming to the - // "db.client.connection.use_time" semantic conventions. It represents the time - // between borrowing a connection and returning it to the pool. - // Instrument: histogram - // Unit: s - // Stability: development - DBClientConnectionUseTimeName = "db.client.connection.use_time" - DBClientConnectionUseTimeUnit = "s" - DBClientConnectionUseTimeDescription = "The time between borrowing a connection and returning it to the pool" - // DBClientConnectionWaitTime is the metric conforming to the - // "db.client.connection.wait_time" semantic conventions. It represents the - // time it took to obtain an open connection from the pool. - // Instrument: histogram - // Unit: s - // Stability: development - DBClientConnectionWaitTimeName = "db.client.connection.wait_time" - DBClientConnectionWaitTimeUnit = "s" - DBClientConnectionWaitTimeDescription = "The time it took to obtain an open connection from the pool" - // DBClientConnectionsCreateTime is the metric conforming to the - // "db.client.connections.create_time" semantic conventions. It represents the - // deprecated, use `db.client.connection.create_time` instead. Note: the unit - // also changed from `ms` to `s`. - // Instrument: histogram - // Unit: ms - // Stability: development - // Deprecated: Replaced by `db.client.connection.create_time`. Note: the unit also changed from `ms` to `s`. - DBClientConnectionsCreateTimeName = "db.client.connections.create_time" - DBClientConnectionsCreateTimeUnit = "ms" - DBClientConnectionsCreateTimeDescription = "Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`." - // DBClientConnectionsIdleMax is the metric conforming to the - // "db.client.connections.idle.max" semantic conventions. It represents the - // deprecated, use `db.client.connection.idle.max` instead. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - // Deprecated: Replaced by `db.client.connection.idle.max`. - DBClientConnectionsIdleMaxName = "db.client.connections.idle.max" - DBClientConnectionsIdleMaxUnit = "{connection}" - DBClientConnectionsIdleMaxDescription = "Deprecated, use `db.client.connection.idle.max` instead." - // DBClientConnectionsIdleMin is the metric conforming to the - // "db.client.connections.idle.min" semantic conventions. It represents the - // deprecated, use `db.client.connection.idle.min` instead. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - // Deprecated: Replaced by `db.client.connection.idle.min`. - DBClientConnectionsIdleMinName = "db.client.connections.idle.min" - DBClientConnectionsIdleMinUnit = "{connection}" - DBClientConnectionsIdleMinDescription = "Deprecated, use `db.client.connection.idle.min` instead." - // DBClientConnectionsMax is the metric conforming to the - // "db.client.connections.max" semantic conventions. It represents the - // deprecated, use `db.client.connection.max` instead. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - // Deprecated: Replaced by `db.client.connection.max`. - DBClientConnectionsMaxName = "db.client.connections.max" - DBClientConnectionsMaxUnit = "{connection}" - DBClientConnectionsMaxDescription = "Deprecated, use `db.client.connection.max` instead." - // DBClientConnectionsPendingRequests is the metric conforming to the - // "db.client.connections.pending_requests" semantic conventions. It represents - // the deprecated, use `db.client.connection.pending_requests` instead. - // Instrument: updowncounter - // Unit: {request} - // Stability: development - // Deprecated: Replaced by `db.client.connection.pending_requests`. - DBClientConnectionsPendingRequestsName = "db.client.connections.pending_requests" - DBClientConnectionsPendingRequestsUnit = "{request}" - DBClientConnectionsPendingRequestsDescription = "Deprecated, use `db.client.connection.pending_requests` instead." - // DBClientConnectionsTimeouts is the metric conforming to the - // "db.client.connections.timeouts" semantic conventions. It represents the - // deprecated, use `db.client.connection.timeouts` instead. - // Instrument: counter - // Unit: {timeout} - // Stability: development - // Deprecated: Replaced by `db.client.connection.timeouts`. - DBClientConnectionsTimeoutsName = "db.client.connections.timeouts" - DBClientConnectionsTimeoutsUnit = "{timeout}" - DBClientConnectionsTimeoutsDescription = "Deprecated, use `db.client.connection.timeouts` instead." - // DBClientConnectionsUsage is the metric conforming to the - // "db.client.connections.usage" semantic conventions. It represents the - // deprecated, use `db.client.connection.count` instead. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - // Deprecated: Replaced by `db.client.connection.count`. - DBClientConnectionsUsageName = "db.client.connections.usage" - DBClientConnectionsUsageUnit = "{connection}" - DBClientConnectionsUsageDescription = "Deprecated, use `db.client.connection.count` instead." - // DBClientConnectionsUseTime is the metric conforming to the - // "db.client.connections.use_time" semantic conventions. It represents the - // deprecated, use `db.client.connection.use_time` instead. Note: the unit also - // changed from `ms` to `s`. - // Instrument: histogram - // Unit: ms - // Stability: development - // Deprecated: Replaced by `db.client.connection.use_time`. Note: the unit also changed from `ms` to `s`. - DBClientConnectionsUseTimeName = "db.client.connections.use_time" - DBClientConnectionsUseTimeUnit = "ms" - DBClientConnectionsUseTimeDescription = "Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`." - // DBClientConnectionsWaitTime is the metric conforming to the - // "db.client.connections.wait_time" semantic conventions. It represents the - // deprecated, use `db.client.connection.wait_time` instead. Note: the unit - // also changed from `ms` to `s`. - // Instrument: histogram - // Unit: ms - // Stability: development - // Deprecated: Replaced by `db.client.connection.wait_time`. Note: the unit also changed from `ms` to `s`. - DBClientConnectionsWaitTimeName = "db.client.connections.wait_time" - DBClientConnectionsWaitTimeUnit = "ms" - DBClientConnectionsWaitTimeDescription = "Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`." - // DBClientCosmosDBActiveInstanceCount is the metric conforming to the - // "db.client.cosmosdb.active_instance.count" semantic conventions. It - // represents the deprecated, use `azure.cosmosdb.client.active_instance.count` - // instead. - // Instrument: updowncounter - // Unit: {instance} - // Stability: development - // Deprecated: Replaced by `azure.cosmosdb.client.active_instance.count`. - DBClientCosmosDBActiveInstanceCountName = "db.client.cosmosdb.active_instance.count" - DBClientCosmosDBActiveInstanceCountUnit = "{instance}" - DBClientCosmosDBActiveInstanceCountDescription = "Deprecated, use `azure.cosmosdb.client.active_instance.count` instead." - // DBClientCosmosDBOperationRequestCharge is the metric conforming to the - // "db.client.cosmosdb.operation.request_charge" semantic conventions. It - // represents the deprecated, use - // `azure.cosmosdb.client.operation.request_charge` instead. - // Instrument: histogram - // Unit: {request_unit} - // Stability: development - // Deprecated: Replaced by `azure.cosmosdb.client.operation.request_charge`. - DBClientCosmosDBOperationRequestChargeName = "db.client.cosmosdb.operation.request_charge" - DBClientCosmosDBOperationRequestChargeUnit = "{request_unit}" - DBClientCosmosDBOperationRequestChargeDescription = "Deprecated, use `azure.cosmosdb.client.operation.request_charge` instead." - // DBClientOperationDuration is the metric conforming to the - // "db.client.operation.duration" semantic conventions. It represents the - // duration of database client operations. - // Instrument: histogram - // Unit: s - // Stability: release_candidate - DBClientOperationDurationName = "db.client.operation.duration" - DBClientOperationDurationUnit = "s" - DBClientOperationDurationDescription = "Duration of database client operations." - // DBClientResponseReturnedRows is the metric conforming to the - // "db.client.response.returned_rows" semantic conventions. It represents the - // actual number of records returned by the database operation. - // Instrument: histogram - // Unit: {row} - // Stability: development - DBClientResponseReturnedRowsName = "db.client.response.returned_rows" - DBClientResponseReturnedRowsUnit = "{row}" - DBClientResponseReturnedRowsDescription = "The actual number of records returned by the database operation." - // DNSLookupDuration is the metric conforming to the "dns.lookup.duration" - // semantic conventions. It represents the measures the time taken to perform a - // DNS lookup. - // Instrument: histogram - // Unit: s - // Stability: development - DNSLookupDurationName = "dns.lookup.duration" - DNSLookupDurationUnit = "s" - DNSLookupDurationDescription = "Measures the time taken to perform a DNS lookup." - // FaaSColdstarts is the metric conforming to the "faas.coldstarts" semantic - // conventions. It represents the number of invocation cold starts. - // Instrument: counter - // Unit: {coldstart} - // Stability: development - FaaSColdstartsName = "faas.coldstarts" - FaaSColdstartsUnit = "{coldstart}" - FaaSColdstartsDescription = "Number of invocation cold starts" - // FaaSCPUUsage is the metric conforming to the "faas.cpu_usage" semantic - // conventions. It represents the distribution of CPU usage per invocation. - // Instrument: histogram - // Unit: s - // Stability: development - FaaSCPUUsageName = "faas.cpu_usage" - FaaSCPUUsageUnit = "s" - FaaSCPUUsageDescription = "Distribution of CPU usage per invocation" - // FaaSErrors is the metric conforming to the "faas.errors" semantic - // conventions. It represents the number of invocation errors. - // Instrument: counter - // Unit: {error} - // Stability: development - FaaSErrorsName = "faas.errors" - FaaSErrorsUnit = "{error}" - FaaSErrorsDescription = "Number of invocation errors" - // FaaSInitDuration is the metric conforming to the "faas.init_duration" - // semantic conventions. It represents the measures the duration of the - // function's initialization, such as a cold start. - // Instrument: histogram - // Unit: s - // Stability: development - FaaSInitDurationName = "faas.init_duration" - FaaSInitDurationUnit = "s" - FaaSInitDurationDescription = "Measures the duration of the function's initialization, such as a cold start" - // FaaSInvocations is the metric conforming to the "faas.invocations" semantic - // conventions. It represents the number of successful invocations. - // Instrument: counter - // Unit: {invocation} - // Stability: development - FaaSInvocationsName = "faas.invocations" - FaaSInvocationsUnit = "{invocation}" - FaaSInvocationsDescription = "Number of successful invocations" - // FaaSInvokeDuration is the metric conforming to the "faas.invoke_duration" - // semantic conventions. It represents the measures the duration of the - // function's logic execution. - // Instrument: histogram - // Unit: s - // Stability: development - FaaSInvokeDurationName = "faas.invoke_duration" - FaaSInvokeDurationUnit = "s" - FaaSInvokeDurationDescription = "Measures the duration of the function's logic execution" - // FaaSMemUsage is the metric conforming to the "faas.mem_usage" semantic - // conventions. It represents the distribution of max memory usage per - // invocation. - // Instrument: histogram - // Unit: By - // Stability: development - FaaSMemUsageName = "faas.mem_usage" - FaaSMemUsageUnit = "By" - FaaSMemUsageDescription = "Distribution of max memory usage per invocation" - // FaaSNetIo is the metric conforming to the "faas.net_io" semantic - // conventions. It represents the distribution of net I/O usage per invocation. - // Instrument: histogram - // Unit: By - // Stability: development - FaaSNetIoName = "faas.net_io" - FaaSNetIoUnit = "By" - FaaSNetIoDescription = "Distribution of net I/O usage per invocation" - // FaaSTimeouts is the metric conforming to the "faas.timeouts" semantic - // conventions. It represents the number of invocation timeouts. - // Instrument: counter - // Unit: {timeout} - // Stability: development - FaaSTimeoutsName = "faas.timeouts" - FaaSTimeoutsUnit = "{timeout}" - FaaSTimeoutsDescription = "Number of invocation timeouts" - // GenAIClientOperationDuration is the metric conforming to the - // "gen_ai.client.operation.duration" semantic conventions. It represents the - // genAI operation duration. - // Instrument: histogram - // Unit: s - // Stability: development - GenAIClientOperationDurationName = "gen_ai.client.operation.duration" - GenAIClientOperationDurationUnit = "s" - GenAIClientOperationDurationDescription = "GenAI operation duration" - // GenAIClientTokenUsage is the metric conforming to the - // "gen_ai.client.token.usage" semantic conventions. It represents the measures - // number of input and output tokens used. - // Instrument: histogram - // Unit: {token} - // Stability: development - GenAIClientTokenUsageName = "gen_ai.client.token.usage" - GenAIClientTokenUsageUnit = "{token}" - GenAIClientTokenUsageDescription = "Measures number of input and output tokens used" - // GenAIServerRequestDuration is the metric conforming to the - // "gen_ai.server.request.duration" semantic conventions. It represents the - // generative AI server request duration such as time-to-last byte or last - // output token. - // Instrument: histogram - // Unit: s - // Stability: development - GenAIServerRequestDurationName = "gen_ai.server.request.duration" - GenAIServerRequestDurationUnit = "s" - GenAIServerRequestDurationDescription = "Generative AI server request duration such as time-to-last byte or last output token" - // GenAIServerTimePerOutputToken is the metric conforming to the - // "gen_ai.server.time_per_output_token" semantic conventions. It represents - // the time per output token generated after the first token for successful - // responses. - // Instrument: histogram - // Unit: s - // Stability: development - GenAIServerTimePerOutputTokenName = "gen_ai.server.time_per_output_token" - GenAIServerTimePerOutputTokenUnit = "s" - GenAIServerTimePerOutputTokenDescription = "Time per output token generated after the first token for successful responses" - // GenAIServerTimeToFirstToken is the metric conforming to the - // "gen_ai.server.time_to_first_token" semantic conventions. It represents the - // time to generate first token for successful responses. - // Instrument: histogram - // Unit: s - // Stability: development - GenAIServerTimeToFirstTokenName = "gen_ai.server.time_to_first_token" - GenAIServerTimeToFirstTokenUnit = "s" - GenAIServerTimeToFirstTokenDescription = "Time to generate first token for successful responses" - // GoConfigGogc is the metric conforming to the "go.config.gogc" semantic - // conventions. It represents the heap size target percentage configured by the - // user, otherwise 100. - // Instrument: updowncounter - // Unit: % - // Stability: development - GoConfigGogcName = "go.config.gogc" - GoConfigGogcUnit = "%" - GoConfigGogcDescription = "Heap size target percentage configured by the user, otherwise 100." - // GoGoroutineCount is the metric conforming to the "go.goroutine.count" - // semantic conventions. It represents the count of live goroutines. - // Instrument: updowncounter - // Unit: {goroutine} - // Stability: development - GoGoroutineCountName = "go.goroutine.count" - GoGoroutineCountUnit = "{goroutine}" - GoGoroutineCountDescription = "Count of live goroutines." - // GoMemoryAllocated is the metric conforming to the "go.memory.allocated" - // semantic conventions. It represents the memory allocated to the heap by the - // application. - // Instrument: counter - // Unit: By - // Stability: development - GoMemoryAllocatedName = "go.memory.allocated" - GoMemoryAllocatedUnit = "By" - GoMemoryAllocatedDescription = "Memory allocated to the heap by the application." - // GoMemoryAllocations is the metric conforming to the "go.memory.allocations" - // semantic conventions. It represents the count of allocations to the heap by - // the application. - // Instrument: counter - // Unit: {allocation} - // Stability: development - GoMemoryAllocationsName = "go.memory.allocations" - GoMemoryAllocationsUnit = "{allocation}" - GoMemoryAllocationsDescription = "Count of allocations to the heap by the application." - // GoMemoryGCGoal is the metric conforming to the "go.memory.gc.goal" semantic - // conventions. It represents the heap size target for the end of the GC cycle. - // Instrument: updowncounter - // Unit: By - // Stability: development - GoMemoryGCGoalName = "go.memory.gc.goal" - GoMemoryGCGoalUnit = "By" - GoMemoryGCGoalDescription = "Heap size target for the end of the GC cycle." - // GoMemoryLimit is the metric conforming to the "go.memory.limit" semantic - // conventions. It represents the go runtime memory limit configured by the - // user, if a limit exists. - // Instrument: updowncounter - // Unit: By - // Stability: development - GoMemoryLimitName = "go.memory.limit" - GoMemoryLimitUnit = "By" - GoMemoryLimitDescription = "Go runtime memory limit configured by the user, if a limit exists." - // GoMemoryUsed is the metric conforming to the "go.memory.used" semantic - // conventions. It represents the memory used by the Go runtime. - // Instrument: updowncounter - // Unit: By - // Stability: development - GoMemoryUsedName = "go.memory.used" - GoMemoryUsedUnit = "By" - GoMemoryUsedDescription = "Memory used by the Go runtime." - // GoProcessorLimit is the metric conforming to the "go.processor.limit" - // semantic conventions. It represents the number of OS threads that can - // execute user-level Go code simultaneously. - // Instrument: updowncounter - // Unit: {thread} - // Stability: development - GoProcessorLimitName = "go.processor.limit" - GoProcessorLimitUnit = "{thread}" - GoProcessorLimitDescription = "The number of OS threads that can execute user-level Go code simultaneously." - // GoScheduleDuration is the metric conforming to the "go.schedule.duration" - // semantic conventions. It represents the time goroutines have spent in the - // scheduler in a runnable state before actually running. - // Instrument: histogram - // Unit: s - // Stability: development - GoScheduleDurationName = "go.schedule.duration" - GoScheduleDurationUnit = "s" - GoScheduleDurationDescription = "The time goroutines have spent in the scheduler in a runnable state before actually running." - // HTTPClientActiveRequests is the metric conforming to the - // "http.client.active_requests" semantic conventions. It represents the number - // of active HTTP requests. - // Instrument: updowncounter - // Unit: {request} - // Stability: development - HTTPClientActiveRequestsName = "http.client.active_requests" - HTTPClientActiveRequestsUnit = "{request}" - HTTPClientActiveRequestsDescription = "Number of active HTTP requests." - // HTTPClientConnectionDuration is the metric conforming to the - // "http.client.connection.duration" semantic conventions. It represents the - // duration of the successfully established outbound HTTP connections. - // Instrument: histogram - // Unit: s - // Stability: development - HTTPClientConnectionDurationName = "http.client.connection.duration" - HTTPClientConnectionDurationUnit = "s" - HTTPClientConnectionDurationDescription = "The duration of the successfully established outbound HTTP connections." - // HTTPClientOpenConnections is the metric conforming to the - // "http.client.open_connections" semantic conventions. It represents the - // number of outbound HTTP connections that are currently active or idle on the - // client. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - HTTPClientOpenConnectionsName = "http.client.open_connections" - HTTPClientOpenConnectionsUnit = "{connection}" - HTTPClientOpenConnectionsDescription = "Number of outbound HTTP connections that are currently active or idle on the client." - // HTTPClientRequestBodySize is the metric conforming to the - // "http.client.request.body.size" semantic conventions. It represents the size - // of HTTP client request bodies. - // Instrument: histogram - // Unit: By - // Stability: development - HTTPClientRequestBodySizeName = "http.client.request.body.size" - HTTPClientRequestBodySizeUnit = "By" - HTTPClientRequestBodySizeDescription = "Size of HTTP client request bodies." - // HTTPClientRequestDuration is the metric conforming to the - // "http.client.request.duration" semantic conventions. It represents the - // duration of HTTP client requests. - // Instrument: histogram - // Unit: s - // Stability: stable - HTTPClientRequestDurationName = "http.client.request.duration" - HTTPClientRequestDurationUnit = "s" - HTTPClientRequestDurationDescription = "Duration of HTTP client requests." - // HTTPClientResponseBodySize is the metric conforming to the - // "http.client.response.body.size" semantic conventions. It represents the - // size of HTTP client response bodies. - // Instrument: histogram - // Unit: By - // Stability: development - HTTPClientResponseBodySizeName = "http.client.response.body.size" - HTTPClientResponseBodySizeUnit = "By" - HTTPClientResponseBodySizeDescription = "Size of HTTP client response bodies." - // HTTPServerActiveRequests is the metric conforming to the - // "http.server.active_requests" semantic conventions. It represents the number - // of active HTTP server requests. - // Instrument: updowncounter - // Unit: {request} - // Stability: development - HTTPServerActiveRequestsName = "http.server.active_requests" - HTTPServerActiveRequestsUnit = "{request}" - HTTPServerActiveRequestsDescription = "Number of active HTTP server requests." - // HTTPServerRequestBodySize is the metric conforming to the - // "http.server.request.body.size" semantic conventions. It represents the size - // of HTTP server request bodies. - // Instrument: histogram - // Unit: By - // Stability: development - HTTPServerRequestBodySizeName = "http.server.request.body.size" - HTTPServerRequestBodySizeUnit = "By" - HTTPServerRequestBodySizeDescription = "Size of HTTP server request bodies." - // HTTPServerRequestDuration is the metric conforming to the - // "http.server.request.duration" semantic conventions. It represents the - // duration of HTTP server requests. - // Instrument: histogram - // Unit: s - // Stability: stable - HTTPServerRequestDurationName = "http.server.request.duration" - HTTPServerRequestDurationUnit = "s" - HTTPServerRequestDurationDescription = "Duration of HTTP server requests." - // HTTPServerResponseBodySize is the metric conforming to the - // "http.server.response.body.size" semantic conventions. It represents the - // size of HTTP server response bodies. - // Instrument: histogram - // Unit: By - // Stability: development - HTTPServerResponseBodySizeName = "http.server.response.body.size" - HTTPServerResponseBodySizeUnit = "By" - HTTPServerResponseBodySizeDescription = "Size of HTTP server response bodies." - // HwEnergy is the metric conforming to the "hw.energy" semantic conventions. - // It represents the energy consumed by the component. - // Instrument: counter - // Unit: J - // Stability: development - HwEnergyName = "hw.energy" - HwEnergyUnit = "J" - HwEnergyDescription = "Energy consumed by the component" - // HwErrors is the metric conforming to the "hw.errors" semantic conventions. - // It represents the number of errors encountered by the component. - // Instrument: counter - // Unit: {error} - // Stability: development - HwErrorsName = "hw.errors" - HwErrorsUnit = "{error}" - HwErrorsDescription = "Number of errors encountered by the component" - // HwPower is the metric conforming to the "hw.power" semantic conventions. It - // represents the instantaneous power consumed by the component. - // Instrument: gauge - // Unit: W - // Stability: development - HwPowerName = "hw.power" - HwPowerUnit = "W" - HwPowerDescription = "Instantaneous power consumed by the component" - // HwStatus is the metric conforming to the "hw.status" semantic conventions. - // It represents the operational status: `1` (true) or `0` (false) for each of - // the possible states. - // Instrument: updowncounter - // Unit: 1 - // Stability: development - HwStatusName = "hw.status" - HwStatusUnit = "1" - HwStatusDescription = "Operational status: `1` (true) or `0` (false) for each of the possible states" - // K8SCronJobActiveJobs is the metric conforming to the - // "k8s.cronjob.active_jobs" semantic conventions. It represents the number of - // actively running jobs for a cronjob. - // Instrument: updowncounter - // Unit: {job} - // Stability: development - K8SCronJobActiveJobsName = "k8s.cronjob.active_jobs" - K8SCronJobActiveJobsUnit = "{job}" - K8SCronJobActiveJobsDescription = "The number of actively running jobs for a cronjob" - // K8SDaemonSetCurrentScheduledNodes is the metric conforming to the - // "k8s.daemonset.current_scheduled_nodes" semantic conventions. It represents - // the number of nodes that are running at least 1 daemon pod and are supposed - // to run the daemon pod. - // Instrument: updowncounter - // Unit: {node} - // Stability: development - K8SDaemonSetCurrentScheduledNodesName = "k8s.daemonset.current_scheduled_nodes" - K8SDaemonSetCurrentScheduledNodesUnit = "{node}" - K8SDaemonSetCurrentScheduledNodesDescription = "Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod" - // K8SDaemonSetDesiredScheduledNodes is the metric conforming to the - // "k8s.daemonset.desired_scheduled_nodes" semantic conventions. It represents - // the number of nodes that should be running the daemon pod (including nodes - // currently running the daemon pod). - // Instrument: updowncounter - // Unit: {node} - // Stability: development - K8SDaemonSetDesiredScheduledNodesName = "k8s.daemonset.desired_scheduled_nodes" - K8SDaemonSetDesiredScheduledNodesUnit = "{node}" - K8SDaemonSetDesiredScheduledNodesDescription = "Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod)" - // K8SDaemonSetMisscheduledNodes is the metric conforming to the - // "k8s.daemonset.misscheduled_nodes" semantic conventions. It represents the - // number of nodes that are running the daemon pod, but are not supposed to run - // the daemon pod. - // Instrument: updowncounter - // Unit: {node} - // Stability: development - K8SDaemonSetMisscheduledNodesName = "k8s.daemonset.misscheduled_nodes" - K8SDaemonSetMisscheduledNodesUnit = "{node}" - K8SDaemonSetMisscheduledNodesDescription = "Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod" - // K8SDaemonSetReadyNodes is the metric conforming to the - // "k8s.daemonset.ready_nodes" semantic conventions. It represents the number - // of nodes that should be running the daemon pod and have one or more of the - // daemon pod running and ready. - // Instrument: updowncounter - // Unit: {node} - // Stability: development - K8SDaemonSetReadyNodesName = "k8s.daemonset.ready_nodes" - K8SDaemonSetReadyNodesUnit = "{node}" - K8SDaemonSetReadyNodesDescription = "Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready" - // K8SDeploymentAvailablePods is the metric conforming to the - // "k8s.deployment.available_pods" semantic conventions. It represents the - // total number of available replica pods (ready for at least minReadySeconds) - // targeted by this deployment. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SDeploymentAvailablePodsName = "k8s.deployment.available_pods" - K8SDeploymentAvailablePodsUnit = "{pod}" - K8SDeploymentAvailablePodsDescription = "Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment" - // K8SDeploymentDesiredPods is the metric conforming to the - // "k8s.deployment.desired_pods" semantic conventions. It represents the number - // of desired replica pods in this deployment. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SDeploymentDesiredPodsName = "k8s.deployment.desired_pods" - K8SDeploymentDesiredPodsUnit = "{pod}" - K8SDeploymentDesiredPodsDescription = "Number of desired replica pods in this deployment" - // K8SHpaCurrentPods is the metric conforming to the "k8s.hpa.current_pods" - // semantic conventions. It represents the current number of replica pods - // managed by this horizontal pod autoscaler, as last seen by the autoscaler. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SHpaCurrentPodsName = "k8s.hpa.current_pods" - K8SHpaCurrentPodsUnit = "{pod}" - K8SHpaCurrentPodsDescription = "Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler" - // K8SHpaDesiredPods is the metric conforming to the "k8s.hpa.desired_pods" - // semantic conventions. It represents the desired number of replica pods - // managed by this horizontal pod autoscaler, as last calculated by the - // autoscaler. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SHpaDesiredPodsName = "k8s.hpa.desired_pods" - K8SHpaDesiredPodsUnit = "{pod}" - K8SHpaDesiredPodsDescription = "Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler" - // K8SHpaMaxPods is the metric conforming to the "k8s.hpa.max_pods" semantic - // conventions. It represents the upper limit for the number of replica pods to - // which the autoscaler can scale up. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SHpaMaxPodsName = "k8s.hpa.max_pods" - K8SHpaMaxPodsUnit = "{pod}" - K8SHpaMaxPodsDescription = "The upper limit for the number of replica pods to which the autoscaler can scale up" - // K8SHpaMinPods is the metric conforming to the "k8s.hpa.min_pods" semantic - // conventions. It represents the lower limit for the number of replica pods to - // which the autoscaler can scale down. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SHpaMinPodsName = "k8s.hpa.min_pods" - K8SHpaMinPodsUnit = "{pod}" - K8SHpaMinPodsDescription = "The lower limit for the number of replica pods to which the autoscaler can scale down" - // K8SJobActivePods is the metric conforming to the "k8s.job.active_pods" - // semantic conventions. It represents the number of pending and actively - // running pods for a job. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SJobActivePodsName = "k8s.job.active_pods" - K8SJobActivePodsUnit = "{pod}" - K8SJobActivePodsDescription = "The number of pending and actively running pods for a job" - // K8SJobDesiredSuccessfulPods is the metric conforming to the - // "k8s.job.desired_successful_pods" semantic conventions. It represents the - // desired number of successfully finished pods the job should be run with. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SJobDesiredSuccessfulPodsName = "k8s.job.desired_successful_pods" - K8SJobDesiredSuccessfulPodsUnit = "{pod}" - K8SJobDesiredSuccessfulPodsDescription = "The desired number of successfully finished pods the job should be run with" - // K8SJobFailedPods is the metric conforming to the "k8s.job.failed_pods" - // semantic conventions. It represents the number of pods which reached phase - // Failed for a job. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SJobFailedPodsName = "k8s.job.failed_pods" - K8SJobFailedPodsUnit = "{pod}" - K8SJobFailedPodsDescription = "The number of pods which reached phase Failed for a job" - // K8SJobMaxParallelPods is the metric conforming to the - // "k8s.job.max_parallel_pods" semantic conventions. It represents the max - // desired number of pods the job should run at any given time. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SJobMaxParallelPodsName = "k8s.job.max_parallel_pods" - K8SJobMaxParallelPodsUnit = "{pod}" - K8SJobMaxParallelPodsDescription = "The max desired number of pods the job should run at any given time" - // K8SJobSuccessfulPods is the metric conforming to the - // "k8s.job.successful_pods" semantic conventions. It represents the number of - // pods which reached phase Succeeded for a job. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SJobSuccessfulPodsName = "k8s.job.successful_pods" - K8SJobSuccessfulPodsUnit = "{pod}" - K8SJobSuccessfulPodsDescription = "The number of pods which reached phase Succeeded for a job" - // K8SNamespacePhase is the metric conforming to the "k8s.namespace.phase" - // semantic conventions. It represents the describes number of K8s namespaces - // that are currently in a given phase. - // Instrument: updowncounter - // Unit: {namespace} - // Stability: development - K8SNamespacePhaseName = "k8s.namespace.phase" - K8SNamespacePhaseUnit = "{namespace}" - K8SNamespacePhaseDescription = "Describes number of K8s namespaces that are currently in a given phase." - // K8SNodeCPUTime is the metric conforming to the "k8s.node.cpu.time" semantic - // conventions. It represents the total CPU time consumed. - // Instrument: counter - // Unit: s - // Stability: development - K8SNodeCPUTimeName = "k8s.node.cpu.time" - K8SNodeCPUTimeUnit = "s" - K8SNodeCPUTimeDescription = "Total CPU time consumed" - // K8SNodeCPUUsage is the metric conforming to the "k8s.node.cpu.usage" - // semantic conventions. It represents the node's CPU usage, measured in cpus. - // Range from 0 to the number of allocatable CPUs. - // Instrument: gauge - // Unit: {cpu} - // Stability: development - K8SNodeCPUUsageName = "k8s.node.cpu.usage" - K8SNodeCPUUsageUnit = "{cpu}" - K8SNodeCPUUsageDescription = "Node's CPU usage, measured in cpus. Range from 0 to the number of allocatable CPUs" - // K8SNodeMemoryUsage is the metric conforming to the "k8s.node.memory.usage" - // semantic conventions. It represents the memory usage of the Node. - // Instrument: gauge - // Unit: By - // Stability: development - K8SNodeMemoryUsageName = "k8s.node.memory.usage" - K8SNodeMemoryUsageUnit = "By" - K8SNodeMemoryUsageDescription = "Memory usage of the Node" - // K8SNodeNetworkErrors is the metric conforming to the - // "k8s.node.network.errors" semantic conventions. It represents the node - // network errors. - // Instrument: counter - // Unit: {error} - // Stability: development - K8SNodeNetworkErrorsName = "k8s.node.network.errors" - K8SNodeNetworkErrorsUnit = "{error}" - K8SNodeNetworkErrorsDescription = "Node network errors" - // K8SNodeNetworkIo is the metric conforming to the "k8s.node.network.io" - // semantic conventions. It represents the network bytes for the Node. - // Instrument: counter - // Unit: By - // Stability: development - K8SNodeNetworkIoName = "k8s.node.network.io" - K8SNodeNetworkIoUnit = "By" - K8SNodeNetworkIoDescription = "Network bytes for the Node" - // K8SNodeUptime is the metric conforming to the "k8s.node.uptime" semantic - // conventions. It represents the time the Node has been running. - // Instrument: gauge - // Unit: s - // Stability: development - K8SNodeUptimeName = "k8s.node.uptime" - K8SNodeUptimeUnit = "s" - K8SNodeUptimeDescription = "The time the Node has been running" - // K8SPodCPUTime is the metric conforming to the "k8s.pod.cpu.time" semantic - // conventions. It represents the total CPU time consumed. - // Instrument: counter - // Unit: s - // Stability: development - K8SPodCPUTimeName = "k8s.pod.cpu.time" - K8SPodCPUTimeUnit = "s" - K8SPodCPUTimeDescription = "Total CPU time consumed" - // K8SPodCPUUsage is the metric conforming to the "k8s.pod.cpu.usage" semantic - // conventions. It represents the pod's CPU usage, measured in cpus. Range from - // 0 to the number of allocatable CPUs. - // Instrument: gauge - // Unit: {cpu} - // Stability: development - K8SPodCPUUsageName = "k8s.pod.cpu.usage" - K8SPodCPUUsageUnit = "{cpu}" - K8SPodCPUUsageDescription = "Pod's CPU usage, measured in cpus. Range from 0 to the number of allocatable CPUs" - // K8SPodMemoryUsage is the metric conforming to the "k8s.pod.memory.usage" - // semantic conventions. It represents the memory usage of the Pod. - // Instrument: gauge - // Unit: By - // Stability: development - K8SPodMemoryUsageName = "k8s.pod.memory.usage" - K8SPodMemoryUsageUnit = "By" - K8SPodMemoryUsageDescription = "Memory usage of the Pod" - // K8SPodNetworkErrors is the metric conforming to the "k8s.pod.network.errors" - // semantic conventions. It represents the pod network errors. - // Instrument: counter - // Unit: {error} - // Stability: development - K8SPodNetworkErrorsName = "k8s.pod.network.errors" - K8SPodNetworkErrorsUnit = "{error}" - K8SPodNetworkErrorsDescription = "Pod network errors" - // K8SPodNetworkIo is the metric conforming to the "k8s.pod.network.io" - // semantic conventions. It represents the network bytes for the Pod. - // Instrument: counter - // Unit: By - // Stability: development - K8SPodNetworkIoName = "k8s.pod.network.io" - K8SPodNetworkIoUnit = "By" - K8SPodNetworkIoDescription = "Network bytes for the Pod" - // K8SPodUptime is the metric conforming to the "k8s.pod.uptime" semantic - // conventions. It represents the time the Pod has been running. - // Instrument: gauge - // Unit: s - // Stability: development - K8SPodUptimeName = "k8s.pod.uptime" - K8SPodUptimeUnit = "s" - K8SPodUptimeDescription = "The time the Pod has been running" - // K8SReplicaSetAvailablePods is the metric conforming to the - // "k8s.replicaset.available_pods" semantic conventions. It represents the - // total number of available replica pods (ready for at least minReadySeconds) - // targeted by this replicaset. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SReplicaSetAvailablePodsName = "k8s.replicaset.available_pods" - K8SReplicaSetAvailablePodsUnit = "{pod}" - K8SReplicaSetAvailablePodsDescription = "Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset" - // K8SReplicaSetDesiredPods is the metric conforming to the - // "k8s.replicaset.desired_pods" semantic conventions. It represents the number - // of desired replica pods in this replicaset. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SReplicaSetDesiredPodsName = "k8s.replicaset.desired_pods" - K8SReplicaSetDesiredPodsUnit = "{pod}" - K8SReplicaSetDesiredPodsDescription = "Number of desired replica pods in this replicaset" - // K8SReplicationControllerAvailablePods is the metric conforming to the - // "k8s.replication_controller.available_pods" semantic conventions. It - // represents the total number of available replica pods (ready for at least - // minReadySeconds) targeted by this replication controller. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SReplicationControllerAvailablePodsName = "k8s.replication_controller.available_pods" - K8SReplicationControllerAvailablePodsUnit = "{pod}" - K8SReplicationControllerAvailablePodsDescription = "Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller" - // K8SReplicationControllerDesiredPods is the metric conforming to the - // "k8s.replication_controller.desired_pods" semantic conventions. It - // represents the number of desired replica pods in this replication - // controller. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SReplicationControllerDesiredPodsName = "k8s.replication_controller.desired_pods" - K8SReplicationControllerDesiredPodsUnit = "{pod}" - K8SReplicationControllerDesiredPodsDescription = "Number of desired replica pods in this replication controller" - // K8SStatefulSetCurrentPods is the metric conforming to the - // "k8s.statefulset.current_pods" semantic conventions. It represents the - // number of replica pods created by the statefulset controller from the - // statefulset version indicated by currentRevision. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SStatefulSetCurrentPodsName = "k8s.statefulset.current_pods" - K8SStatefulSetCurrentPodsUnit = "{pod}" - K8SStatefulSetCurrentPodsDescription = "The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision" - // K8SStatefulSetDesiredPods is the metric conforming to the - // "k8s.statefulset.desired_pods" semantic conventions. It represents the - // number of desired replica pods in this statefulset. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SStatefulSetDesiredPodsName = "k8s.statefulset.desired_pods" - K8SStatefulSetDesiredPodsUnit = "{pod}" - K8SStatefulSetDesiredPodsDescription = "Number of desired replica pods in this statefulset" - // K8SStatefulSetReadyPods is the metric conforming to the - // "k8s.statefulset.ready_pods" semantic conventions. It represents the number - // of replica pods created for this statefulset with a Ready Condition. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SStatefulSetReadyPodsName = "k8s.statefulset.ready_pods" - K8SStatefulSetReadyPodsUnit = "{pod}" - K8SStatefulSetReadyPodsDescription = "The number of replica pods created for this statefulset with a Ready Condition" - // K8SStatefulSetUpdatedPods is the metric conforming to the - // "k8s.statefulset.updated_pods" semantic conventions. It represents the - // number of replica pods created by the statefulset controller from the - // statefulset version indicated by updateRevision. - // Instrument: updowncounter - // Unit: {pod} - // Stability: development - K8SStatefulSetUpdatedPodsName = "k8s.statefulset.updated_pods" - K8SStatefulSetUpdatedPodsUnit = "{pod}" - K8SStatefulSetUpdatedPodsDescription = "Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision" - // KestrelActiveConnections is the metric conforming to the - // "kestrel.active_connections" semantic conventions. It represents the number - // of connections that are currently active on the server. - // Instrument: updowncounter - // Unit: {connection} - // Stability: stable - KestrelActiveConnectionsName = "kestrel.active_connections" - KestrelActiveConnectionsUnit = "{connection}" - KestrelActiveConnectionsDescription = "Number of connections that are currently active on the server." - // KestrelActiveTLSHandshakes is the metric conforming to the - // "kestrel.active_tls_handshakes" semantic conventions. It represents the - // number of TLS handshakes that are currently in progress on the server. - // Instrument: updowncounter - // Unit: {handshake} - // Stability: stable - KestrelActiveTLSHandshakesName = "kestrel.active_tls_handshakes" - KestrelActiveTLSHandshakesUnit = "{handshake}" - KestrelActiveTLSHandshakesDescription = "Number of TLS handshakes that are currently in progress on the server." - // KestrelConnectionDuration is the metric conforming to the - // "kestrel.connection.duration" semantic conventions. It represents the - // duration of connections on the server. - // Instrument: histogram - // Unit: s - // Stability: stable - KestrelConnectionDurationName = "kestrel.connection.duration" - KestrelConnectionDurationUnit = "s" - KestrelConnectionDurationDescription = "The duration of connections on the server." - // KestrelQueuedConnections is the metric conforming to the - // "kestrel.queued_connections" semantic conventions. It represents the number - // of connections that are currently queued and are waiting to start. - // Instrument: updowncounter - // Unit: {connection} - // Stability: stable - KestrelQueuedConnectionsName = "kestrel.queued_connections" - KestrelQueuedConnectionsUnit = "{connection}" - KestrelQueuedConnectionsDescription = "Number of connections that are currently queued and are waiting to start." - // KestrelQueuedRequests is the metric conforming to the - // "kestrel.queued_requests" semantic conventions. It represents the number of - // HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are - // currently queued and are waiting to start. - // Instrument: updowncounter - // Unit: {request} - // Stability: stable - KestrelQueuedRequestsName = "kestrel.queued_requests" - KestrelQueuedRequestsUnit = "{request}" - KestrelQueuedRequestsDescription = "Number of HTTP requests on multiplexed connections (HTTP/2 and HTTP/3) that are currently queued and are waiting to start." - // KestrelRejectedConnections is the metric conforming to the - // "kestrel.rejected_connections" semantic conventions. It represents the - // number of connections rejected by the server. - // Instrument: counter - // Unit: {connection} - // Stability: stable - KestrelRejectedConnectionsName = "kestrel.rejected_connections" - KestrelRejectedConnectionsUnit = "{connection}" - KestrelRejectedConnectionsDescription = "Number of connections rejected by the server." - // KestrelTLSHandshakeDuration is the metric conforming to the - // "kestrel.tls_handshake.duration" semantic conventions. It represents the - // duration of TLS handshakes on the server. - // Instrument: histogram - // Unit: s - // Stability: stable - KestrelTLSHandshakeDurationName = "kestrel.tls_handshake.duration" - KestrelTLSHandshakeDurationUnit = "s" - KestrelTLSHandshakeDurationDescription = "The duration of TLS handshakes on the server." - // KestrelUpgradedConnections is the metric conforming to the - // "kestrel.upgraded_connections" semantic conventions. It represents the - // number of connections that are currently upgraded (WebSockets). . - // Instrument: updowncounter - // Unit: {connection} - // Stability: stable - KestrelUpgradedConnectionsName = "kestrel.upgraded_connections" - KestrelUpgradedConnectionsUnit = "{connection}" - KestrelUpgradedConnectionsDescription = "Number of connections that are currently upgraded (WebSockets). ." - // MessagingClientConsumedMessages is the metric conforming to the - // "messaging.client.consumed.messages" semantic conventions. It represents the - // number of messages that were delivered to the application. - // Instrument: counter - // Unit: {message} - // Stability: development - MessagingClientConsumedMessagesName = "messaging.client.consumed.messages" - MessagingClientConsumedMessagesUnit = "{message}" - MessagingClientConsumedMessagesDescription = "Number of messages that were delivered to the application." - // MessagingClientOperationDuration is the metric conforming to the - // "messaging.client.operation.duration" semantic conventions. It represents - // the duration of messaging operation initiated by a producer or consumer - // client. - // Instrument: histogram - // Unit: s - // Stability: development - MessagingClientOperationDurationName = "messaging.client.operation.duration" - MessagingClientOperationDurationUnit = "s" - MessagingClientOperationDurationDescription = "Duration of messaging operation initiated by a producer or consumer client." - // MessagingClientPublishedMessages is the metric conforming to the - // "messaging.client.published.messages" semantic conventions. It represents - // the deprecated. Use `messaging.client.sent.messages` instead. - // Instrument: counter - // Unit: {message} - // Stability: development - // Deprecated: Replaced by `messaging.client.sent.messages`. - MessagingClientPublishedMessagesName = "messaging.client.published.messages" - MessagingClientPublishedMessagesUnit = "{message}" - MessagingClientPublishedMessagesDescription = "Deprecated. Use `messaging.client.sent.messages` instead." - // MessagingClientSentMessages is the metric conforming to the - // "messaging.client.sent.messages" semantic conventions. It represents the - // number of messages producer attempted to send to the broker. - // Instrument: counter - // Unit: {message} - // Stability: development - MessagingClientSentMessagesName = "messaging.client.sent.messages" - MessagingClientSentMessagesUnit = "{message}" - MessagingClientSentMessagesDescription = "Number of messages producer attempted to send to the broker." - // MessagingProcessDuration is the metric conforming to the - // "messaging.process.duration" semantic conventions. It represents the - // duration of processing operation. - // Instrument: histogram - // Unit: s - // Stability: development - MessagingProcessDurationName = "messaging.process.duration" - MessagingProcessDurationUnit = "s" - MessagingProcessDurationDescription = "Duration of processing operation." - // MessagingProcessMessages is the metric conforming to the - // "messaging.process.messages" semantic conventions. It represents the - // deprecated. Use `messaging.client.consumed.messages` instead. - // Instrument: counter - // Unit: {message} - // Stability: development - // Deprecated: Replaced by `messaging.client.consumed.messages`. - MessagingProcessMessagesName = "messaging.process.messages" - MessagingProcessMessagesUnit = "{message}" - MessagingProcessMessagesDescription = "Deprecated. Use `messaging.client.consumed.messages` instead." - // MessagingPublishDuration is the metric conforming to the - // "messaging.publish.duration" semantic conventions. It represents the - // deprecated. Use `messaging.client.operation.duration` instead. - // Instrument: histogram - // Unit: s - // Stability: development - // Deprecated: Replaced by `messaging.client.operation.duration`. - MessagingPublishDurationName = "messaging.publish.duration" - MessagingPublishDurationUnit = "s" - MessagingPublishDurationDescription = "Deprecated. Use `messaging.client.operation.duration` instead." - // MessagingPublishMessages is the metric conforming to the - // "messaging.publish.messages" semantic conventions. It represents the - // deprecated. Use `messaging.client.produced.messages` instead. - // Instrument: counter - // Unit: {message} - // Stability: development - // Deprecated: Replaced by `messaging.client.produced.messages`. - MessagingPublishMessagesName = "messaging.publish.messages" - MessagingPublishMessagesUnit = "{message}" - MessagingPublishMessagesDescription = "Deprecated. Use `messaging.client.produced.messages` instead." - // MessagingReceiveDuration is the metric conforming to the - // "messaging.receive.duration" semantic conventions. It represents the - // deprecated. Use `messaging.client.operation.duration` instead. - // Instrument: histogram - // Unit: s - // Stability: development - // Deprecated: Replaced by `messaging.client.operation.duration`. - MessagingReceiveDurationName = "messaging.receive.duration" - MessagingReceiveDurationUnit = "s" - MessagingReceiveDurationDescription = "Deprecated. Use `messaging.client.operation.duration` instead." - // MessagingReceiveMessages is the metric conforming to the - // "messaging.receive.messages" semantic conventions. It represents the - // deprecated. Use `messaging.client.consumed.messages` instead. - // Instrument: counter - // Unit: {message} - // Stability: development - // Deprecated: Replaced by `messaging.client.consumed.messages`. - MessagingReceiveMessagesName = "messaging.receive.messages" - MessagingReceiveMessagesUnit = "{message}" - MessagingReceiveMessagesDescription = "Deprecated. Use `messaging.client.consumed.messages` instead." - // ProcessContextSwitches is the metric conforming to the - // "process.context_switches" semantic conventions. It represents the number of - // times the process has been context switched. - // Instrument: counter - // Unit: {count} - // Stability: development - ProcessContextSwitchesName = "process.context_switches" - ProcessContextSwitchesUnit = "{count}" - ProcessContextSwitchesDescription = "Number of times the process has been context switched." - // ProcessCPUTime is the metric conforming to the "process.cpu.time" semantic - // conventions. It represents the total CPU seconds broken down by different - // states. - // Instrument: counter - // Unit: s - // Stability: development - ProcessCPUTimeName = "process.cpu.time" - ProcessCPUTimeUnit = "s" - ProcessCPUTimeDescription = "Total CPU seconds broken down by different states." - // ProcessCPUUtilization is the metric conforming to the - // "process.cpu.utilization" semantic conventions. It represents the difference - // in process.cpu.time since the last measurement, divided by the elapsed time - // and number of CPUs available to the process. - // Instrument: gauge - // Unit: 1 - // Stability: development - ProcessCPUUtilizationName = "process.cpu.utilization" - ProcessCPUUtilizationUnit = "1" - ProcessCPUUtilizationDescription = "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process." - // ProcessDiskIo is the metric conforming to the "process.disk.io" semantic - // conventions. It represents the disk bytes transferred. - // Instrument: counter - // Unit: By - // Stability: development - ProcessDiskIoName = "process.disk.io" - ProcessDiskIoUnit = "By" - ProcessDiskIoDescription = "Disk bytes transferred." - // ProcessMemoryUsage is the metric conforming to the "process.memory.usage" - // semantic conventions. It represents the amount of physical memory in use. - // Instrument: updowncounter - // Unit: By - // Stability: development - ProcessMemoryUsageName = "process.memory.usage" - ProcessMemoryUsageUnit = "By" - ProcessMemoryUsageDescription = "The amount of physical memory in use." - // ProcessMemoryVirtual is the metric conforming to the - // "process.memory.virtual" semantic conventions. It represents the amount of - // committed virtual memory. - // Instrument: updowncounter - // Unit: By - // Stability: development - ProcessMemoryVirtualName = "process.memory.virtual" - ProcessMemoryVirtualUnit = "By" - ProcessMemoryVirtualDescription = "The amount of committed virtual memory." - // ProcessNetworkIo is the metric conforming to the "process.network.io" - // semantic conventions. It represents the network bytes transferred. - // Instrument: counter - // Unit: By - // Stability: development - ProcessNetworkIoName = "process.network.io" - ProcessNetworkIoUnit = "By" - ProcessNetworkIoDescription = "Network bytes transferred." - // ProcessOpenFileDescriptorCount is the metric conforming to the - // "process.open_file_descriptor.count" semantic conventions. It represents the - // number of file descriptors in use by the process. - // Instrument: updowncounter - // Unit: {count} - // Stability: development - ProcessOpenFileDescriptorCountName = "process.open_file_descriptor.count" - ProcessOpenFileDescriptorCountUnit = "{count}" - ProcessOpenFileDescriptorCountDescription = "Number of file descriptors in use by the process." - // ProcessPagingFaults is the metric conforming to the "process.paging.faults" - // semantic conventions. It represents the number of page faults the process - // has made. - // Instrument: counter - // Unit: {fault} - // Stability: development - ProcessPagingFaultsName = "process.paging.faults" - ProcessPagingFaultsUnit = "{fault}" - ProcessPagingFaultsDescription = "Number of page faults the process has made." - // ProcessThreadCount is the metric conforming to the "process.thread.count" - // semantic conventions. It represents the process threads count. - // Instrument: updowncounter - // Unit: {thread} - // Stability: development - ProcessThreadCountName = "process.thread.count" - ProcessThreadCountUnit = "{thread}" - ProcessThreadCountDescription = "Process threads count." - // ProcessUptime is the metric conforming to the "process.uptime" semantic - // conventions. It represents the time the process has been running. - // Instrument: gauge - // Unit: s - // Stability: development - ProcessUptimeName = "process.uptime" - ProcessUptimeUnit = "s" - ProcessUptimeDescription = "The time the process has been running." - // RPCClientDuration is the metric conforming to the "rpc.client.duration" - // semantic conventions. It represents the measures the duration of outbound - // RPC. - // Instrument: histogram - // Unit: ms - // Stability: development - RPCClientDurationName = "rpc.client.duration" - RPCClientDurationUnit = "ms" - RPCClientDurationDescription = "Measures the duration of outbound RPC." - // RPCClientRequestSize is the metric conforming to the - // "rpc.client.request.size" semantic conventions. It represents the measures - // the size of RPC request messages (uncompressed). - // Instrument: histogram - // Unit: By - // Stability: development - RPCClientRequestSizeName = "rpc.client.request.size" - RPCClientRequestSizeUnit = "By" - RPCClientRequestSizeDescription = "Measures the size of RPC request messages (uncompressed)." - // RPCClientRequestsPerRPC is the metric conforming to the - // "rpc.client.requests_per_rpc" semantic conventions. It represents the - // measures the number of messages received per RPC. - // Instrument: histogram - // Unit: {count} - // Stability: development - RPCClientRequestsPerRPCName = "rpc.client.requests_per_rpc" - RPCClientRequestsPerRPCUnit = "{count}" - RPCClientRequestsPerRPCDescription = "Measures the number of messages received per RPC." - // RPCClientResponseSize is the metric conforming to the - // "rpc.client.response.size" semantic conventions. It represents the measures - // the size of RPC response messages (uncompressed). - // Instrument: histogram - // Unit: By - // Stability: development - RPCClientResponseSizeName = "rpc.client.response.size" - RPCClientResponseSizeUnit = "By" - RPCClientResponseSizeDescription = "Measures the size of RPC response messages (uncompressed)." - // RPCClientResponsesPerRPC is the metric conforming to the - // "rpc.client.responses_per_rpc" semantic conventions. It represents the - // measures the number of messages sent per RPC. - // Instrument: histogram - // Unit: {count} - // Stability: development - RPCClientResponsesPerRPCName = "rpc.client.responses_per_rpc" - RPCClientResponsesPerRPCUnit = "{count}" - RPCClientResponsesPerRPCDescription = "Measures the number of messages sent per RPC." - // RPCServerDuration is the metric conforming to the "rpc.server.duration" - // semantic conventions. It represents the measures the duration of inbound - // RPC. - // Instrument: histogram - // Unit: ms - // Stability: development - RPCServerDurationName = "rpc.server.duration" - RPCServerDurationUnit = "ms" - RPCServerDurationDescription = "Measures the duration of inbound RPC." - // RPCServerRequestSize is the metric conforming to the - // "rpc.server.request.size" semantic conventions. It represents the measures - // the size of RPC request messages (uncompressed). - // Instrument: histogram - // Unit: By - // Stability: development - RPCServerRequestSizeName = "rpc.server.request.size" - RPCServerRequestSizeUnit = "By" - RPCServerRequestSizeDescription = "Measures the size of RPC request messages (uncompressed)." - // RPCServerRequestsPerRPC is the metric conforming to the - // "rpc.server.requests_per_rpc" semantic conventions. It represents the - // measures the number of messages received per RPC. - // Instrument: histogram - // Unit: {count} - // Stability: development - RPCServerRequestsPerRPCName = "rpc.server.requests_per_rpc" - RPCServerRequestsPerRPCUnit = "{count}" - RPCServerRequestsPerRPCDescription = "Measures the number of messages received per RPC." - // RPCServerResponseSize is the metric conforming to the - // "rpc.server.response.size" semantic conventions. It represents the measures - // the size of RPC response messages (uncompressed). - // Instrument: histogram - // Unit: By - // Stability: development - RPCServerResponseSizeName = "rpc.server.response.size" - RPCServerResponseSizeUnit = "By" - RPCServerResponseSizeDescription = "Measures the size of RPC response messages (uncompressed)." - // RPCServerResponsesPerRPC is the metric conforming to the - // "rpc.server.responses_per_rpc" semantic conventions. It represents the - // measures the number of messages sent per RPC. - // Instrument: histogram - // Unit: {count} - // Stability: development - RPCServerResponsesPerRPCName = "rpc.server.responses_per_rpc" - RPCServerResponsesPerRPCUnit = "{count}" - RPCServerResponsesPerRPCDescription = "Measures the number of messages sent per RPC." - // SignalrServerActiveConnections is the metric conforming to the - // "signalr.server.active_connections" semantic conventions. It represents the - // number of connections that are currently active on the server. - // Instrument: updowncounter - // Unit: {connection} - // Stability: stable - SignalrServerActiveConnectionsName = "signalr.server.active_connections" - SignalrServerActiveConnectionsUnit = "{connection}" - SignalrServerActiveConnectionsDescription = "Number of connections that are currently active on the server." - // SignalrServerConnectionDuration is the metric conforming to the - // "signalr.server.connection.duration" semantic conventions. It represents the - // duration of connections on the server. - // Instrument: histogram - // Unit: s - // Stability: stable - SignalrServerConnectionDurationName = "signalr.server.connection.duration" - SignalrServerConnectionDurationUnit = "s" - SignalrServerConnectionDurationDescription = "The duration of connections on the server." - // SystemCPUFrequency is the metric conforming to the "system.cpu.frequency" - // semantic conventions. It represents the reports the current frequency of the - // CPU in Hz. - // Instrument: gauge - // Unit: {Hz} - // Stability: development - SystemCPUFrequencyName = "system.cpu.frequency" - SystemCPUFrequencyUnit = "{Hz}" - SystemCPUFrequencyDescription = "Reports the current frequency of the CPU in Hz" - // SystemCPULogicalCount is the metric conforming to the - // "system.cpu.logical.count" semantic conventions. It represents the reports - // the number of logical (virtual) processor cores created by the operating - // system to manage multitasking. - // Instrument: updowncounter - // Unit: {cpu} - // Stability: development - SystemCPULogicalCountName = "system.cpu.logical.count" - SystemCPULogicalCountUnit = "{cpu}" - SystemCPULogicalCountDescription = "Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking" - // SystemCPUPhysicalCount is the metric conforming to the - // "system.cpu.physical.count" semantic conventions. It represents the reports - // the number of actual physical processor cores on the hardware. - // Instrument: updowncounter - // Unit: {cpu} - // Stability: development - SystemCPUPhysicalCountName = "system.cpu.physical.count" - SystemCPUPhysicalCountUnit = "{cpu}" - SystemCPUPhysicalCountDescription = "Reports the number of actual physical processor cores on the hardware" - // SystemCPUTime is the metric conforming to the "system.cpu.time" semantic - // conventions. It represents the seconds each logical CPU spent on each mode. - // Instrument: counter - // Unit: s - // Stability: development - SystemCPUTimeName = "system.cpu.time" - SystemCPUTimeUnit = "s" - SystemCPUTimeDescription = "Seconds each logical CPU spent on each mode" - // SystemCPUUtilization is the metric conforming to the - // "system.cpu.utilization" semantic conventions. It represents the difference - // in system.cpu.time since the last measurement, divided by the elapsed time - // and number of logical CPUs. - // Instrument: gauge - // Unit: 1 - // Stability: development - SystemCPUUtilizationName = "system.cpu.utilization" - SystemCPUUtilizationUnit = "1" - SystemCPUUtilizationDescription = "Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs" - // SystemDiskIo is the metric conforming to the "system.disk.io" semantic - // conventions. - // Instrument: counter - // Unit: By - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemDiskIoName = "system.disk.io" - SystemDiskIoUnit = "By" - // SystemDiskIoTime is the metric conforming to the "system.disk.io_time" - // semantic conventions. It represents the time disk spent activated. - // Instrument: counter - // Unit: s - // Stability: development - SystemDiskIoTimeName = "system.disk.io_time" - SystemDiskIoTimeUnit = "s" - SystemDiskIoTimeDescription = "Time disk spent activated" - // SystemDiskLimit is the metric conforming to the "system.disk.limit" semantic - // conventions. It represents the total storage capacity of the disk. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemDiskLimitName = "system.disk.limit" - SystemDiskLimitUnit = "By" - SystemDiskLimitDescription = "The total storage capacity of the disk" - // SystemDiskMerged is the metric conforming to the "system.disk.merged" - // semantic conventions. - // Instrument: counter - // Unit: {operation} - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemDiskMergedName = "system.disk.merged" - SystemDiskMergedUnit = "{operation}" - // SystemDiskOperationTime is the metric conforming to the - // "system.disk.operation_time" semantic conventions. It represents the sum of - // the time each operation took to complete. - // Instrument: counter - // Unit: s - // Stability: development - SystemDiskOperationTimeName = "system.disk.operation_time" - SystemDiskOperationTimeUnit = "s" - SystemDiskOperationTimeDescription = "Sum of the time each operation took to complete" - // SystemDiskOperations is the metric conforming to the - // "system.disk.operations" semantic conventions. - // Instrument: counter - // Unit: {operation} - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemDiskOperationsName = "system.disk.operations" - SystemDiskOperationsUnit = "{operation}" - // SystemFilesystemLimit is the metric conforming to the - // "system.filesystem.limit" semantic conventions. It represents the total - // storage capacity of the filesystem. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemFilesystemLimitName = "system.filesystem.limit" - SystemFilesystemLimitUnit = "By" - SystemFilesystemLimitDescription = "The total storage capacity of the filesystem" - // SystemFilesystemUsage is the metric conforming to the - // "system.filesystem.usage" semantic conventions. It represents the reports a - // filesystem's space usage across different states. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemFilesystemUsageName = "system.filesystem.usage" - SystemFilesystemUsageUnit = "By" - SystemFilesystemUsageDescription = "Reports a filesystem's space usage across different states." - // SystemFilesystemUtilization is the metric conforming to the - // "system.filesystem.utilization" semantic conventions. - // Instrument: gauge - // Unit: 1 - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemFilesystemUtilizationName = "system.filesystem.utilization" - SystemFilesystemUtilizationUnit = "1" - // SystemLinuxMemoryAvailable is the metric conforming to the - // "system.linux.memory.available" semantic conventions. It represents an - // estimate of how much memory is available for starting new applications, - // without causing swapping. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemLinuxMemoryAvailableName = "system.linux.memory.available" - SystemLinuxMemoryAvailableUnit = "By" - SystemLinuxMemoryAvailableDescription = "An estimate of how much memory is available for starting new applications, without causing swapping" - // SystemLinuxMemorySlabUsage is the metric conforming to the - // "system.linux.memory.slab.usage" semantic conventions. It represents the - // reports the memory used by the Linux kernel for managing caches of - // frequently used objects. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemLinuxMemorySlabUsageName = "system.linux.memory.slab.usage" - SystemLinuxMemorySlabUsageUnit = "By" - SystemLinuxMemorySlabUsageDescription = "Reports the memory used by the Linux kernel for managing caches of frequently used objects." - // SystemMemoryLimit is the metric conforming to the "system.memory.limit" - // semantic conventions. It represents the total memory available in the - // system. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemMemoryLimitName = "system.memory.limit" - SystemMemoryLimitUnit = "By" - SystemMemoryLimitDescription = "Total memory available in the system." - // SystemMemoryShared is the metric conforming to the "system.memory.shared" - // semantic conventions. It represents the shared memory used (mostly by - // tmpfs). - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemMemorySharedName = "system.memory.shared" - SystemMemorySharedUnit = "By" - SystemMemorySharedDescription = "Shared memory used (mostly by tmpfs)." - // SystemMemoryUsage is the metric conforming to the "system.memory.usage" - // semantic conventions. It represents the reports memory in use by state. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemMemoryUsageName = "system.memory.usage" - SystemMemoryUsageUnit = "By" - SystemMemoryUsageDescription = "Reports memory in use by state." - // SystemMemoryUtilization is the metric conforming to the - // "system.memory.utilization" semantic conventions. - // Instrument: gauge - // Unit: 1 - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemMemoryUtilizationName = "system.memory.utilization" - SystemMemoryUtilizationUnit = "1" - // SystemNetworkConnections is the metric conforming to the - // "system.network.connections" semantic conventions. - // Instrument: updowncounter - // Unit: {connection} - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemNetworkConnectionsName = "system.network.connections" - SystemNetworkConnectionsUnit = "{connection}" - // SystemNetworkDropped is the metric conforming to the - // "system.network.dropped" semantic conventions. It represents the count of - // packets that are dropped or discarded even though there was no error. - // Instrument: counter - // Unit: {packet} - // Stability: development - SystemNetworkDroppedName = "system.network.dropped" - SystemNetworkDroppedUnit = "{packet}" - SystemNetworkDroppedDescription = "Count of packets that are dropped or discarded even though there was no error" - // SystemNetworkErrors is the metric conforming to the "system.network.errors" - // semantic conventions. It represents the count of network errors detected. - // Instrument: counter - // Unit: {error} - // Stability: development - SystemNetworkErrorsName = "system.network.errors" - SystemNetworkErrorsUnit = "{error}" - SystemNetworkErrorsDescription = "Count of network errors detected" - // SystemNetworkIo is the metric conforming to the "system.network.io" semantic - // conventions. - // Instrument: counter - // Unit: By - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemNetworkIoName = "system.network.io" - SystemNetworkIoUnit = "By" - // SystemNetworkPackets is the metric conforming to the - // "system.network.packets" semantic conventions. - // Instrument: counter - // Unit: {packet} - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemNetworkPacketsName = "system.network.packets" - SystemNetworkPacketsUnit = "{packet}" - // SystemPagingFaults is the metric conforming to the "system.paging.faults" - // semantic conventions. - // Instrument: counter - // Unit: {fault} - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemPagingFaultsName = "system.paging.faults" - SystemPagingFaultsUnit = "{fault}" - // SystemPagingOperations is the metric conforming to the - // "system.paging.operations" semantic conventions. - // Instrument: counter - // Unit: {operation} - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemPagingOperationsName = "system.paging.operations" - SystemPagingOperationsUnit = "{operation}" - // SystemPagingUsage is the metric conforming to the "system.paging.usage" - // semantic conventions. It represents the unix swap or windows pagefile usage. - // Instrument: updowncounter - // Unit: By - // Stability: development - SystemPagingUsageName = "system.paging.usage" - SystemPagingUsageUnit = "By" - SystemPagingUsageDescription = "Unix swap or windows pagefile usage" - // SystemPagingUtilization is the metric conforming to the - // "system.paging.utilization" semantic conventions. - // Instrument: gauge - // Unit: 1 - // Stability: development - // NOTE: The description (brief) for this metric is not defined in the semantic-conventions repository. - SystemPagingUtilizationName = "system.paging.utilization" - SystemPagingUtilizationUnit = "1" - // SystemProcessCount is the metric conforming to the "system.process.count" - // semantic conventions. It represents the total number of processes in each - // state. - // Instrument: updowncounter - // Unit: {process} - // Stability: development - SystemProcessCountName = "system.process.count" - SystemProcessCountUnit = "{process}" - SystemProcessCountDescription = "Total number of processes in each state" - // SystemProcessCreated is the metric conforming to the - // "system.process.created" semantic conventions. It represents the total - // number of processes created over uptime of the host. - // Instrument: counter - // Unit: {process} - // Stability: development - SystemProcessCreatedName = "system.process.created" - SystemProcessCreatedUnit = "{process}" - SystemProcessCreatedDescription = "Total number of processes created over uptime of the host" - // SystemUptime is the metric conforming to the "system.uptime" semantic - // conventions. It represents the time the system has been running. - // Instrument: gauge - // Unit: s - // Stability: development - SystemUptimeName = "system.uptime" - SystemUptimeUnit = "s" - SystemUptimeDescription = "The time the system has been running" - // VCSChangeCount is the metric conforming to the "vcs.change.count" semantic - // conventions. It represents the number of changes (pull requests/merge - // requests/changelists) in a repository, categorized by their state (e.g. open - // or merged). - // Instrument: updowncounter - // Unit: {change} - // Stability: development - VCSChangeCountName = "vcs.change.count" - VCSChangeCountUnit = "{change}" - VCSChangeCountDescription = "The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged)" - // VCSChangeDuration is the metric conforming to the "vcs.change.duration" - // semantic conventions. It represents the time duration a change (pull - // request/merge request/changelist) has been in a given state. - // Instrument: gauge - // Unit: s - // Stability: development - VCSChangeDurationName = "vcs.change.duration" - VCSChangeDurationUnit = "s" - VCSChangeDurationDescription = "The time duration a change (pull request/merge request/changelist) has been in a given state." - // VCSChangeTimeToApproval is the metric conforming to the - // "vcs.change.time_to_approval" semantic conventions. It represents the amount - // of time since its creation it took a change (pull request/merge - // request/changelist) to get the first approval. - // Instrument: gauge - // Unit: s - // Stability: development - VCSChangeTimeToApprovalName = "vcs.change.time_to_approval" - VCSChangeTimeToApprovalUnit = "s" - VCSChangeTimeToApprovalDescription = "The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval." - // VCSChangeTimeToMerge is the metric conforming to the - // "vcs.change.time_to_merge" semantic conventions. It represents the amount of - // time since its creation it took a change (pull request/merge - // request/changelist) to get merged into the target(base) ref. - // Instrument: gauge - // Unit: s - // Stability: development - VCSChangeTimeToMergeName = "vcs.change.time_to_merge" - VCSChangeTimeToMergeUnit = "s" - VCSChangeTimeToMergeDescription = "The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref." - // VCSContributorCount is the metric conforming to the "vcs.contributor.count" - // semantic conventions. It represents the number of unique contributors to a - // repository. - // Instrument: gauge - // Unit: {contributor} - // Stability: development - VCSContributorCountName = "vcs.contributor.count" - VCSContributorCountUnit = "{contributor}" - VCSContributorCountDescription = "The number of unique contributors to a repository" - // VCSRefCount is the metric conforming to the "vcs.ref.count" semantic - // conventions. It represents the number of refs of type branch or tag in a - // repository. - // Instrument: updowncounter - // Unit: {ref} - // Stability: development - VCSRefCountName = "vcs.ref.count" - VCSRefCountUnit = "{ref}" - VCSRefCountDescription = "The number of refs of type branch or tag in a repository." - // VCSRefLinesDelta is the metric conforming to the "vcs.ref.lines_delta" - // semantic conventions. It represents the number of lines added/removed in a - // ref (branch) relative to the ref from the `vcs.ref.base.name` attribute. - // Instrument: gauge - // Unit: {line} - // Stability: development - VCSRefLinesDeltaName = "vcs.ref.lines_delta" - VCSRefLinesDeltaUnit = "{line}" - VCSRefLinesDeltaDescription = "The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute." - // VCSRefRevisionsDelta is the metric conforming to the - // "vcs.ref.revisions_delta" semantic conventions. It represents the number of - // revisions (commits) a ref (branch) is ahead/behind the branch from the - // `vcs.ref.base.name` attribute. - // Instrument: gauge - // Unit: {revision} - // Stability: development - VCSRefRevisionsDeltaName = "vcs.ref.revisions_delta" - VCSRefRevisionsDeltaUnit = "{revision}" - VCSRefRevisionsDeltaDescription = "The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute" - // VCSRefTime is the metric conforming to the "vcs.ref.time" semantic - // conventions. It represents the time a ref (branch) created from the default - // branch (trunk) has existed. The `ref.type` attribute will always be `branch` - // . - // Instrument: gauge - // Unit: s - // Stability: development - VCSRefTimeName = "vcs.ref.time" - VCSRefTimeUnit = "s" - VCSRefTimeDescription = "Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch`" - // VCSRepositoryCount is the metric conforming to the "vcs.repository.count" - // semantic conventions. It represents the number of repositories in an - // organization. - // Instrument: updowncounter - // Unit: {repository} - // Stability: development - VCSRepositoryCountName = "vcs.repository.count" - VCSRepositoryCountUnit = "{repository}" - VCSRepositoryCountDescription = "The number of repositories in an organization." -) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/schema.go deleted file mode 100644 index 70948a20034..00000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.30.0/schema.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package semconv - -// SchemaURL is the schema URL that matches the version of the semantic conventions -// that this package defines. Semconv packages starting from v1.4.0 must declare -// non-empty schema URL in the form https://opentelemetry.io/schemas/ -const SchemaURL = "https://opentelemetry.io/schemas/1.30.0" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go new file mode 100644 index 00000000000..089b0c457fc --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv/metric.go @@ -0,0 +1,1010 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package rpcconv provides types and functionality for OpenTelemetry semantic +// conventions in the "rpc" namespace. +package rpcconv + +import ( + "context" + "sync" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" +) + +var ( + addOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }} + recOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }} +) + +// ClientDuration is an instrument used to record metric values conforming to the +// "rpc.client.duration" semantic conventions. It represents the measures the +// duration of outbound RPC. +type ClientDuration struct { + metric.Float64Histogram +} + +var newClientDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Measures the duration of outbound RPC."), + metric.WithUnit("ms"), +} + +// NewClientDuration returns a new ClientDuration instrument. +func NewClientDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ClientDuration, error) { + // Check if the meter is nil. + if m == nil { + return ClientDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientDurationOpts + } else { + opt = append(opt, newClientDurationOpts...) + } + + i, err := m.Float64Histogram( + "rpc.client.duration", + opt..., + ) + if err != nil { + return ClientDuration{noop.Float64Histogram{}}, err + } + return ClientDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientDuration) Name() string { + return "rpc.client.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientDuration) Unit() string { + return "ms" +} + +// Description returns the semantic convention description of the instrument +func (ClientDuration) Description() string { + return "Measures the duration of outbound RPC." +} + +// Record records val to the current distribution for attrs. +// +// While streaming RPCs may record this metric as start-of-batch +// to end-of-batch, it's hard to interpret in practice. +// +// **Streaming**: N/A. +func (m ClientDuration) Record(ctx context.Context, val float64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// While streaming RPCs may record this metric as start-of-batch +// to end-of-batch, it's hard to interpret in practice. +// +// **Streaming**: N/A. +func (m ClientDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// ClientRequestSize is an instrument used to record metric values conforming to +// the "rpc.client.request.size" semantic conventions. It represents the measures +// the size of RPC request messages (uncompressed). +type ClientRequestSize struct { + metric.Int64Histogram +} + +var newClientRequestSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC request messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewClientRequestSize returns a new ClientRequestSize instrument. +func NewClientRequestSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientRequestSize, error) { + // Check if the meter is nil. + if m == nil { + return ClientRequestSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientRequestSizeOpts + } else { + opt = append(opt, newClientRequestSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.client.request.size", + opt..., + ) + if err != nil { + return ClientRequestSize{noop.Int64Histogram{}}, err + } + return ClientRequestSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientRequestSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientRequestSize) Name() string { + return "rpc.client.request.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientRequestSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ClientRequestSize) Description() string { + return "Measures the size of RPC request messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ClientRequestSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ClientRequestSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ClientRequestsPerRPC is an instrument used to record metric values conforming +// to the "rpc.client.requests_per_rpc" semantic conventions. It represents the +// measures the number of messages received per RPC. +type ClientRequestsPerRPC struct { + metric.Int64Histogram +} + +var newClientRequestsPerRPCOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the number of messages received per RPC."), + metric.WithUnit("{count}"), +} + +// NewClientRequestsPerRPC returns a new ClientRequestsPerRPC instrument. +func NewClientRequestsPerRPC( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientRequestsPerRPC, error) { + // Check if the meter is nil. + if m == nil { + return ClientRequestsPerRPC{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientRequestsPerRPCOpts + } else { + opt = append(opt, newClientRequestsPerRPCOpts...) + } + + i, err := m.Int64Histogram( + "rpc.client.requests_per_rpc", + opt..., + ) + if err != nil { + return ClientRequestsPerRPC{noop.Int64Histogram{}}, err + } + return ClientRequestsPerRPC{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientRequestsPerRPC) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientRequestsPerRPC) Name() string { + return "rpc.client.requests_per_rpc" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientRequestsPerRPC) Unit() string { + return "{count}" +} + +// Description returns the semantic convention description of the instrument +func (ClientRequestsPerRPC) Description() string { + return "Measures the number of messages received per RPC." +} + +// Record records val to the current distribution for attrs. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming**: This metric is required for server and client streaming RPCs +func (m ClientRequestsPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming**: This metric is required for server and client streaming RPCs +func (m ClientRequestsPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ClientResponseSize is an instrument used to record metric values conforming to +// the "rpc.client.response.size" semantic conventions. It represents the +// measures the size of RPC response messages (uncompressed). +type ClientResponseSize struct { + metric.Int64Histogram +} + +var newClientResponseSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC response messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewClientResponseSize returns a new ClientResponseSize instrument. +func NewClientResponseSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientResponseSize, error) { + // Check if the meter is nil. + if m == nil { + return ClientResponseSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientResponseSizeOpts + } else { + opt = append(opt, newClientResponseSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.client.response.size", + opt..., + ) + if err != nil { + return ClientResponseSize{noop.Int64Histogram{}}, err + } + return ClientResponseSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientResponseSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientResponseSize) Name() string { + return "rpc.client.response.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientResponseSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ClientResponseSize) Description() string { + return "Measures the size of RPC response messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ClientResponseSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ClientResponseSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ClientResponsesPerRPC is an instrument used to record metric values conforming +// to the "rpc.client.responses_per_rpc" semantic conventions. It represents the +// measures the number of messages sent per RPC. +type ClientResponsesPerRPC struct { + metric.Int64Histogram +} + +var newClientResponsesPerRPCOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the number of messages sent per RPC."), + metric.WithUnit("{count}"), +} + +// NewClientResponsesPerRPC returns a new ClientResponsesPerRPC instrument. +func NewClientResponsesPerRPC( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientResponsesPerRPC, error) { + // Check if the meter is nil. + if m == nil { + return ClientResponsesPerRPC{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientResponsesPerRPCOpts + } else { + opt = append(opt, newClientResponsesPerRPCOpts...) + } + + i, err := m.Int64Histogram( + "rpc.client.responses_per_rpc", + opt..., + ) + if err != nil { + return ClientResponsesPerRPC{noop.Int64Histogram{}}, err + } + return ClientResponsesPerRPC{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientResponsesPerRPC) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientResponsesPerRPC) Name() string { + return "rpc.client.responses_per_rpc" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientResponsesPerRPC) Unit() string { + return "{count}" +} + +// Description returns the semantic convention description of the instrument +func (ClientResponsesPerRPC) Description() string { + return "Measures the number of messages sent per RPC." +} + +// Record records val to the current distribution for attrs. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming**: This metric is required for server and client streaming RPCs +func (m ClientResponsesPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming**: This metric is required for server and client streaming RPCs +func (m ClientResponsesPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ServerDuration is an instrument used to record metric values conforming to the +// "rpc.server.duration" semantic conventions. It represents the measures the +// duration of inbound RPC. +type ServerDuration struct { + metric.Float64Histogram +} + +var newServerDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Measures the duration of inbound RPC."), + metric.WithUnit("ms"), +} + +// NewServerDuration returns a new ServerDuration instrument. +func NewServerDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ServerDuration, error) { + // Check if the meter is nil. + if m == nil { + return ServerDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerDurationOpts + } else { + opt = append(opt, newServerDurationOpts...) + } + + i, err := m.Float64Histogram( + "rpc.server.duration", + opt..., + ) + if err != nil { + return ServerDuration{noop.Float64Histogram{}}, err + } + return ServerDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerDuration) Name() string { + return "rpc.server.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerDuration) Unit() string { + return "ms" +} + +// Description returns the semantic convention description of the instrument +func (ServerDuration) Description() string { + return "Measures the duration of inbound RPC." +} + +// Record records val to the current distribution for attrs. +// +// While streaming RPCs may record this metric as start-of-batch +// to end-of-batch, it's hard to interpret in practice. +// +// **Streaming**: N/A. +func (m ServerDuration) Record(ctx context.Context, val float64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// While streaming RPCs may record this metric as start-of-batch +// to end-of-batch, it's hard to interpret in practice. +// +// **Streaming**: N/A. +func (m ServerDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// ServerRequestSize is an instrument used to record metric values conforming to +// the "rpc.server.request.size" semantic conventions. It represents the measures +// the size of RPC request messages (uncompressed). +type ServerRequestSize struct { + metric.Int64Histogram +} + +var newServerRequestSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC request messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewServerRequestSize returns a new ServerRequestSize instrument. +func NewServerRequestSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerRequestSize, error) { + // Check if the meter is nil. + if m == nil { + return ServerRequestSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerRequestSizeOpts + } else { + opt = append(opt, newServerRequestSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.server.request.size", + opt..., + ) + if err != nil { + return ServerRequestSize{noop.Int64Histogram{}}, err + } + return ServerRequestSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerRequestSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerRequestSize) Name() string { + return "rpc.server.request.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerRequestSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ServerRequestSize) Description() string { + return "Measures the size of RPC request messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ServerRequestSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per message in a streaming batch +func (m ServerRequestSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ServerRequestsPerRPC is an instrument used to record metric values conforming +// to the "rpc.server.requests_per_rpc" semantic conventions. It represents the +// measures the number of messages received per RPC. +type ServerRequestsPerRPC struct { + metric.Int64Histogram +} + +var newServerRequestsPerRPCOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the number of messages received per RPC."), + metric.WithUnit("{count}"), +} + +// NewServerRequestsPerRPC returns a new ServerRequestsPerRPC instrument. +func NewServerRequestsPerRPC( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerRequestsPerRPC, error) { + // Check if the meter is nil. + if m == nil { + return ServerRequestsPerRPC{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerRequestsPerRPCOpts + } else { + opt = append(opt, newServerRequestsPerRPCOpts...) + } + + i, err := m.Int64Histogram( + "rpc.server.requests_per_rpc", + opt..., + ) + if err != nil { + return ServerRequestsPerRPC{noop.Int64Histogram{}}, err + } + return ServerRequestsPerRPC{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerRequestsPerRPC) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerRequestsPerRPC) Name() string { + return "rpc.server.requests_per_rpc" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerRequestsPerRPC) Unit() string { + return "{count}" +} + +// Description returns the semantic convention description of the instrument +func (ServerRequestsPerRPC) Description() string { + return "Measures the number of messages received per RPC." +} + +// Record records val to the current distribution for attrs. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming** : This metric is required for server and client streaming RPCs +func (m ServerRequestsPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming** : This metric is required for server and client streaming RPCs +func (m ServerRequestsPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ServerResponseSize is an instrument used to record metric values conforming to +// the "rpc.server.response.size" semantic conventions. It represents the +// measures the size of RPC response messages (uncompressed). +type ServerResponseSize struct { + metric.Int64Histogram +} + +var newServerResponseSizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the size of RPC response messages (uncompressed)."), + metric.WithUnit("By"), +} + +// NewServerResponseSize returns a new ServerResponseSize instrument. +func NewServerResponseSize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerResponseSize, error) { + // Check if the meter is nil. + if m == nil { + return ServerResponseSize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerResponseSizeOpts + } else { + opt = append(opt, newServerResponseSizeOpts...) + } + + i, err := m.Int64Histogram( + "rpc.server.response.size", + opt..., + ) + if err != nil { + return ServerResponseSize{noop.Int64Histogram{}}, err + } + return ServerResponseSize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerResponseSize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerResponseSize) Name() string { + return "rpc.server.response.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerResponseSize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ServerResponseSize) Description() string { + return "Measures the size of RPC response messages (uncompressed)." +} + +// Record records val to the current distribution for attrs. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ServerResponseSize) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// **Streaming**: Recorded per response in a streaming batch +func (m ServerResponseSize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// ServerResponsesPerRPC is an instrument used to record metric values conforming +// to the "rpc.server.responses_per_rpc" semantic conventions. It represents the +// measures the number of messages sent per RPC. +type ServerResponsesPerRPC struct { + metric.Int64Histogram +} + +var newServerResponsesPerRPCOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Measures the number of messages sent per RPC."), + metric.WithUnit("{count}"), +} + +// NewServerResponsesPerRPC returns a new ServerResponsesPerRPC instrument. +func NewServerResponsesPerRPC( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerResponsesPerRPC, error) { + // Check if the meter is nil. + if m == nil { + return ServerResponsesPerRPC{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerResponsesPerRPCOpts + } else { + opt = append(opt, newServerResponsesPerRPCOpts...) + } + + i, err := m.Int64Histogram( + "rpc.server.responses_per_rpc", + opt..., + ) + if err != nil { + return ServerResponsesPerRPC{noop.Int64Histogram{}}, err + } + return ServerResponsesPerRPC{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerResponsesPerRPC) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerResponsesPerRPC) Name() string { + return "rpc.server.responses_per_rpc" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerResponsesPerRPC) Unit() string { + return "{count}" +} + +// Description returns the semantic convention description of the instrument +func (ServerResponsesPerRPC) Description() string { + return "Measures the number of messages sent per RPC." +} + +// Record records val to the current distribution for attrs. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming**: This metric is required for server and client streaming RPCs +func (m ServerResponsesPerRPC) Record(ctx context.Context, val int64, attrs ...attribute.KeyValue) { + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributes(attrs...)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// Should be 1 for all non-streaming RPCs. +// +// **Streaming**: This metric is required for server and client streaming RPCs +func (m ServerResponsesPerRPC) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := recOptPool.Get().(*[]metric.RecordOption) + defer func() { + *o = (*o)[:0] + recOptPool.Put(o) + }() + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/httpconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/httpconv/metric.go new file mode 100644 index 00000000000..1eb8c9e2a9d --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/httpconv/metric.go @@ -0,0 +1,2051 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package httpconv provides types and functionality for OpenTelemetry semantic +// conventions in the "http" namespace. +package httpconv + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" + "go.opentelemetry.io/otel/semconv/internal/metricpool" +) + +// ErrorTypeAttr is an attribute conforming to the error.type semantic +// conventions. It represents the describes a class of error the operation ended +// with. +type ErrorTypeAttr string + +var ( + // ErrorTypeOther is a fallback error value to be used when the instrumentation + // doesn't define a custom value. + ErrorTypeOther ErrorTypeAttr = "_OTHER" +) + +// ConnectionStateAttr is an attribute conforming to the http.connection.state +// semantic conventions. It represents the state of the HTTP connection in the +// HTTP connection pool. +type ConnectionStateAttr string + +var ( + // ConnectionStateActive is the active state. + ConnectionStateActive ConnectionStateAttr = "active" + // ConnectionStateIdle is the idle state. + ConnectionStateIdle ConnectionStateAttr = "idle" +) + +// RequestMethodAttr is an attribute conforming to the http.request.method +// semantic conventions. It represents the HTTP request method. +type RequestMethodAttr string + +var ( + // RequestMethodConnect is the CONNECT method. + RequestMethodConnect RequestMethodAttr = "CONNECT" + // RequestMethodDelete is the DELETE method. + RequestMethodDelete RequestMethodAttr = "DELETE" + // RequestMethodGet is the GET method. + RequestMethodGet RequestMethodAttr = "GET" + // RequestMethodHead is the HEAD method. + RequestMethodHead RequestMethodAttr = "HEAD" + // RequestMethodOptions is the OPTIONS method. + RequestMethodOptions RequestMethodAttr = "OPTIONS" + // RequestMethodPatch is the PATCH method. + RequestMethodPatch RequestMethodAttr = "PATCH" + // RequestMethodPost is the POST method. + RequestMethodPost RequestMethodAttr = "POST" + // RequestMethodPut is the PUT method. + RequestMethodPut RequestMethodAttr = "PUT" + // RequestMethodTrace is the TRACE method. + RequestMethodTrace RequestMethodAttr = "TRACE" + // RequestMethodQuery is the QUERY method. + RequestMethodQuery RequestMethodAttr = "QUERY" + // RequestMethodOther is the any HTTP method that the instrumentation has no + // prior knowledge of. + RequestMethodOther RequestMethodAttr = "_OTHER" +) + +// UserAgentSyntheticTypeAttr is an attribute conforming to the +// user_agent.synthetic.type semantic conventions. It represents the specifies +// the category of synthetic traffic, such as tests or bots. +type UserAgentSyntheticTypeAttr string + +var ( + // UserAgentSyntheticTypeBot is the bot source. + UserAgentSyntheticTypeBot UserAgentSyntheticTypeAttr = "bot" + // UserAgentSyntheticTypeTest is the synthetic test source. + UserAgentSyntheticTypeTest UserAgentSyntheticTypeAttr = "test" +) + +// ClientActiveRequests is an instrument used to record metric values conforming +// to the "http.client.active_requests" semantic conventions. It represents the +// number of active HTTP requests. +type ClientActiveRequests struct { + metric.Int64UpDownCounter +} + +var newClientActiveRequestsOpts = []metric.Int64UpDownCounterOption{ + metric.WithDescription("Number of active HTTP requests."), + metric.WithUnit("{request}"), +} + +// NewClientActiveRequests returns a new ClientActiveRequests instrument. +func NewClientActiveRequests( + m metric.Meter, + opt ...metric.Int64UpDownCounterOption, +) (ClientActiveRequests, error) { + // Check if the meter is nil. + if m == nil { + return ClientActiveRequests{noop.Int64UpDownCounter{}}, nil + } + + if len(opt) == 0 { + opt = newClientActiveRequestsOpts + } else { + opt = append(opt, newClientActiveRequestsOpts...) + } + + i, err := m.Int64UpDownCounter( + "http.client.active_requests", + opt..., + ) + if err != nil { + return ClientActiveRequests{noop.Int64UpDownCounter{}}, err + } + return ClientActiveRequests{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientActiveRequests) Inst() metric.Int64UpDownCounter { + return m.Int64UpDownCounter +} + +// Name returns the semantic convention name of the instrument. +func (ClientActiveRequests) Name() string { + return "http.client.active_requests" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientActiveRequests) Unit() string { + return "{request}" +} + +// Description returns the semantic convention description of the instrument +func (ClientActiveRequests) Description() string { + return "Number of active HTTP requests." +} + +// Add adds incr to the existing count for attrs. +// +// The serverAddress is the server domain name if available without reverse DNS +// lookup; otherwise, IP address or Unix domain socket name. +// +// The serverPort is the server port number. +// +// All additional attrs passed are included in the recorded value. +func (m ClientActiveRequests) Add( + ctx context.Context, + incr int64, + serverAddress string, + serverPort int, + attrs ...attribute.KeyValue, +) { + if !m.Int64UpDownCounter.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64UpDownCounter.Add(ctx, incr, metric.WithAttributes( + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )) + return + } + + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )..., + ), + ) + + m.Int64UpDownCounter.Add(ctx, incr, *o...) +} + +// AddSet adds incr to the existing count for set. +func (m ClientActiveRequests) AddSet(ctx context.Context, incr int64, set attribute.Set) { + if !m.Int64UpDownCounter.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64UpDownCounter.Add(ctx, incr) + return + } + + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64UpDownCounter.Add(ctx, incr, *o...) +} + +// AttrURLTemplate returns an optional attribute for the "url.template" semantic +// convention. It represents the low-cardinality template of an +// [absolute path reference]. +// +// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 +func (ClientActiveRequests) AttrURLTemplate(val string) attribute.KeyValue { + return attribute.String("url.template", val) +} + +// AttrRequestMethod returns an optional attribute for the "http.request.method" +// semantic convention. It represents the HTTP request method. +func (ClientActiveRequests) AttrRequestMethod(val RequestMethodAttr) attribute.KeyValue { + return attribute.String("http.request.method", string(val)) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientActiveRequests) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ClientActiveRequestsObservable is an instrument used to record metric values +// conforming to the "http.client.active_requests" semantic conventions. It +// represents the number of active HTTP requests. +type ClientActiveRequestsObservable struct { + metric.Int64ObservableUpDownCounter +} + +var newClientActiveRequestsObservableOpts = []metric.Int64ObservableUpDownCounterOption{ + metric.WithDescription("Number of active HTTP requests."), + metric.WithUnit("{request}"), +} + +// NewClientActiveRequestsObservable returns a new ClientActiveRequestsObservable +// instrument. +func NewClientActiveRequestsObservable( + m metric.Meter, + opt ...metric.Int64ObservableUpDownCounterOption, +) (ClientActiveRequestsObservable, error) { + // Check if the meter is nil. + if m == nil { + return ClientActiveRequestsObservable{noop.Int64ObservableUpDownCounter{}}, nil + } + + if len(opt) == 0 { + opt = newClientActiveRequestsObservableOpts + } else { + opt = append(opt, newClientActiveRequestsObservableOpts...) + } + + i, err := m.Int64ObservableUpDownCounter( + "http.client.active_requests", + opt..., + ) + if err != nil { + return ClientActiveRequestsObservable{noop.Int64ObservableUpDownCounter{}}, err + } + return ClientActiveRequestsObservable{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientActiveRequestsObservable) Inst() metric.Int64ObservableUpDownCounter { + return m.Int64ObservableUpDownCounter +} + +// Name returns the semantic convention name of the instrument. +func (ClientActiveRequestsObservable) Name() string { + return "http.client.active_requests" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientActiveRequestsObservable) Unit() string { + return "{request}" +} + +// Description returns the semantic convention description of the instrument +func (ClientActiveRequestsObservable) Description() string { + return "Number of active HTTP requests." +} + +// AttrServerAddress returns a required attribute for the "server.address" +// semantic convention. It represents the server domain name if available without +// reverse DNS lookup; otherwise, IP address or Unix domain socket name. +func (ClientActiveRequestsObservable) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns a required attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ClientActiveRequestsObservable) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrURLTemplate returns an optional attribute for the "url.template" semantic +// convention. It represents the low-cardinality template of an +// [absolute path reference]. +// +// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 +func (ClientActiveRequestsObservable) AttrURLTemplate(val string) attribute.KeyValue { + return attribute.String("url.template", val) +} + +// AttrRequestMethod returns an optional attribute for the "http.request.method" +// semantic convention. It represents the HTTP request method. +func (ClientActiveRequestsObservable) AttrRequestMethod(val RequestMethodAttr) attribute.KeyValue { + return attribute.String("http.request.method", string(val)) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientActiveRequestsObservable) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ClientConnectionDuration is an instrument used to record metric values +// conforming to the "http.client.connection.duration" semantic conventions. It +// represents the duration of the successfully established outbound HTTP +// connections. +type ClientConnectionDuration struct { + metric.Float64Histogram +} + +var newClientConnectionDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("The duration of the successfully established outbound HTTP connections."), + metric.WithUnit("s"), +} + +// NewClientConnectionDuration returns a new ClientConnectionDuration instrument. +func NewClientConnectionDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ClientConnectionDuration, error) { + // Check if the meter is nil. + if m == nil { + return ClientConnectionDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientConnectionDurationOpts + } else { + opt = append(opt, newClientConnectionDurationOpts...) + } + + i, err := m.Float64Histogram( + "http.client.connection.duration", + opt..., + ) + if err != nil { + return ClientConnectionDuration{noop.Float64Histogram{}}, err + } + return ClientConnectionDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientConnectionDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientConnectionDuration) Name() string { + return "http.client.connection.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientConnectionDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ClientConnectionDuration) Description() string { + return "The duration of the successfully established outbound HTTP connections." +} + +// Record records val to the current distribution for attrs. +// +// The serverAddress is the server domain name if available without reverse DNS +// lookup; otherwise, IP address or Unix domain socket name. +// +// The serverPort is the server port number. +// +// All additional attrs passed are included in the recorded value. +func (m ClientConnectionDuration) Record( + ctx context.Context, + val float64, + serverAddress string, + serverPort int, + attrs ...attribute.KeyValue, +) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +func (m ClientConnectionDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientConnectionDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkPeerAddress returns an optional attribute for the +// "network.peer.address" semantic convention. It represents the peer address of +// the network connection - IP address or Unix domain socket name. +func (ClientConnectionDuration) AttrNetworkPeerAddress(val string) attribute.KeyValue { + return attribute.String("network.peer.address", val) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientConnectionDuration) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ClientOpenConnections is an instrument used to record metric values conforming +// to the "http.client.open_connections" semantic conventions. It represents the +// number of outbound HTTP connections that are currently active or idle on the +// client. +type ClientOpenConnections struct { + metric.Int64UpDownCounter +} + +var newClientOpenConnectionsOpts = []metric.Int64UpDownCounterOption{ + metric.WithDescription("Number of outbound HTTP connections that are currently active or idle on the client."), + metric.WithUnit("{connection}"), +} + +// NewClientOpenConnections returns a new ClientOpenConnections instrument. +func NewClientOpenConnections( + m metric.Meter, + opt ...metric.Int64UpDownCounterOption, +) (ClientOpenConnections, error) { + // Check if the meter is nil. + if m == nil { + return ClientOpenConnections{noop.Int64UpDownCounter{}}, nil + } + + if len(opt) == 0 { + opt = newClientOpenConnectionsOpts + } else { + opt = append(opt, newClientOpenConnectionsOpts...) + } + + i, err := m.Int64UpDownCounter( + "http.client.open_connections", + opt..., + ) + if err != nil { + return ClientOpenConnections{noop.Int64UpDownCounter{}}, err + } + return ClientOpenConnections{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientOpenConnections) Inst() metric.Int64UpDownCounter { + return m.Int64UpDownCounter +} + +// Name returns the semantic convention name of the instrument. +func (ClientOpenConnections) Name() string { + return "http.client.open_connections" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientOpenConnections) Unit() string { + return "{connection}" +} + +// Description returns the semantic convention description of the instrument +func (ClientOpenConnections) Description() string { + return "Number of outbound HTTP connections that are currently active or idle on the client." +} + +// Add adds incr to the existing count for attrs. +// +// The connectionState is the state of the HTTP connection in the HTTP connection +// pool. +// +// The serverAddress is the server domain name if available without reverse DNS +// lookup; otherwise, IP address or Unix domain socket name. +// +// The serverPort is the server port number. +// +// All additional attrs passed are included in the recorded value. +func (m ClientOpenConnections) Add( + ctx context.Context, + incr int64, + connectionState ConnectionStateAttr, + serverAddress string, + serverPort int, + attrs ...attribute.KeyValue, +) { + if !m.Int64UpDownCounter.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64UpDownCounter.Add(ctx, incr, metric.WithAttributes( + attribute.String("http.connection.state", string(connectionState)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )) + return + } + + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.connection.state", string(connectionState)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )..., + ), + ) + + m.Int64UpDownCounter.Add(ctx, incr, *o...) +} + +// AddSet adds incr to the existing count for set. +func (m ClientOpenConnections) AddSet(ctx context.Context, incr int64, set attribute.Set) { + if !m.Int64UpDownCounter.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64UpDownCounter.Add(ctx, incr) + return + } + + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64UpDownCounter.Add(ctx, incr, *o...) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientOpenConnections) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkPeerAddress returns an optional attribute for the +// "network.peer.address" semantic convention. It represents the peer address of +// the network connection - IP address or Unix domain socket name. +func (ClientOpenConnections) AttrNetworkPeerAddress(val string) attribute.KeyValue { + return attribute.String("network.peer.address", val) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientOpenConnections) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ClientOpenConnectionsObservable is an instrument used to record metric values +// conforming to the "http.client.open_connections" semantic conventions. It +// represents the number of outbound HTTP connections that are currently active +// or idle on the client. +type ClientOpenConnectionsObservable struct { + metric.Int64ObservableUpDownCounter +} + +var newClientOpenConnectionsObservableOpts = []metric.Int64ObservableUpDownCounterOption{ + metric.WithDescription("Number of outbound HTTP connections that are currently active or idle on the client."), + metric.WithUnit("{connection}"), +} + +// NewClientOpenConnectionsObservable returns a new +// ClientOpenConnectionsObservable instrument. +func NewClientOpenConnectionsObservable( + m metric.Meter, + opt ...metric.Int64ObservableUpDownCounterOption, +) (ClientOpenConnectionsObservable, error) { + // Check if the meter is nil. + if m == nil { + return ClientOpenConnectionsObservable{noop.Int64ObservableUpDownCounter{}}, nil + } + + if len(opt) == 0 { + opt = newClientOpenConnectionsObservableOpts + } else { + opt = append(opt, newClientOpenConnectionsObservableOpts...) + } + + i, err := m.Int64ObservableUpDownCounter( + "http.client.open_connections", + opt..., + ) + if err != nil { + return ClientOpenConnectionsObservable{noop.Int64ObservableUpDownCounter{}}, err + } + return ClientOpenConnectionsObservable{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientOpenConnectionsObservable) Inst() metric.Int64ObservableUpDownCounter { + return m.Int64ObservableUpDownCounter +} + +// Name returns the semantic convention name of the instrument. +func (ClientOpenConnectionsObservable) Name() string { + return "http.client.open_connections" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientOpenConnectionsObservable) Unit() string { + return "{connection}" +} + +// Description returns the semantic convention description of the instrument +func (ClientOpenConnectionsObservable) Description() string { + return "Number of outbound HTTP connections that are currently active or idle on the client." +} + +// AttrConnectionState returns a required attribute for the +// "http.connection.state" semantic convention. It represents the state of the +// HTTP connection in the HTTP connection pool. +func (ClientOpenConnectionsObservable) AttrConnectionState(val ConnectionStateAttr) attribute.KeyValue { + return attribute.String("http.connection.state", string(val)) +} + +// AttrServerAddress returns a required attribute for the "server.address" +// semantic convention. It represents the server domain name if available without +// reverse DNS lookup; otherwise, IP address or Unix domain socket name. +func (ClientOpenConnectionsObservable) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns a required attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ClientOpenConnectionsObservable) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientOpenConnectionsObservable) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrNetworkPeerAddress returns an optional attribute for the +// "network.peer.address" semantic convention. It represents the peer address of +// the network connection - IP address or Unix domain socket name. +func (ClientOpenConnectionsObservable) AttrNetworkPeerAddress(val string) attribute.KeyValue { + return attribute.String("network.peer.address", val) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientOpenConnectionsObservable) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ClientRequestBodySize is an instrument used to record metric values conforming +// to the "http.client.request.body.size" semantic conventions. It represents the +// size of HTTP client request bodies. +type ClientRequestBodySize struct { + metric.Int64Histogram +} + +var newClientRequestBodySizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Size of HTTP client request bodies."), + metric.WithUnit("By"), +} + +// NewClientRequestBodySize returns a new ClientRequestBodySize instrument. +func NewClientRequestBodySize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientRequestBodySize, error) { + // Check if the meter is nil. + if m == nil { + return ClientRequestBodySize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientRequestBodySizeOpts + } else { + opt = append(opt, newClientRequestBodySizeOpts...) + } + + i, err := m.Int64Histogram( + "http.client.request.body.size", + opt..., + ) + if err != nil { + return ClientRequestBodySize{noop.Int64Histogram{}}, err + } + return ClientRequestBodySize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientRequestBodySize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientRequestBodySize) Name() string { + return "http.client.request.body.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientRequestBodySize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ClientRequestBodySize) Description() string { + return "Size of HTTP client request bodies." +} + +// Record records val to the current distribution for attrs. +// +// The requestMethod is the HTTP request method. +// +// The serverAddress is the server domain name if available without reverse DNS +// lookup; otherwise, IP address or Unix domain socket name. +// +// The serverPort is the server port number. +// +// All additional attrs passed are included in the recorded value. +// +// The size of the request payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ClientRequestBodySize) Record( + ctx context.Context, + val int64, + requestMethod RequestMethodAttr, + serverAddress string, + serverPort int, + attrs ...attribute.KeyValue, +) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// The size of the request payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ClientRequestBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientRequestBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "http.response.status_code" semantic convention. It represents the +// [HTTP response status code]. +// +// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 +func (ClientRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue { + return attribute.Int("http.response.status_code", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ClientRequestBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrURLTemplate returns an optional attribute for the "url.template" semantic +// convention. It represents the low-cardinality template of an +// [absolute path reference]. +// +// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 +func (ClientRequestBodySize) AttrURLTemplate(val string) attribute.KeyValue { + return attribute.String("url.template", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientRequestBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientRequestBodySize) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ClientRequestDuration is an instrument used to record metric values conforming +// to the "http.client.request.duration" semantic conventions. It represents the +// duration of HTTP client requests. +type ClientRequestDuration struct { + metric.Float64Histogram +} + +var newClientRequestDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Duration of HTTP client requests."), + metric.WithUnit("s"), + metric.WithExplicitBucketBoundaries([]float64{0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10}...), +} + +// NewClientRequestDuration returns a new ClientRequestDuration instrument. +func NewClientRequestDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ClientRequestDuration, error) { + // Check if the meter is nil. + if m == nil { + return ClientRequestDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientRequestDurationOpts + } else { + opt = append(opt, newClientRequestDurationOpts...) + } + + i, err := m.Float64Histogram( + "http.client.request.duration", + opt..., + ) + if err != nil { + return ClientRequestDuration{noop.Float64Histogram{}}, err + } + return ClientRequestDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientRequestDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientRequestDuration) Name() string { + return "http.client.request.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientRequestDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ClientRequestDuration) Description() string { + return "Duration of HTTP client requests." +} + +// Record records val to the current distribution for attrs. +// +// The requestMethod is the HTTP request method. +// +// The serverAddress is the server domain name if available without reverse DNS +// lookup; otherwise, IP address or Unix domain socket name. +// +// The serverPort is the server port number. +// +// All additional attrs passed are included in the recorded value. +func (m ClientRequestDuration) Record( + ctx context.Context, + val float64, + requestMethod RequestMethodAttr, + serverAddress string, + serverPort int, + attrs ...attribute.KeyValue, +) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +func (m ClientRequestDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientRequestDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "http.response.status_code" semantic convention. It represents the +// [HTTP response status code]. +// +// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 +func (ClientRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue { + return attribute.Int("http.response.status_code", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ClientRequestDuration) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientRequestDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientRequestDuration) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// AttrURLTemplate returns an optional attribute for the "url.template" semantic +// convention. It represents the low-cardinality template of an +// [absolute path reference]. +// +// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 +func (ClientRequestDuration) AttrURLTemplate(val string) attribute.KeyValue { + return attribute.String("url.template", val) +} + +// ClientResponseBodySize is an instrument used to record metric values +// conforming to the "http.client.response.body.size" semantic conventions. It +// represents the size of HTTP client response bodies. +type ClientResponseBodySize struct { + metric.Int64Histogram +} + +var newClientResponseBodySizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Size of HTTP client response bodies."), + metric.WithUnit("By"), +} + +// NewClientResponseBodySize returns a new ClientResponseBodySize instrument. +func NewClientResponseBodySize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ClientResponseBodySize, error) { + // Check if the meter is nil. + if m == nil { + return ClientResponseBodySize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientResponseBodySizeOpts + } else { + opt = append(opt, newClientResponseBodySizeOpts...) + } + + i, err := m.Int64Histogram( + "http.client.response.body.size", + opt..., + ) + if err != nil { + return ClientResponseBodySize{noop.Int64Histogram{}}, err + } + return ClientResponseBodySize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientResponseBodySize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientResponseBodySize) Name() string { + return "http.client.response.body.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientResponseBodySize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ClientResponseBodySize) Description() string { + return "Size of HTTP client response bodies." +} + +// Record records val to the current distribution for attrs. +// +// The requestMethod is the HTTP request method. +// +// The serverAddress is the server domain name if available without reverse DNS +// lookup; otherwise, IP address or Unix domain socket name. +// +// The serverPort is the server port number. +// +// All additional attrs passed are included in the recorded value. +// +// The size of the response payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ClientResponseBodySize) Record( + ctx context.Context, + val int64, + requestMethod RequestMethodAttr, + serverAddress string, + serverPort int, + attrs ...attribute.KeyValue, +) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("server.address", serverAddress), + attribute.Int("server.port", serverPort), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// The size of the response payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ClientResponseBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientResponseBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "http.response.status_code" semantic convention. It represents the +// [HTTP response status code]. +// +// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 +func (ClientResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue { + return attribute.Int("http.response.status_code", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ClientResponseBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrURLTemplate returns an optional attribute for the "url.template" semantic +// convention. It represents the low-cardinality template of an +// [absolute path reference]. +// +// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2 +func (ClientResponseBodySize) AttrURLTemplate(val string) attribute.KeyValue { + return attribute.String("url.template", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ClientResponseBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrURLScheme returns an optional attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ClientResponseBodySize) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// ServerActiveRequests is an instrument used to record metric values conforming +// to the "http.server.active_requests" semantic conventions. It represents the +// number of active HTTP server requests. +type ServerActiveRequests struct { + metric.Int64UpDownCounter +} + +var newServerActiveRequestsOpts = []metric.Int64UpDownCounterOption{ + metric.WithDescription("Number of active HTTP server requests."), + metric.WithUnit("{request}"), +} + +// NewServerActiveRequests returns a new ServerActiveRequests instrument. +func NewServerActiveRequests( + m metric.Meter, + opt ...metric.Int64UpDownCounterOption, +) (ServerActiveRequests, error) { + // Check if the meter is nil. + if m == nil { + return ServerActiveRequests{noop.Int64UpDownCounter{}}, nil + } + + if len(opt) == 0 { + opt = newServerActiveRequestsOpts + } else { + opt = append(opt, newServerActiveRequestsOpts...) + } + + i, err := m.Int64UpDownCounter( + "http.server.active_requests", + opt..., + ) + if err != nil { + return ServerActiveRequests{noop.Int64UpDownCounter{}}, err + } + return ServerActiveRequests{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerActiveRequests) Inst() metric.Int64UpDownCounter { + return m.Int64UpDownCounter +} + +// Name returns the semantic convention name of the instrument. +func (ServerActiveRequests) Name() string { + return "http.server.active_requests" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerActiveRequests) Unit() string { + return "{request}" +} + +// Description returns the semantic convention description of the instrument +func (ServerActiveRequests) Description() string { + return "Number of active HTTP server requests." +} + +// Add adds incr to the existing count for attrs. +// +// The requestMethod is the HTTP request method. +// +// The urlScheme is the the [URI scheme] component identifying the used protocol. +// +// All additional attrs passed are included in the recorded value. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (m ServerActiveRequests) Add( + ctx context.Context, + incr int64, + requestMethod RequestMethodAttr, + urlScheme string, + attrs ...attribute.KeyValue, +) { + if !m.Int64UpDownCounter.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64UpDownCounter.Add(ctx, incr, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )) + return + } + + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )..., + ), + ) + + m.Int64UpDownCounter.Add(ctx, incr, *o...) +} + +// AddSet adds incr to the existing count for set. +func (m ServerActiveRequests) AddSet(ctx context.Context, incr int64, set attribute.Set) { + if !m.Int64UpDownCounter.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64UpDownCounter.Add(ctx, incr) + return + } + + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64UpDownCounter.Add(ctx, incr, *o...) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the name of the local HTTP server that +// received the request. +func (ServerActiveRequests) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the port of the local HTTP server that received the +// request. +func (ServerActiveRequests) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// ServerActiveRequestsObservable is an instrument used to record metric values +// conforming to the "http.server.active_requests" semantic conventions. It +// represents the number of active HTTP server requests. +type ServerActiveRequestsObservable struct { + metric.Int64ObservableUpDownCounter +} + +var newServerActiveRequestsObservableOpts = []metric.Int64ObservableUpDownCounterOption{ + metric.WithDescription("Number of active HTTP server requests."), + metric.WithUnit("{request}"), +} + +// NewServerActiveRequestsObservable returns a new ServerActiveRequestsObservable +// instrument. +func NewServerActiveRequestsObservable( + m metric.Meter, + opt ...metric.Int64ObservableUpDownCounterOption, +) (ServerActiveRequestsObservable, error) { + // Check if the meter is nil. + if m == nil { + return ServerActiveRequestsObservable{noop.Int64ObservableUpDownCounter{}}, nil + } + + if len(opt) == 0 { + opt = newServerActiveRequestsObservableOpts + } else { + opt = append(opt, newServerActiveRequestsObservableOpts...) + } + + i, err := m.Int64ObservableUpDownCounter( + "http.server.active_requests", + opt..., + ) + if err != nil { + return ServerActiveRequestsObservable{noop.Int64ObservableUpDownCounter{}}, err + } + return ServerActiveRequestsObservable{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerActiveRequestsObservable) Inst() metric.Int64ObservableUpDownCounter { + return m.Int64ObservableUpDownCounter +} + +// Name returns the semantic convention name of the instrument. +func (ServerActiveRequestsObservable) Name() string { + return "http.server.active_requests" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerActiveRequestsObservable) Unit() string { + return "{request}" +} + +// Description returns the semantic convention description of the instrument +func (ServerActiveRequestsObservable) Description() string { + return "Number of active HTTP server requests." +} + +// AttrRequestMethod returns a required attribute for the "http.request.method" +// semantic convention. It represents the HTTP request method. +func (ServerActiveRequestsObservable) AttrRequestMethod(val RequestMethodAttr) attribute.KeyValue { + return attribute.String("http.request.method", string(val)) +} + +// AttrURLScheme returns a required attribute for the "url.scheme" semantic +// convention. It represents the [URI scheme] component identifying the used +// protocol. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (ServerActiveRequestsObservable) AttrURLScheme(val string) attribute.KeyValue { + return attribute.String("url.scheme", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the name of the local HTTP server that +// received the request. +func (ServerActiveRequestsObservable) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the port of the local HTTP server that received the +// request. +func (ServerActiveRequestsObservable) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// ServerRequestBodySize is an instrument used to record metric values conforming +// to the "http.server.request.body.size" semantic conventions. It represents the +// size of HTTP server request bodies. +type ServerRequestBodySize struct { + metric.Int64Histogram +} + +var newServerRequestBodySizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Size of HTTP server request bodies."), + metric.WithUnit("By"), +} + +// NewServerRequestBodySize returns a new ServerRequestBodySize instrument. +func NewServerRequestBodySize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerRequestBodySize, error) { + // Check if the meter is nil. + if m == nil { + return ServerRequestBodySize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerRequestBodySizeOpts + } else { + opt = append(opt, newServerRequestBodySizeOpts...) + } + + i, err := m.Int64Histogram( + "http.server.request.body.size", + opt..., + ) + if err != nil { + return ServerRequestBodySize{noop.Int64Histogram{}}, err + } + return ServerRequestBodySize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerRequestBodySize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerRequestBodySize) Name() string { + return "http.server.request.body.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerRequestBodySize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ServerRequestBodySize) Description() string { + return "Size of HTTP server request bodies." +} + +// Record records val to the current distribution for attrs. +// +// The requestMethod is the HTTP request method. +// +// The urlScheme is the the [URI scheme] component identifying the used protocol. +// +// All additional attrs passed are included in the recorded value. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +// +// The size of the request payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ServerRequestBodySize) Record( + ctx context.Context, + val int64, + requestMethod RequestMethodAttr, + urlScheme string, + attrs ...attribute.KeyValue, +) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// The size of the request payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ServerRequestBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerRequestBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "http.response.status_code" semantic convention. It represents the +// [HTTP response status code]. +// +// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 +func (ServerRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue { + return attribute.Int("http.response.status_code", val) +} + +// AttrRoute returns an optional attribute for the "http.route" semantic +// convention. It represents the matched route template for the request. This +// MUST be low-cardinality and include all static path segments, with dynamic +// path segments represented with placeholders. +func (ServerRequestBodySize) AttrRoute(val string) attribute.KeyValue { + return attribute.String("http.route", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ServerRequestBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ServerRequestBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the name of the local HTTP server that +// received the request. +func (ServerRequestBodySize) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the port of the local HTTP server that received the +// request. +func (ServerRequestBodySize) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrUserAgentSyntheticType returns an optional attribute for the +// "user_agent.synthetic.type" semantic convention. It represents the specifies +// the category of synthetic traffic, such as tests or bots. +func (ServerRequestBodySize) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue { + return attribute.String("user_agent.synthetic.type", string(val)) +} + +// ServerRequestDuration is an instrument used to record metric values conforming +// to the "http.server.request.duration" semantic conventions. It represents the +// duration of HTTP server requests. +type ServerRequestDuration struct { + metric.Float64Histogram +} + +var newServerRequestDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Duration of HTTP server requests."), + metric.WithUnit("s"), + metric.WithExplicitBucketBoundaries([]float64{0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10}...), +} + +// NewServerRequestDuration returns a new ServerRequestDuration instrument. +func NewServerRequestDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ServerRequestDuration, error) { + // Check if the meter is nil. + if m == nil { + return ServerRequestDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerRequestDurationOpts + } else { + opt = append(opt, newServerRequestDurationOpts...) + } + + i, err := m.Float64Histogram( + "http.server.request.duration", + opt..., + ) + if err != nil { + return ServerRequestDuration{noop.Float64Histogram{}}, err + } + return ServerRequestDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerRequestDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerRequestDuration) Name() string { + return "http.server.request.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerRequestDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ServerRequestDuration) Description() string { + return "Duration of HTTP server requests." +} + +// Record records val to the current distribution for attrs. +// +// The requestMethod is the HTTP request method. +// +// The urlScheme is the the [URI scheme] component identifying the used protocol. +// +// All additional attrs passed are included in the recorded value. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +func (m ServerRequestDuration) Record( + ctx context.Context, + val float64, + requestMethod RequestMethodAttr, + urlScheme string, + attrs ...attribute.KeyValue, +) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +func (m ServerRequestDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerRequestDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "http.response.status_code" semantic convention. It represents the +// [HTTP response status code]. +// +// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 +func (ServerRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue { + return attribute.Int("http.response.status_code", val) +} + +// AttrRoute returns an optional attribute for the "http.route" semantic +// convention. It represents the matched route template for the request. This +// MUST be low-cardinality and include all static path segments, with dynamic +// path segments represented with placeholders. +func (ServerRequestDuration) AttrRoute(val string) attribute.KeyValue { + return attribute.String("http.route", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ServerRequestDuration) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ServerRequestDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the name of the local HTTP server that +// received the request. +func (ServerRequestDuration) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the port of the local HTTP server that received the +// request. +func (ServerRequestDuration) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrUserAgentSyntheticType returns an optional attribute for the +// "user_agent.synthetic.type" semantic convention. It represents the specifies +// the category of synthetic traffic, such as tests or bots. +func (ServerRequestDuration) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue { + return attribute.String("user_agent.synthetic.type", string(val)) +} + +// ServerResponseBodySize is an instrument used to record metric values +// conforming to the "http.server.response.body.size" semantic conventions. It +// represents the size of HTTP server response bodies. +type ServerResponseBodySize struct { + metric.Int64Histogram +} + +var newServerResponseBodySizeOpts = []metric.Int64HistogramOption{ + metric.WithDescription("Size of HTTP server response bodies."), + metric.WithUnit("By"), +} + +// NewServerResponseBodySize returns a new ServerResponseBodySize instrument. +func NewServerResponseBodySize( + m metric.Meter, + opt ...metric.Int64HistogramOption, +) (ServerResponseBodySize, error) { + // Check if the meter is nil. + if m == nil { + return ServerResponseBodySize{noop.Int64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerResponseBodySizeOpts + } else { + opt = append(opt, newServerResponseBodySizeOpts...) + } + + i, err := m.Int64Histogram( + "http.server.response.body.size", + opt..., + ) + if err != nil { + return ServerResponseBodySize{noop.Int64Histogram{}}, err + } + return ServerResponseBodySize{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerResponseBodySize) Inst() metric.Int64Histogram { + return m.Int64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerResponseBodySize) Name() string { + return "http.server.response.body.size" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerResponseBodySize) Unit() string { + return "By" +} + +// Description returns the semantic convention description of the instrument +func (ServerResponseBodySize) Description() string { + return "Size of HTTP server response bodies." +} + +// Record records val to the current distribution for attrs. +// +// The requestMethod is the HTTP request method. +// +// The urlScheme is the the [URI scheme] component identifying the used protocol. +// +// All additional attrs passed are included in the recorded value. +// +// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1 +// +// The size of the response payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ServerResponseBodySize) Record( + ctx context.Context, + val int64, + requestMethod RequestMethodAttr, + urlScheme string, + attrs ...attribute.KeyValue, +) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Int64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("http.request.method", string(requestMethod)), + attribute.String("url.scheme", urlScheme), + )..., + ), + ) + + m.Int64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// The size of the response payload body in bytes. This is the number of bytes +// transferred excluding headers and is often, but not always, present as the +// [Content-Length] header. For requests using transport encoding, this should be +// the compressed size. +// +// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length +func (m ServerResponseBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) { + if !m.Int64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Int64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Int64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerResponseBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "http.response.status_code" semantic convention. It represents the +// [HTTP response status code]. +// +// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6 +func (ServerResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue { + return attribute.Int("http.response.status_code", val) +} + +// AttrRoute returns an optional attribute for the "http.route" semantic +// convention. It represents the matched route template for the request. This +// MUST be low-cardinality and include all static path segments, with dynamic +// path segments represented with placeholders. +func (ServerResponseBodySize) AttrRoute(val string) attribute.KeyValue { + return attribute.String("http.route", val) +} + +// AttrNetworkProtocolName returns an optional attribute for the +// "network.protocol.name" semantic convention. It represents the +// [OSI application layer] or non-OSI equivalent. +// +// [OSI application layer]: https://wikipedia.org/wiki/Application_layer +func (ServerResponseBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue { + return attribute.String("network.protocol.name", val) +} + +// AttrNetworkProtocolVersion returns an optional attribute for the +// "network.protocol.version" semantic convention. It represents the actual +// version of the protocol used for network communication. +func (ServerResponseBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue { + return attribute.String("network.protocol.version", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents the name of the local HTTP server that +// received the request. +func (ServerResponseBodySize) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the port of the local HTTP server that received the +// request. +func (ServerResponseBodySize) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// AttrUserAgentSyntheticType returns an optional attribute for the +// "user_agent.synthetic.type" semantic convention. It represents the specifies +// the category of synthetic traffic, such as tests or bots. +func (ServerResponseBodySize) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue { + return attribute.String("user_agent.synthetic.type", string(val)) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/otelconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/otelconv/metric.go similarity index 94% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/otelconv/metric.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/otelconv/metric.go index 367b5876020..9eaf0fd9a2d 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/otelconv/metric.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/otelconv/metric.go @@ -187,6 +187,12 @@ func (SDKExporterLogExported) Description() string { // non-rejected log records count as success. // If no rejection reason is available, `rejected` SHOULD be used as value for // `error.type`. +// If the exporter retries failed export attempts, the export operation is +// considered finished only after the final attempt has concluded. +// Each log record MUST be counted exactly once per export operation: +// intermediate failed attempts that are followed by a retry MUST NOT increment +// the counter, +// and `error.type` reflects the cause of the final attempt. func (m SDKExporterLogExported) Add( ctx context.Context, incr int64, @@ -222,6 +228,12 @@ func (m SDKExporterLogExported) Add( // non-rejected log records count as success. // If no rejection reason is available, `rejected` SHOULD be used as value for // `error.type`. +// If the exporter retries failed export attempts, the export operation is +// considered finished only after the final attempt has concluded. +// Each log record MUST be counted exactly once per export operation: +// intermediate failed attempts that are followed by a retry MUST NOT increment +// the counter, +// and `error.type` reflects the cause of the final attempt. func (m SDKExporterLogExported) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64Counter.Enabled(ctx) { return @@ -429,8 +441,10 @@ func (SDKExporterLogInflight) Description() string { // // All additional attrs passed are included in the recorded value. // -// For successful exports, `error.type` MUST NOT be set. For failed exports, -// `error.type` MUST contain the failure cause. +// Log records are counted as inflight from when they are passed to the exporter +// until the export operation has concluded. +// If the exporter retries failed export attempts, log records remain inflight +// across all retry attempts and any backoff between them. func (m SDKExporterLogInflight) Add( ctx context.Context, incr int64, @@ -459,8 +473,10 @@ func (m SDKExporterLogInflight) Add( // AddSet adds incr to the existing count for set. // -// For successful exports, `error.type` MUST NOT be set. For failed exports, -// `error.type` MUST contain the failure cause. +// Log records are counted as inflight from when they are passed to the exporter +// until the export operation has concluded. +// If the exporter retries failed export attempts, log records remain inflight +// across all retry attempts and any backoff between them. func (m SDKExporterLogInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64UpDownCounter.Enabled(ctx) { return @@ -662,6 +678,12 @@ func (SDKExporterMetricDataPointExported) Description() string { // non-rejected data points count as success. // If no rejection reason is available, `rejected` SHOULD be used as value for // `error.type`. +// If the exporter retries failed export attempts, the export operation is +// considered finished only after the final attempt has concluded. +// Each metric data point MUST be counted exactly once per export operation: +// intermediate failed attempts that are followed by a retry MUST NOT increment +// the counter, +// and `error.type` reflects the cause of the final attempt. func (m SDKExporterMetricDataPointExported) Add( ctx context.Context, incr int64, @@ -697,6 +719,12 @@ func (m SDKExporterMetricDataPointExported) Add( // non-rejected data points count as success. // If no rejection reason is available, `rejected` SHOULD be used as value for // `error.type`. +// If the exporter retries failed export attempts, the export operation is +// considered finished only after the final attempt has concluded. +// Each metric data point MUST be counted exactly once per export operation: +// intermediate failed attempts that are followed by a retry MUST NOT increment +// the counter, +// and `error.type` reflects the cause of the final attempt. func (m SDKExporterMetricDataPointExported) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64Counter.Enabled(ctx) { return @@ -906,8 +934,10 @@ func (SDKExporterMetricDataPointInflight) Description() string { // // All additional attrs passed are included in the recorded value. // -// For successful exports, `error.type` MUST NOT be set. For failed exports, -// `error.type` MUST contain the failure cause. +// Metric data points are counted as inflight from when they are passed to the +// exporter until the export operation has concluded. +// If the exporter retries failed export attempts, metric data points remain +// inflight across all retry attempts and any backoff between them. func (m SDKExporterMetricDataPointInflight) Add( ctx context.Context, incr int64, @@ -936,8 +966,10 @@ func (m SDKExporterMetricDataPointInflight) Add( // AddSet adds incr to the existing count for set. // -// For successful exports, `error.type` MUST NOT be set. For failed exports, -// `error.type` MUST contain the failure cause. +// Metric data points are counted as inflight from when they are passed to the +// exporter until the export operation has concluded. +// If the exporter retries failed export attempts, metric data points remain +// inflight across all retry attempts and any backoff between them. func (m SDKExporterMetricDataPointInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64UpDownCounter.Enabled(ctx) { return @@ -1138,6 +1170,11 @@ func (SDKExporterOperationDuration) Description() string { // successful // operations, `error.type` MUST NOT be set. For unsuccessful export operations, // `error.type` MUST contain a relevant failure cause. +// If the exporter retries failed export attempts, exactly one observation MUST +// be recorded per export operation, +// covering the wall-clock duration from the start of the first attempt through +// the conclusion of the final attempt (including any backoff between attempts). +// `error.type` reflects the cause of the final attempt. // // [http]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1 // [grpc]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success @@ -1175,6 +1212,11 @@ func (m SDKExporterOperationDuration) Record( // successful // operations, `error.type` MUST NOT be set. For unsuccessful export operations, // `error.type` MUST contain a relevant failure cause. +// If the exporter retries failed export attempts, exactly one observation MUST +// be recorded per export operation, +// covering the wall-clock duration from the start of the first attempt through +// the conclusion of the final attempt (including any backoff between attempts). +// `error.type` reflects the cause of the final attempt. // // [http]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1 // [grpc]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success @@ -1312,6 +1354,11 @@ func (SDKExporterSpanExported) Description() string { // success. // If no rejection reason is available, `rejected` SHOULD be used as value for // `error.type`. +// If the exporter retries failed export attempts, the export operation is +// considered finished only after the final attempt has concluded. +// Each span MUST be counted exactly once per export operation: intermediate +// failed attempts that are followed by a retry MUST NOT increment the counter, +// and `error.type` reflects the cause of the final attempt. func (m SDKExporterSpanExported) Add( ctx context.Context, incr int64, @@ -1347,6 +1394,11 @@ func (m SDKExporterSpanExported) Add( // success. // If no rejection reason is available, `rejected` SHOULD be used as value for // `error.type`. +// If the exporter retries failed export attempts, the export operation is +// considered finished only after the final attempt has concluded. +// Each span MUST be counted exactly once per export operation: intermediate +// failed attempts that are followed by a retry MUST NOT increment the counter, +// and `error.type` reflects the cause of the final attempt. func (m SDKExporterSpanExported) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64Counter.Enabled(ctx) { return @@ -1554,8 +1606,10 @@ func (SDKExporterSpanInflight) Description() string { // // All additional attrs passed are included in the recorded value. // -// For successful exports, `error.type` MUST NOT be set. For failed exports, -// `error.type` MUST contain the failure cause. +// Spans are counted as inflight from when they are passed to the exporter until +// the export operation has concluded. +// If the exporter retries failed export attempts, spans remain inflight across +// all retry attempts and any backoff between them. func (m SDKExporterSpanInflight) Add( ctx context.Context, incr int64, @@ -1584,8 +1638,10 @@ func (m SDKExporterSpanInflight) Add( // AddSet adds incr to the existing count for set. // -// For successful exports, `error.type` MUST NOT be set. For failed exports, -// `error.type` MUST contain the failure cause. +// Spans are counted as inflight from when they are passed to the exporter until +// the export operation has concluded. +// If the exporter retries failed export attempts, spans remain inflight across +// all retry attempts and any backoff between them. func (m SDKExporterSpanInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64UpDownCounter.Enabled(ctx) { return @@ -2071,6 +2127,11 @@ func (SDKProcessorLogProcessed) Description() string { // // For successful processing, `error.type` MUST NOT be set. For failed // processing, `error.type` MUST contain the failure cause. +// SDK Batching Log Record Processors MUST use `queue_full` as the value of +// `error.type` for log records dropped due to a full queue. +// SDK Log Record Processors MUST use `already_shutdown` as the value of +// `error.type` for log records dropped because the processor has already been +// shut down. // For the SDK Simple and Batching Log Record Processor a log record is // considered to be processed already when it has been submitted to the exporter, // not when the corresponding export call has finished. @@ -2104,6 +2165,11 @@ func (m SDKProcessorLogProcessed) Add( // // For successful processing, `error.type` MUST NOT be set. For failed // processing, `error.type` MUST contain the failure cause. +// SDK Batching Log Record Processors MUST use `queue_full` as the value of +// `error.type` for log records dropped due to a full queue. +// SDK Log Record Processors MUST use `already_shutdown` as the value of +// `error.type` for log records dropped because the processor has already been +// shut down. // For the SDK Simple and Batching Log Record Processor a log record is // considered to be processed already when it has been submitted to the exporter, // not when the corresponding export call has finished. @@ -2125,8 +2191,6 @@ func (m SDKProcessorLogProcessed) AddSet(ctx context.Context, incr int64, set at // AttrErrorType returns an optional attribute for the "error.type" semantic // convention. It represents a low-cardinality description of the failure reason. -// SDK Batching Log Record Processors MUST use `queue_full` for log records -// dropped due to a full queue. func (SDKProcessorLogProcessed) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { return attribute.String("error.type", string(val)) } @@ -2207,8 +2271,6 @@ func (SDKProcessorLogProcessedObservable) Description() string { // AttrErrorType returns an optional attribute for the "error.type" semantic // convention. It represents a low-cardinality description of the failure reason. -// SDK Batching Log Record Processors MUST use `queue_full` for log records -// dropped due to a full queue. func (SDKProcessorLogProcessedObservable) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { return attribute.String("error.type", string(val)) } @@ -2440,6 +2502,10 @@ func (SDKProcessorSpanProcessed) Description() string { // // For successful processing, `error.type` MUST NOT be set. For failed // processing, `error.type` MUST contain the failure cause. +// SDK Batching Span Processors MUST use `queue_full` as the value of +// `error.type` for spans dropped due to a full queue. +// SDK Span Processors MUST use `already_shutdown` as the value of `error.type` +// for spans dropped because the processor has already been shut down. // For the SDK Simple and Batching Span Processor a span is considered to be // processed already when it has been submitted to the exporter, not when the // corresponding export call has finished. @@ -2473,6 +2539,10 @@ func (m SDKProcessorSpanProcessed) Add( // // For successful processing, `error.type` MUST NOT be set. For failed // processing, `error.type` MUST contain the failure cause. +// SDK Batching Span Processors MUST use `queue_full` as the value of +// `error.type` for spans dropped due to a full queue. +// SDK Span Processors MUST use `already_shutdown` as the value of `error.type` +// for spans dropped because the processor has already been shut down. // For the SDK Simple and Batching Span Processor a span is considered to be // processed already when it has been submitted to the exporter, not when the // corresponding export call has finished. @@ -2494,8 +2564,6 @@ func (m SDKProcessorSpanProcessed) AddSet(ctx context.Context, incr int64, set a // AttrErrorType returns an optional attribute for the "error.type" semantic // convention. It represents a low-cardinality description of the failure reason. -// SDK Batching Span Processors MUST use `queue_full` for spans dropped due to a -// full queue. func (SDKProcessorSpanProcessed) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { return attribute.String("error.type", string(val)) } @@ -2576,8 +2644,6 @@ func (SDKProcessorSpanProcessedObservable) Description() string { // AttrErrorType returns an optional attribute for the "error.type" semantic // convention. It represents a low-cardinality description of the failure reason. -// SDK Batching Span Processors MUST use `queue_full` for spans dropped due to a -// full queue. func (SDKProcessorSpanProcessedObservable) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { return attribute.String("error.type", string(val)) } @@ -2806,6 +2872,9 @@ func (SDKSpanLive) Description() string { // Add adds incr to the existing count for attrs. // // All additional attrs passed are included in the recorded value. +// +// Non-recording spans are not counted, hence `otel.span.sampling_result` can +// only take values `RECORD_ONLY` and `RECORD_AND_SAMPLE`, not `DROP`. func (m SDKSpanLive) Add( ctx context.Context, incr int64, @@ -2833,6 +2902,9 @@ func (m SDKSpanLive) Add( } // AddSet adds incr to the existing count for set. +// +// Non-recording spans are not counted, hence `otel.span.sampling_result` can +// only take values `RECORD_ONLY` and `RECORD_AND_SAMPLE`, not `DROP`. func (m SDKSpanLive) AddSet(ctx context.Context, incr int64, set attribute.Set) { if !m.Int64UpDownCounter.Enabled(ctx) { return diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv/metric.go new file mode 100644 index 00000000000..c766d4b9e8a --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv/metric.go @@ -0,0 +1,357 @@ +// Code generated from semantic convention specification. DO NOT EDIT. + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package rpcconv provides types and functionality for OpenTelemetry semantic +// conventions in the "rpc" namespace. +package rpcconv + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" + "go.opentelemetry.io/otel/semconv/internal/metricpool" +) + +// ErrorTypeAttr is an attribute conforming to the error.type semantic +// conventions. It represents the describes a class of error the operation ended +// with. +type ErrorTypeAttr string + +var ( + // ErrorTypeOther is a fallback error value to be used when the instrumentation + // doesn't define a custom value. + ErrorTypeOther ErrorTypeAttr = "_OTHER" +) + +// SystemNameAttr is an attribute conforming to the rpc.system.name semantic +// conventions. It represents the Remote Procedure Call (RPC) system. +type SystemNameAttr string + +var ( + // SystemNameGRPC is the [gRPC]. + // + // [gRPC]: https://grpc.io/ + SystemNameGRPC SystemNameAttr = "grpc" + // SystemNameDubbo is the [Apache Dubbo]. + // + // [Apache Dubbo]: https://dubbo.apache.org/ + SystemNameDubbo SystemNameAttr = "dubbo" + // SystemNameConnectrpc is the [Connect RPC]. + // + // [Connect RPC]: https://connectrpc.com/ + SystemNameConnectrpc SystemNameAttr = "connectrpc" + // SystemNameJSONRPC is the [JSON-RPC]. + // + // [JSON-RPC]: https://www.jsonrpc.org/ + SystemNameJSONRPC SystemNameAttr = "jsonrpc" +) + +// ClientCallDuration is an instrument used to record metric values conforming to +// the "rpc.client.call.duration" semantic conventions. It represents the +// measures the duration of an outgoing Remote Procedure Call (RPC). +type ClientCallDuration struct { + metric.Float64Histogram +} + +var newClientCallDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Measures the duration of an outgoing Remote Procedure Call (RPC)."), + metric.WithUnit("s"), + metric.WithExplicitBucketBoundaries([]float64{0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10}...), +} + +// NewClientCallDuration returns a new ClientCallDuration instrument. +func NewClientCallDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ClientCallDuration, error) { + // Check if the meter is nil. + if m == nil { + return ClientCallDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newClientCallDurationOpts + } else { + opt = append(opt, newClientCallDurationOpts...) + } + + i, err := m.Float64Histogram( + "rpc.client.call.duration", + opt..., + ) + if err != nil { + return ClientCallDuration{noop.Float64Histogram{}}, err + } + return ClientCallDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ClientCallDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ClientCallDuration) Name() string { + return "rpc.client.call.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ClientCallDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ClientCallDuration) Description() string { + return "Measures the duration of an outgoing Remote Procedure Call (RPC)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// When this metric is reported alongside an RPC client span, the metric value +// SHOULD be the same as the RPC client span duration. +func (m ClientCallDuration) Record( + ctx context.Context, + val float64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("rpc.system.name", string(systemName)), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// When this metric is reported alongside an RPC client span, the metric value +// SHOULD be the same as the RPC client span duration. +func (m ClientCallDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ClientCallDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ClientCallDuration) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ClientCallDuration) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents a string identifying a group of RPC server +// instances request is sent to. +func (ClientCallDuration) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ClientCallDuration) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} + +// ServerCallDuration is an instrument used to record metric values conforming to +// the "rpc.server.call.duration" semantic conventions. It represents the +// measures the duration of an incoming Remote Procedure Call (RPC). +type ServerCallDuration struct { + metric.Float64Histogram +} + +var newServerCallDurationOpts = []metric.Float64HistogramOption{ + metric.WithDescription("Measures the duration of an incoming Remote Procedure Call (RPC)."), + metric.WithUnit("s"), + metric.WithExplicitBucketBoundaries([]float64{0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10}...), +} + +// NewServerCallDuration returns a new ServerCallDuration instrument. +func NewServerCallDuration( + m metric.Meter, + opt ...metric.Float64HistogramOption, +) (ServerCallDuration, error) { + // Check if the meter is nil. + if m == nil { + return ServerCallDuration{noop.Float64Histogram{}}, nil + } + + if len(opt) == 0 { + opt = newServerCallDurationOpts + } else { + opt = append(opt, newServerCallDurationOpts...) + } + + i, err := m.Float64Histogram( + "rpc.server.call.duration", + opt..., + ) + if err != nil { + return ServerCallDuration{noop.Float64Histogram{}}, err + } + return ServerCallDuration{i}, nil +} + +// Inst returns the underlying metric instrument. +func (m ServerCallDuration) Inst() metric.Float64Histogram { + return m.Float64Histogram +} + +// Name returns the semantic convention name of the instrument. +func (ServerCallDuration) Name() string { + return "rpc.server.call.duration" +} + +// Unit returns the semantic convention unit of the instrument +func (ServerCallDuration) Unit() string { + return "s" +} + +// Description returns the semantic convention description of the instrument +func (ServerCallDuration) Description() string { + return "Measures the duration of an incoming Remote Procedure Call (RPC)." +} + +// Record records val to the current distribution for attrs. +// +// The systemName is the the Remote Procedure Call (RPC) system. +// +// All additional attrs passed are included in the recorded value. +// +// When this metric is reported alongside an RPC server span, the metric value +// SHOULD be the same as the RPC server span duration. +func (m ServerCallDuration) Record( + ctx context.Context, + val float64, + systemName SystemNameAttr, + attrs ...attribute.KeyValue, +) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if len(attrs) == 0 { + m.Float64Histogram.Record(ctx, val, metric.WithAttributes( + attribute.String("rpc.system.name", string(systemName)), + )) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append( + *o, + metric.WithAttributes( + append( + attrs[:len(attrs):len(attrs)], + attribute.String("rpc.system.name", string(systemName)), + )..., + ), + ) + + m.Float64Histogram.Record(ctx, val, *o...) +} + +// RecordSet records val to the current distribution for set. +// +// When this metric is reported alongside an RPC server span, the metric value +// SHOULD be the same as the RPC server span duration. +func (m ServerCallDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) { + if !m.Float64Histogram.Enabled(ctx) { + return + } + if set.Len() == 0 { + m.Float64Histogram.Record(ctx, val) + return + } + + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) + + *o = append(*o, metric.WithAttributeSet(set)) + m.Float64Histogram.Record(ctx, val, *o...) +} + +// AttrErrorType returns an optional attribute for the "error.type" semantic +// convention. It represents the describes a class of error the operation ended +// with. +func (ServerCallDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue { + return attribute.String("error.type", string(val)) +} + +// AttrMethod returns an optional attribute for the "rpc.method" semantic +// convention. It represents the fully-qualified logical name of the method from +// the RPC interface perspective. +func (ServerCallDuration) AttrMethod(val string) attribute.KeyValue { + return attribute.String("rpc.method", val) +} + +// AttrResponseStatusCode returns an optional attribute for the +// "rpc.response.status_code" semantic convention. It represents the status code +// of the RPC returned by the RPC server or generated by the client. +func (ServerCallDuration) AttrResponseStatusCode(val string) attribute.KeyValue { + return attribute.String("rpc.response.status_code", val) +} + +// AttrServerAddress returns an optional attribute for the "server.address" +// semantic convention. It represents a string identifying a group of RPC server +// instances request is sent to. +func (ServerCallDuration) AttrServerAddress(val string) attribute.KeyValue { + return attribute.String("server.address", val) +} + +// AttrServerPort returns an optional attribute for the "server.port" semantic +// convention. It represents the server port number. +func (ServerCallDuration) AttrServerPort(val int) attribute.KeyValue { + return attribute.Int("server.port", val) +} diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index ea790309690..f599bf285de 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -5,5 +5,5 @@ package otel // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.45.0" + return "1.46.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index 3b1ad7301a2..f329d171d94 100644 --- a/vendor/go.opentelemetry.io/otel/versions.yaml +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -3,7 +3,7 @@ module-sets: stable-v1: - version: v1.45.0 + version: v1.46.0 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opencensus @@ -22,12 +22,12 @@ module-sets: - go.opentelemetry.io/otel/sdk/metric - go.opentelemetry.io/otel/trace experimental-metrics: - version: v0.67.0 + version: v0.68.0 modules: - go.opentelemetry.io/otel/exporters/prometheus - go.opentelemetry.io/otel/metric/x experimental-logs: - version: v0.21.0 + version: v0.22.0 modules: - go.opentelemetry.io/otel/log - go.opentelemetry.io/otel/log/logtest @@ -37,7 +37,7 @@ module-sets: - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp - go.opentelemetry.io/otel/exporters/stdout/stdoutlog experimental-schema: - version: v0.0.18 + version: v0.0.19 modules: - go.opentelemetry.io/otel/schema excluded-modules: diff --git a/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go b/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go index 304f6476374..cef3580008e 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go @@ -194,7 +194,7 @@ type AnyValue_StringValueStrindex struct { // Profiling signal and process the data as if this value were absent or // empty, ignoring its semantic content for the non-Profiling signal. // - // Status: [Development] + // Status: [Alpha] StringValueStrindex int32 `protobuf:"varint,8,opt,name=string_value_strindex,json=stringValueStrindex,proto3,oneof"` } @@ -330,7 +330,7 @@ type KeyValue struct { unknownFields protoimpl.UnknownFields // The key name of the pair. - // key_ref MUST NOT be set if key is used. + // key_strindex MUST NOT be set if key is used. Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // The value of the pair. Value *AnyValue `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` @@ -344,7 +344,7 @@ type KeyValue struct { // Profiling signal and process the data as if this value were absent or // empty, ignoring its semantic content for the non-Profiling signal. // - // Status: [Development] + // Status: [Alpha] KeyStrindex int32 `protobuf:"varint,3,opt,name=key_strindex,json=keyStrindex,proto3" json:"key_strindex,omitempty"` } diff --git a/vendor/go.yaml.in/yaml/v3/parserc.go b/vendor/go.yaml.in/yaml/v3/parserc.go index 25fe823637a..f35829db4da 100644 --- a/vendor/go.yaml.in/yaml/v3/parserc.go +++ b/vendor/go.yaml.in/yaml/v3/parserc.go @@ -226,9 +226,9 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool } // Parse the production: -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END // -// ************ +// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +// ************ func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -249,13 +249,11 @@ func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) } // Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// -// * // -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// -// ************************* +// implicit_document ::= block_node DOCUMENT-END* +// * +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// ************************* func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { token := peek_token(parser) @@ -359,9 +357,9 @@ func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t } // Parse the productions: -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* // -// *********** +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// *********** func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -382,11 +380,10 @@ func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event } // Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// -// ************* // -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// implicit_document ::= block_node DOCUMENT-END* +// ************* +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -432,42 +429,32 @@ func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) } // Parse the productions: -// block_node_or_indentless_sequence ::= -// -// ALIAS -// ***** -// | properties (block_content | indentless_block_sequence)? -// ********** * -// | block_content | indentless_block_sequence -// * -// -// block_node ::= ALIAS -// -// ***** -// | properties block_content? -// ********** * -// | block_content -// * -// -// flow_node ::= ALIAS -// -// ***** -// | properties flow_content? -// ********** * -// | flow_content -// * -// -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// -// ************************* -// -// block_content ::= block_collection | flow_collection | SCALAR -// -// ****** // -// flow_content ::= flow_collection | SCALAR -// -// ****** +// block_node_or_indentless_sequence ::= +// ALIAS +// ***** +// | properties (block_content | indentless_block_sequence)? +// ********** * +// | block_content | indentless_block_sequence +// * +// block_node ::= ALIAS +// ***** +// | properties block_content? +// ********** * +// | block_content +// * +// flow_node ::= ALIAS +// ***** +// | properties flow_content? +// ********** * +// | flow_content +// * +// properties ::= TAG ANCHOR? | ANCHOR TAG? +// ************************* +// block_content ::= block_collection | flow_collection | SCALAR +// ****** +// flow_content ::= flow_collection | SCALAR +// ****** func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() @@ -697,9 +684,9 @@ func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, i } // Parse the productions: -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END // -// ******************** *********** * ********* +// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +// ******************** *********** * ********* func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -755,9 +742,9 @@ func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_e } // Parse the productions: -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ // -// *********** * +// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +// *********** * func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -821,15 +808,15 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { } // Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START // -// ******************* -// ((KEY block_node_or_indentless_sequence?)? -// *** * -// (VALUE block_node_or_indentless_sequence?)?)* +// block_mapping ::= BLOCK-MAPPING_START +// ******************* +// ((KEY block_node_or_indentless_sequence?)? +// *** * +// (VALUE block_node_or_indentless_sequence?)?)* // -// BLOCK-END -// ********* +// BLOCK-END +// ********* func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -896,13 +883,14 @@ func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_even } // Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START // -// ((KEY block_node_or_indentless_sequence?)? +// block_mapping ::= BLOCK-MAPPING_START +// +// ((KEY block_node_or_indentless_sequence?)? // -// (VALUE block_node_or_indentless_sequence?)?)* -// ***** * -// BLOCK-END +// (VALUE block_node_or_indentless_sequence?)?)* +// ***** * +// BLOCK-END func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -929,19 +917,17 @@ func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_ev } // Parse the productions: -// flow_sequence ::= FLOW-SEQUENCE-START -// -// ******************* -// (flow_sequence_entry FLOW-ENTRY)* -// * ********** -// flow_sequence_entry? -// * -// FLOW-SEQUENCE-END -// ***************** // -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// -// * +// flow_sequence ::= FLOW-SEQUENCE-START +// ******************* +// (flow_sequence_entry FLOW-ENTRY)* +// * ********** +// flow_sequence_entry? +// * +// FLOW-SEQUENCE-END +// ***************** +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -1005,9 +991,9 @@ func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_ev } // Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? // -// *** * +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// *** * func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -1026,9 +1012,9 @@ func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, ev } // Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? // -// ***** * +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// ***** * func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -1050,9 +1036,9 @@ func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, } // Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? // -// * +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -1068,18 +1054,17 @@ func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, ev } // Parse the productions: -// flow_mapping ::= FLOW-MAPPING-START -// -// ****************** -// (flow_mapping_entry FLOW-ENTRY)* -// * ********** -// flow_mapping_entry? -// ****************** -// FLOW-MAPPING-END -// **************** // -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// - *** * +// flow_mapping ::= FLOW-MAPPING-START +// ****************** +// (flow_mapping_entry FLOW-ENTRY)* +// * ********** +// flow_mapping_entry? +// ****************** +// FLOW-MAPPING-END +// **************** +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * *** * func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -1144,8 +1129,9 @@ func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event } // Parse the productions: -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// - ***** * +// +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * ***** * func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { token := peek_token(parser) if token == nil { diff --git a/vendor/go.yaml.in/yaml/v3/yamlh.go b/vendor/go.yaml.in/yaml/v3/yamlh.go index f59aa40f640..07c442361ce 100644 --- a/vendor/go.yaml.in/yaml/v3/yamlh.go +++ b/vendor/go.yaml.in/yaml/v3/yamlh.go @@ -433,21 +433,19 @@ type yaml_document_t struct { // The prototype of a read handler. // -// The read handler is called when the parser needs to read more bytes from the -// source. The handler should write not more than size bytes to the buffer. -// The number of written bytes should be set to the size_read variable. +// The read handler is called when the parser needs to read more bytes from the +// source. The handler should write not more than size bytes to the buffer. +// The number of written bytes should be set to the size_read variable. // -// [in,out] data A pointer to an application data specified by +// [in,out] data A pointer to an application data specified by +// yaml_parser_set_input(). +// [out] buffer The buffer to write the data from the source. +// [in] size The size of the buffer. +// [out] size_read The actual number of bytes read from the source. // -// yaml_parser_set_input(). -// -// [out] buffer The buffer to write the data from the source. -// [in] size The size of the buffer. -// [out] size_read The actual number of bytes read from the source. -// -// On success, the handler should return 1. If the handler failed, -// the returned value should be 0. On EOF, the handler should set the -// size_read to 0 and return 1. +// On success, the handler should return 1. If the handler failed, +// the returned value should be 0. On EOF, the handler should set the +// size_read to 0 and return 1. type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) // This structure holds information about a potential simple key. @@ -655,19 +653,17 @@ type yaml_comment_t struct { // The prototype of a write handler. // -// The write handler is called when the emitter needs to flush the accumulated -// characters to the output. The handler should write @a size bytes of the -// @a buffer to the output. -// -// @param[in,out] data A pointer to an application data specified by -// -// yaml_emitter_set_output(). +// The write handler is called when the emitter needs to flush the accumulated +// characters to the output. The handler should write @a size bytes of the +// @a buffer to the output. // -// @param[in] buffer The buffer with bytes to be written. -// @param[in] size The size of the buffer. +// @param[in,out] data A pointer to an application data specified by +// yaml_emitter_set_output(). +// @param[in] buffer The buffer with bytes to be written. +// @param[in] size The size of the buffer. // -// @returns On success, the handler should return @c 1. If the handler failed, -// the returned value should be @c 0. +// @returns On success, the handler should return @c 1. If the handler failed, +// the returned value should be @c 0. type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error type yaml_emitter_state_t int diff --git a/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go index 8d99551feec..b1da45687cc 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go +++ b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (!amd64 && !loong64 && !ppc64le && !ppc64 && !s390x) || !gc || purego +//go:build (!amd64 && !loong64 && !ppc64le && !ppc64 && !riscv64 && !s390x) || !gc || purego package poly1305 diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go index 315b84ac39b..55041bf51d5 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build gc && !purego && (amd64 || loong64 || ppc64 || ppc64le) +//go:build gc && !purego && (amd64 || loong64 || ppc64 || ppc64le || riscv64) package poly1305 diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_riscv64.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_riscv64.s new file mode 100644 index 00000000000..ce5eb3d43d9 --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_riscv64.s @@ -0,0 +1,158 @@ +// Copyright 2026 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 gc && !purego + +#define LOAD64U(base, offset, t0, t1, t2, t3, dst) \ + MOVBU (offset+0*1)(base), t0; \ + MOVBU (offset+1*1)(base), t1; \ + MOVBU (offset+2*1)(base), t2; \ + MOVBU (offset+3*1)(base), t3; \ + SLL $8, t1; \ + SLL $16, t2; \ + SLL $24, t3; \ + OR t1, t0; \ + OR t3, t2; \ + OR t2, t0, dst; \ + MOVBU (offset+4*1)(base), t0; \ + MOVBU (offset+5*1)(base), t1; \ + MOVBU (offset+6*1)(base), t2; \ + MOVBU (offset+7*1)(base), t3; \ + SLL $32, t0; \ + SLL $40, t1; \ + SLL $48, t2; \ + SLL $56, t3; \ + OR t1, t0; \ + OR t3, t2; \ + OR t2, t0; \ + OR t0, dst + +// func update(state *macState, msg []byte) +TEXT ·update(SB), $0-32 + MOV state+0(FP), X5 + MOV msg_base+8(FP), X6 + MOV msg_len+16(FP), X7 + + MOV $16, X8 + + AND $7, X6, X28 + + MOV (0*8)(X5), X9 // h0 + MOV (1*8)(X5), X10 // h1 + MOV (2*8)(X5), X11 // h2 + MOV (3*8)(X5), X12 // r0 + MOV (4*8)(X5), X13 // r1 + + BLT X7, X8, tail + +loop: + BEQZ X28, aligned_load + + LOAD64U(X6, 0*8, X16, X18, X19, X20, X15) // msg[0:8] + LOAD64U(X6, 1*8, X16, X18, X19, X20, X17) // msg[8:16] + JMP block + +aligned_load: + MOV (0*8)(X6), X15 // msg[0:8] + MOV (1*8)(X6), X17 // msg[8:16] + +block: + ADD X15, X9 // h0 (x1 + y1 = z1', if z1' < x1 then z1' overflow) + SLTU X15, X9, X19 // h0.carry + ADD X17, X10, X22 + SLTU X17, X22, X23 + ADD X22, X19, X10 // h1 + SLTU X22, X10, X19 + OR X23, X19 // h1.carry + ADD $1, X19 + ADD X19, X11 // h2 + + ADD $16, X6 // msg = msg[16:] + +multiply: + MULHU X9, X12, X16 // h0r0.hi + MUL X9, X12, X15 // h0r0.lo + MULHU X10, X12, X17 // h1r0.hi + MUL X10, X12, X14 // h1r0.lo + ADD X14, X16 + SLTU X14, X16, X19 + ADD X19, X17 + MUL X11, X12, X20 + ADD X17, X20 + MULHU X9, X13, X17 // h0r1.hi + MUL X9, X13, X14 // h0r1.lo + ADD X14, X16 + SLTU X14, X16, X19 + ADD X19, X17 + MOV X17, X9 + MUL X11, X13, X21 // h2r1 + MULHU X10, X13, X17 // h1r1.hi + MUL X10, X13, X14 // h1r1.lo + ADD X14, X20 + ADD X17, X21, X22 + SLTU X14, X20, X19 + ADD X22, X19, X21 + ADD X9, X20 + SLTU X9, X20, X19 + ADD X19, X21 + AND $3, X20, X11 + AND $-4, X20, X18 + ADD X18, X15, X9 + ADD X21, X16, X22 + SLTU X18, X9, X19 + SLTU X21, X22, X23 + ADD X22, X19, X10 + SLTU X22, X10, X19 + OR X19, X23, X19 + ADD X19, X11 + SLL $62, X21, X22 + SRL $2, X20, X23 + SRL $2, X21, X21 + OR X22, X23, X20 + ADD X20, X9, X9 + ADD X21, X10, X22 + SLTU X20, X9, X19 + SLTU X21, X22, X23 + ADD X22, X19, X10 + SLTU X22, X10, X19 + OR X19, X23, X19 + ADD X19, X11, X11 + + SUB $16, X7, X7 + BGE X7, X8, loop + +tail: + BEQ X7, X0, done + MOV $1, X15 + MOV $0, X16 + ADD X7, X6, X6 + +flush_buffer: + MOVBU -1(X6), X20 + SRL $56, X15, X19 + SLL $8, X16, X23 + SLL $8, X15, X15 + OR X19, X23, X16 + XOR X20, X15 + SUB $1, X7, X7 + SUB $1, X6, X6 + BNE X7, X0, flush_buffer + + ADD X15, X9 + SLTU X15, X9, X19 + ADD X16, X10, X22 + SLTU X16, X22, X23 + ADD X22, X19, X10 + SLTU X22, X10, X19 + OR X23, X19 + ADD X19, X11 + + MOV $16, X7 + JMP multiply + +done: + MOV X9, (0*8)(X5) // h0 + MOV X10, (1*8)(X5) + MOV X11, (2*8)(X5) + RET diff --git a/vendor/golang.org/x/net/http/httpproxy/proxy.go b/vendor/golang.org/x/net/http/httpproxy/proxy.go index 5ab499b0bcb..1e260f4444a 100644 --- a/vendor/golang.org/x/net/http/httpproxy/proxy.go +++ b/vendor/golang.org/x/net/http/httpproxy/proxy.go @@ -80,18 +80,19 @@ type config struct { domainMatchers []matcher } -// FromEnvironment returns a Config instance populated from the -// environment variables HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the -// lowercase versions thereof). +// FromEnvironment returns a Config instance populated from the environment +// variables HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions +// thereof). When both the uppercase and lowercase versions are provided, the +// lowercase versions are prioritized. // // The environment values may be either a complete URL or a // "host[:port]", in which case the "http" scheme is assumed. An error // is returned if the value is a different form. func FromEnvironment() *Config { return &Config{ - HTTPProxy: getEnvAny("HTTP_PROXY", "http_proxy"), - HTTPSProxy: getEnvAny("HTTPS_PROXY", "https_proxy"), - NoProxy: getEnvAny("NO_PROXY", "no_proxy"), + HTTPProxy: getEnvAny("http_proxy", "HTTP_PROXY"), + HTTPSProxy: getEnvAny("https_proxy", "HTTPS_PROXY"), + NoProxy: getEnvAny("no_proxy", "NO_PROXY"), CGI: os.Getenv("REQUEST_METHOD") != "", } } diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 46219da2b01..e6d0c265acf 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -39,7 +39,6 @@ func NewEncoder(w io.Writer) *Encoder { tableSizeUpdate: false, w: w, } - e.dynTab.table.init() e.dynTab.setMaxSize(initialHeaderTableSize) return e } diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 7a1d976696a..ecd3eeca99a 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -105,7 +105,6 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod emitEnabled: true, firstField: true, } - d.dynTab.table.init() d.dynTab.allowedMaxSize = maxDynamicTableSize d.dynTab.setMaxSize(maxDynamicTableSize) return d diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go index 8cbdf3f019c..3bd7eb75332 100644 --- a/vendor/golang.org/x/net/http2/hpack/tables.go +++ b/vendor/golang.org/x/net/http2/hpack/tables.go @@ -31,10 +31,18 @@ type headerFieldTable struct { // byName maps a HeaderField name to the unique id of the newest entry with // the same name. See above for a definition of "unique id". + // + // byName and byNameValue are used only by search, which is only called + // for tables used by encoders. For tables used only by decoders, the + // maps are never built, as a memory optimization for servers with many + // mostly-idle connections, each pinning a dynamic table. The maps are + // built lazily by the first search call and are nil until then. The two + // maps are always both nil or both non-nil. byName map[string]uint64 // byNameValue maps a HeaderField name/value pair to the unique id of the newest // entry with the same name and value. See above for a definition of "unique id". + // See byName for when this map is non-nil. byNameValue map[pairNameValue]uint64 } @@ -42,9 +50,17 @@ type pairNameValue struct { name, value string } -func (t *headerFieldTable) init() { - t.byName = make(map[string]uint64) - t.byNameValue = make(map[pairNameValue]uint64) +// buildMaps initializes byName and byNameValue from ents. +func (t *headerFieldTable) buildMaps() { + t.byName = make(map[string]uint64, len(t.ents)) + t.byNameValue = make(map[pairNameValue]uint64, len(t.ents)) + for k, f := range t.ents { + // Map to the newest matching entry: later (newer) entries + // overwrite earlier ones, matching addEntry's behavior. + id := t.evictCount + uint64(k) + 1 + t.byName[f.Name] = id + t.byNameValue[pairNameValue{f.Name, f.Value}] = id + } } // len reports the number of entries in the table. @@ -54,9 +70,11 @@ func (t *headerFieldTable) len() int { // addEntry adds a new entry. func (t *headerFieldTable) addEntry(f HeaderField) { - id := uint64(t.len()) + t.evictCount + 1 - t.byName[f.Name] = id - t.byNameValue[pairNameValue{f.Name, f.Value}] = id + if t.byName != nil { + id := uint64(t.len()) + t.evictCount + 1 + t.byName[f.Name] = id + t.byNameValue[pairNameValue{f.Name, f.Value}] = id + } t.ents = append(t.ents, f) } @@ -65,14 +83,16 @@ func (t *headerFieldTable) evictOldest(n int) { if n > t.len() { panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len())) } - for k := 0; k < n; k++ { - f := t.ents[k] - id := t.evictCount + uint64(k) + 1 - if t.byName[f.Name] == id { - delete(t.byName, f.Name) - } - if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id { - delete(t.byNameValue, p) + if t.byName != nil { + for k := 0; k < n; k++ { + f := t.ents[k] + id := t.evictCount + uint64(k) + 1 + if t.byName[f.Name] == id { + delete(t.byName, f.Name) + } + if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id { + delete(t.byNameValue, p) + } } } copy(t.ents, t.ents[n:]) @@ -100,6 +120,9 @@ func (t *headerFieldTable) evictOldest(n int) { // // See Section 2.3.3. func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) { + if t.byName == nil { + t.buildMaps() + } if !f.Sensitive { if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 { return t.idToIndex(id), true diff --git a/vendor/golang.org/x/net/http2/transport_wrap.go b/vendor/golang.org/x/net/http2/transport_wrap.go index 534e77ab963..741fb97062e 100644 --- a/vendor/golang.org/x/net/http2/transport_wrap.go +++ b/vendor/golang.org/x/net/http2/transport_wrap.go @@ -237,32 +237,40 @@ type ClientConn struct { } func (cc *ClientConn) roundTrip(req *http.Request) (*http.Response, error) { - err := func() error { + haveReservation, err := func() (bool, error) { cc.mu.Lock() defer cc.mu.Unlock() if cc.doNotReuse { - return errClientConnUnusable - } - cc.roundTrips++ - if cc.reserved > 0 { - // We've already reserved a concurrency slot for this request. - cc.reserved-- - } else if cc.cc.Reserve() != nil { - // We don't seem to have an available concurrency slot, - // so bump the pending count (requests waiting for a slot). - cc.pending++ + return false, errClientConnUnusable } + // ClientConn.Shutdown will not shut down the conn while // cc.starting > 0 or cc.cc.InFlight() > 0. // // The starting state covers the gap between us deciding to // start sending the request, and actually sending it. cc.starting++ - return nil + + cc.roundTrips++ + if cc.reserved == 0 { + // We do not have a concurrency slot reserved for this request. + return false, nil + } + cc.reserved-- + return true, nil }() if err != nil { return nil, err } + // If we have no reservation, try to acquire one. + // (This must be done without cc.mu held, since Reserve may call back to the state hook.) + if !haveReservation && cc.cc.Reserve() != nil { + // We could not acquire a concurrency slot, so bump the pending count + // (requests waiting for a slot). + cc.mu.Lock() + cc.pending++ + cc.mu.Unlock() + } resp, err := cc.cc.RoundTrip(req) cc.mu.Lock() cc.starting-- @@ -293,16 +301,21 @@ func (cc *ClientConn) ping(ctx context.Context) error { } func (cc *ClientConn) reserveNewRequest() bool { + if err := cc.cc.Reserve(); err != nil { + return false + } + reserved := true cc.mu.Lock() - defer cc.mu.Unlock() if cc.doNotReuse { - return false + reserved = false + } else { + cc.reserved++ } - if err := cc.cc.Reserve(); err != nil { - return false + cc.mu.Unlock() + if !reserved { + cc.cc.Release() } - cc.reserved++ - return true + return reserved } func (cc *ClientConn) setDoNotReuse() { diff --git a/vendor/golang.org/x/text/currency/common.go b/vendor/golang.org/x/text/currency/common.go new file mode 100644 index 00000000000..fef15be5545 --- /dev/null +++ b/vendor/golang.org/x/text/currency/common.go @@ -0,0 +1,67 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package currency + +import ( + "time" + + "golang.org/x/text/language" +) + +// This file contains code common to gen.go and the package code. + +const ( + cashShift = 3 + roundMask = 0x7 + + nonTenderBit = 0x8000 +) + +// currencyInfo contains information about a currency. +// bits 0..2: index into roundings for standard rounding +// bits 3..5: index into roundings for cash rounding +type currencyInfo byte + +// roundingType defines the scale (number of fractional decimals) and increments +// in terms of units of size 10^-scale. For example, for scale == 2 and +// increment == 1, the currency is rounded to units of 0.01. +type roundingType struct { + scale, increment uint8 +} + +// roundings contains rounding data for currencies. This struct is +// created by hand as it is very unlikely to change much. +var roundings = [...]roundingType{ + {2, 1}, // default + {0, 1}, + {1, 1}, + {3, 1}, + {4, 1}, + {2, 5}, // cash rounding alternative + {2, 50}, +} + +// regionToCode returns a 16-bit region code. Only two-letter codes are +// supported. (Three-letter codes are not needed.) +func regionToCode(r language.Region) uint16 { + if s := r.String(); len(s) == 2 { + return uint16(s[0])<<8 | uint16(s[1]) + } + return 0 +} + +func toDate(t time.Time) uint32 { + y := t.Year() + if y == 1 { + return 0 + } + date := uint32(y) << 4 + date |= uint32(t.Month()) + date <<= 5 + date |= uint32(t.Day()) + return date +} + +func fromDate(date uint32) time.Time { + return time.Date(int(date>>9), time.Month((date>>5)&0xf), int(date&0x1f), 0, 0, 0, 0, time.UTC) +} diff --git a/vendor/golang.org/x/text/currency/currency.go b/vendor/golang.org/x/text/currency/currency.go new file mode 100644 index 00000000000..598ddeff420 --- /dev/null +++ b/vendor/golang.org/x/text/currency/currency.go @@ -0,0 +1,185 @@ +// 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 gen_common.go -output tables.go + +// Package currency contains currency-related functionality. +// +// NOTE: the formatting functionality is currently under development and may +// change without notice. +package currency // import "golang.org/x/text/currency" + +import ( + "errors" + "sort" + + "golang.org/x/text/internal/tag" + "golang.org/x/text/language" +) + +// TODO: +// - language-specific currency names. +// - currency formatting. +// - currency information per region +// - register currency code (there are no private use area) + +// TODO: remove Currency type from package language. + +// Kind determines the rounding and rendering properties of a currency value. +type Kind struct { + rounding rounding + // TODO: formatting type: standard, accounting. See CLDR. +} + +type rounding byte + +const ( + standard rounding = iota + cash +) + +var ( + // Standard defines standard rounding and formatting for currencies. + Standard Kind = Kind{rounding: standard} + + // Cash defines rounding and formatting standards for cash transactions. + Cash Kind = Kind{rounding: cash} + + // Accounting defines rounding and formatting standards for accounting. + Accounting Kind = Kind{rounding: standard} +) + +// Rounding reports the rounding characteristics for the given currency, where +// scale is the number of fractional decimals and increment is the number of +// units in terms of 10^(-scale) to which to round to. +func (k Kind) Rounding(cur Unit) (scale, increment int) { + info := currency.Elem(int(cur.index))[3] + switch k.rounding { + case standard: + info &= roundMask + case cash: + info >>= cashShift + } + return int(roundings[info].scale), int(roundings[info].increment) +} + +// Unit is an ISO 4217 currency designator. +type Unit struct { + index uint16 +} + +// String returns the ISO code of u. +func (u Unit) String() string { + if u.index == 0 { + return "XXX" + } + return currency.Elem(int(u.index))[:3] +} + +// Amount creates an Amount for the given currency unit and amount. +func (u Unit) Amount(amount interface{}) Amount { + // TODO: verify amount is a supported number type + return Amount{amount: amount, currency: u} +} + +var ( + errSyntax = errors.New("currency: tag is not well-formed") + errValue = errors.New("currency: tag is not a recognized currency") +) + +// ParseISO parses a 3-letter ISO 4217 currency code. It returns an error if s +// is not well-formed or not a recognized currency code. +func ParseISO(s string) (Unit, error) { + var buf [4]byte // Take one byte more to detect oversize keys. + key := buf[:copy(buf[:], s)] + if !tag.FixCase("XXX", key) { + return Unit{}, errSyntax + } + if i := currency.Index(key); i >= 0 { + if i == xxx { + return Unit{}, nil + } + return Unit{uint16(i)}, nil + } + return Unit{}, errValue +} + +// MustParseISO is like ParseISO, but panics if the given currency unit +// cannot be parsed. It simplifies safe initialization of Unit values. +func MustParseISO(s string) Unit { + c, err := ParseISO(s) + if err != nil { + panic(err) + } + return c +} + +// FromRegion reports the currency unit that is currently legal tender in the +// given region according to CLDR. It will return false if region currently does +// not have a legal tender. +func FromRegion(r language.Region) (currency Unit, ok bool) { + x := regionToCode(r) + i := sort.Search(len(regionToCurrency), func(i int) bool { + return regionToCurrency[i].region >= x + }) + if i < len(regionToCurrency) && regionToCurrency[i].region == x { + return Unit{regionToCurrency[i].code}, true + } + return Unit{}, false +} + +// FromTag reports the most likely currency for the given tag. It considers the +// currency defined in the -u extension and infers the region if necessary. +func FromTag(t language.Tag) (Unit, language.Confidence) { + if cur := t.TypeForKey("cu"); len(cur) == 3 { + c, _ := ParseISO(cur) + return c, language.Exact + } + r, conf := t.Region() + if cur, ok := FromRegion(r); ok { + return cur, conf + } + return Unit{}, language.No +} + +var ( + // Undefined and testing. + XXX Unit = Unit{} + XTS Unit = Unit{xts} + + // G10 currencies https://en.wikipedia.org/wiki/G10_currencies. + USD Unit = Unit{usd} + EUR Unit = Unit{eur} + JPY Unit = Unit{jpy} + GBP Unit = Unit{gbp} + CHF Unit = Unit{chf} + AUD Unit = Unit{aud} + NZD Unit = Unit{nzd} + CAD Unit = Unit{cad} + SEK Unit = Unit{sek} + NOK Unit = Unit{nok} + + // Additional common currencies as defined by CLDR. + BRL Unit = Unit{brl} + CNY Unit = Unit{cny} + DKK Unit = Unit{dkk} + INR Unit = Unit{inr} + RUB Unit = Unit{rub} + HKD Unit = Unit{hkd} + IDR Unit = Unit{idr} + KRW Unit = Unit{krw} + MXN Unit = Unit{mxn} + PLN Unit = Unit{pln} + SAR Unit = Unit{sar} + THB Unit = Unit{thb} + TRY Unit = Unit{try} + TWD Unit = Unit{twd} + ZAR Unit = Unit{zar} + + // Precious metals. + XAG Unit = Unit{xag} + XAU Unit = Unit{xau} + XPT Unit = Unit{xpt} + XPD Unit = Unit{xpd} +) diff --git a/vendor/golang.org/x/text/currency/format.go b/vendor/golang.org/x/text/currency/format.go new file mode 100644 index 00000000000..cc4570d3b68 --- /dev/null +++ b/vendor/golang.org/x/text/currency/format.go @@ -0,0 +1,220 @@ +// 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 currency + +import ( + "fmt" + "sort" + + "golang.org/x/text/internal/format" + "golang.org/x/text/internal/language/compact" + "golang.org/x/text/internal/number" + + "golang.org/x/text/language" +) + +// Amount is an amount-currency unit pair. +type Amount struct { + amount interface{} // Change to decimal(64|128). + currency Unit +} + +// Currency reports the currency unit of this amount. +func (a Amount) Currency() Unit { return a.currency } + +// TODO: based on decimal type, but may make sense to customize a bit. +// func (a Amount) Decimal() +// func (a Amount) Int() (int64, error) +// func (a Amount) Fraction() (int64, error) +// func (a Amount) Rat() *big.Rat +// func (a Amount) Float() (float64, error) +// func (a Amount) Scale() uint +// func (a Amount) Precision() uint +// func (a Amount) Sign() int +// +// Add/Sub/Div/Mul/Round. + +// Format implements fmt.Formatter. It accepts format.State for +// language-specific rendering. +func (a Amount) Format(s fmt.State, verb rune) { + v := formattedValue{ + currency: a.currency, + amount: a.amount, + format: defaultFormat, + } + v.Format(s, verb) +} + +// formattedValue is currency amount or unit that implements language-sensitive +// formatting. +type formattedValue struct { + currency Unit + amount interface{} // Amount, Unit, or number. + format *options +} + +// Format implements fmt.Formatter. It accepts format.State for +// language-specific rendering. +func (v formattedValue) Format(s fmt.State, verb rune) { + var tag language.Tag + var lang compact.ID + if state, ok := s.(format.State); ok { + tag = state.Language() + lang, _ = compact.RegionalID(compact.Tag(tag)) + } + + // Get the options. Use DefaultFormat if not present. + opt := v.format + if opt == nil { + opt = defaultFormat + } + cur := v.currency + if cur.index == 0 { + cur = opt.currency + } + + sym := opt.symbol(lang, cur) + if v.amount != nil { + var f number.Formatter + f.InitDecimal(tag) + + scale, increment := opt.kind.Rounding(cur) + f.RoundingContext.SetScale(scale) + f.RoundingContext.Increment = uint32(increment) + f.RoundingContext.IncrementScale = uint8(scale) + f.RoundingContext.Mode = number.ToNearestAway + + d := f.Append(nil, v.amount) + + fmt.Fprint(s, sym, " ", string(d)) + } else { + fmt.Fprint(s, sym) + } +} + +// Formatter decorates a given number, Unit or Amount with formatting options. +type Formatter func(amount interface{}) formattedValue + +// func (f Formatter) Options(opts ...Option) Formatter + +// TODO: call this a Formatter or FormatFunc? + +var dummy = USD.Amount(0) + +// adjust creates a new Formatter based on the adjustments of fn on f. +func (f Formatter) adjust(fn func(*options)) Formatter { + var o options = *(f(dummy).format) + fn(&o) + return o.format +} + +// Default creates a new Formatter that defaults to currency unit c if a numeric +// value is passed that is not associated with a currency. +func (f Formatter) Default(currency Unit) Formatter { + return f.adjust(func(o *options) { o.currency = currency }) +} + +// Kind sets the kind of the underlying currency unit. +func (f Formatter) Kind(k Kind) Formatter { + return f.adjust(func(o *options) { o.kind = k }) +} + +var defaultFormat *options = ISO(dummy).format + +var ( + // Uses Narrow symbols. Overrides Symbol, if present. + NarrowSymbol Formatter = Formatter(formNarrow) + + // Use Symbols instead of ISO codes, when available. + Symbol Formatter = Formatter(formSymbol) + + // Use ISO code as symbol. + ISO Formatter = Formatter(formISO) + + // TODO: + // // Use full name as symbol. + // Name Formatter +) + +// options configures rendering and rounding options for an Amount. +type options struct { + currency Unit + kind Kind + + symbol func(compactIndex compact.ID, c Unit) string +} + +func (o *options) format(amount interface{}) formattedValue { + v := formattedValue{format: o} + switch x := amount.(type) { + case Amount: + v.amount = x.amount + v.currency = x.currency + case *Amount: + v.amount = x.amount + v.currency = x.currency + case Unit: + v.currency = x + case *Unit: + v.currency = *x + default: + if o.currency.index == 0 { + panic("cannot format number without a currency being set") + } + // TODO: Must be a number. + v.amount = x + v.currency = o.currency + } + return v +} + +var ( + optISO = options{symbol: lookupISO} + optSymbol = options{symbol: lookupSymbol} + optNarrow = options{symbol: lookupNarrow} +) + +// These need to be functions, rather than curried methods, as curried methods +// are evaluated at init time, causing tables to be included unconditionally. +func formISO(x interface{}) formattedValue { return optISO.format(x) } +func formSymbol(x interface{}) formattedValue { return optSymbol.format(x) } +func formNarrow(x interface{}) formattedValue { return optNarrow.format(x) } + +func lookupISO(x compact.ID, c Unit) string { return c.String() } +func lookupSymbol(x compact.ID, c Unit) string { return normalSymbol.lookup(x, c) } +func lookupNarrow(x compact.ID, c Unit) string { return narrowSymbol.lookup(x, c) } + +type symbolIndex struct { + index []uint16 // position corresponds with compact index of language. + data []curToIndex +} + +var ( + normalSymbol = symbolIndex{normalLangIndex, normalSymIndex} + narrowSymbol = symbolIndex{narrowLangIndex, narrowSymIndex} +) + +func (x *symbolIndex) lookup(lang compact.ID, c Unit) string { + for { + index := x.data[x.index[lang]:x.index[lang+1]] + i := sort.Search(len(index), func(i int) bool { + return index[i].cur >= c.index + }) + if i < len(index) && index[i].cur == c.index { + x := index[i].idx + start := x + 1 + end := start + uint16(symbols[x]) + if start == end { + return c.String() + } + return symbols[start:end] + } + if lang == 0 { + break + } + lang = lang.Parent() + } + return c.String() +} diff --git a/vendor/golang.org/x/text/currency/query.go b/vendor/golang.org/x/text/currency/query.go new file mode 100644 index 00000000000..7bf9430a62c --- /dev/null +++ b/vendor/golang.org/x/text/currency/query.go @@ -0,0 +1,152 @@ +// Copyright 2016 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 currency + +import ( + "sort" + "time" + + "golang.org/x/text/language" +) + +// QueryIter represents a set of Units. The default set includes all Units that +// are currently in use as legal tender in any Region. +type QueryIter interface { + // Next returns true if there is a next element available. + // It must be called before any of the other methods are called. + Next() bool + + // Unit returns the unit of the current iteration. + Unit() Unit + + // Region returns the Region for the current iteration. + Region() language.Region + + // From returns the date from which the unit was used in the region. + // It returns false if this date is unknown. + From() (time.Time, bool) + + // To returns the date up till which the unit was used in the region. + // It returns false if this date is unknown or if the unit is still in use. + To() (time.Time, bool) + + // IsTender reports whether the unit is a legal tender in the region during + // the specified date range. + IsTender() bool +} + +// Query represents a set of Units. The default set includes all Units that are +// currently in use as legal tender in any Region. +func Query(options ...QueryOption) QueryIter { + it := &iter{ + end: len(regionData), + date: 0xFFFFFFFF, + } + for _, fn := range options { + fn(it) + } + return it +} + +// NonTender returns a new query that also includes matching Units that are not +// legal tender. +var NonTender QueryOption = nonTender + +func nonTender(i *iter) { + i.nonTender = true +} + +// Historical selects the units for all dates. +var Historical QueryOption = historical + +func historical(i *iter) { + i.date = hist +} + +// A QueryOption can be used to change the set of unit information returned by +// a query. +type QueryOption func(*iter) + +// Date queries the units that were in use at the given point in history. +func Date(t time.Time) QueryOption { + d := toDate(t) + return func(i *iter) { + i.date = d + } +} + +// Region limits the query to only return entries for the given region. +func Region(r language.Region) QueryOption { + p, end := len(regionData), len(regionData) + x := regionToCode(r) + i := sort.Search(len(regionData), func(i int) bool { + return regionData[i].region >= x + }) + if i < len(regionData) && regionData[i].region == x { + p = i + for i++; i < len(regionData) && regionData[i].region == x; i++ { + } + end = i + } + return func(i *iter) { + i.p, i.end = p, end + } +} + +const ( + hist = 0x00 + now = 0xFFFFFFFF +) + +type iter struct { + *regionInfo + p, end int + date uint32 + nonTender bool +} + +func (i *iter) Next() bool { + for ; i.p < i.end; i.p++ { + i.regionInfo = ®ionData[i.p] + if !i.nonTender && !i.IsTender() { + continue + } + if i.date == hist || (i.from <= i.date && (i.to == 0 || i.date <= i.to)) { + i.p++ + return true + } + } + return false +} + +func (r *regionInfo) Region() language.Region { + // TODO: this could be much faster. + var buf [2]byte + buf[0] = uint8(r.region >> 8) + buf[1] = uint8(r.region) + return language.MustParseRegion(string(buf[:])) +} + +func (r *regionInfo) Unit() Unit { + return Unit{r.code &^ nonTenderBit} +} + +func (r *regionInfo) IsTender() bool { + return r.code&nonTenderBit == 0 +} + +func (r *regionInfo) From() (time.Time, bool) { + if r.from == 0 { + return time.Time{}, false + } + return fromDate(r.from), true +} + +func (r *regionInfo) To() (time.Time, bool) { + if r.to == 0 { + return time.Time{}, false + } + return fromDate(r.to), true +} diff --git a/vendor/golang.org/x/text/currency/tables.go b/vendor/golang.org/x/text/currency/tables.go new file mode 100644 index 00000000000..d1a7440a6bd --- /dev/null +++ b/vendor/golang.org/x/text/currency/tables.go @@ -0,0 +1,2629 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package currency + +import "golang.org/x/text/internal/tag" + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +const ( + xxx = 285 + xts = 283 + usd = 252 + eur = 94 + jpy = 133 + gbp = 99 + chf = 61 + aud = 19 + nzd = 192 + cad = 58 + sek = 219 + nok = 190 + dkk = 82 + xag = 266 + xau = 267 + xpt = 280 + xpd = 278 + brl = 46 + cny = 68 + inr = 125 + rub = 210 + hkd = 114 + idr = 120 + krw = 141 + mxn = 178 + pln = 201 + sar = 213 + thb = 235 + try = 244 + twd = 246 + zar = 293 +) + +// currency holds an alphabetically sorted list of canonical 3-letter currency +// identifiers. Each identifier is followed by a byte of type currencyInfo, +// defined in gen_common.go. +const currency tag.Index = "" + // Size: 1208 bytes + "\x00\x00\x00\x00ADP\x09AED\x00AFA\x00AFN\x09ALK\x00ALL\x09AMD\x09ANG\x00" + + "AOA\x00AOK\x00AON\x00AOR\x00ARA\x00ARL\x00ARM\x00ARP\x00ARS\x00ATS\x00AU" + + "D\x00AWG\x00AZM\x00AZN\x00BAD\x00BAM\x00BAN\x00BBD\x00BDT\x00BEC\x00BEF" + + "\x00BEL\x00BGL\x00BGM\x00BGN\x00BGO\x00BHD\x1bBIF\x09BMD\x00BND\x00BOB" + + "\x00BOL\x00BOP\x00BOV\x00BRB\x00BRC\x00BRE\x00BRL\x00BRN\x00BRR\x00BRZ" + + "\x00BSD\x00BTN\x00BUK\x00BWP\x00BYB\x00BYN\x00BYR\x09BZD\x00CAD(CDF\x00C" + + "HE\x00CHF(CHW\x00CLE\x00CLF$CLP\x09CNH\x00CNX\x00CNY\x00COP\x09COU\x00CR" + + "C\x08CSD\x00CSK\x00CUC\x00CUP\x00CVE\x00CYP\x00CZK\x08DDM\x00DEM\x00DJF" + + "\x09DKK0DOP\x00DZD\x00ECS\x00ECV\x00EEK\x00EGP\x00ERN\x00ESA\x00ESB\x00E" + + "SP\x09ETB\x00EUR\x00FIM\x00FJD\x00FKP\x00FRF\x00GBP\x00GEK\x00GEL\x00GHC" + + "\x00GHS\x00GIP\x00GMD\x00GNF\x09GNS\x00GQE\x00GRD\x00GTQ\x00GWE\x00GWP" + + "\x00GYD\x09HKD\x00HNL\x00HRD\x00HRK\x00HTG\x00HUF\x08IDR\x09IEP\x00ILP" + + "\x00ILR\x00ILS\x00INR\x00IQD\x09IRR\x09ISJ\x00ISK\x09ITL\x09JMD\x00JOD" + + "\x1bJPY\x09KES\x00KGS\x00KHR\x00KMF\x09KPW\x09KRH\x00KRO\x00KRW\x09KWD" + + "\x1bKYD\x00KZT\x00LAK\x09LBP\x09LKR\x00LRD\x00LSL\x00LTL\x00LTT\x00LUC" + + "\x00LUF\x09LUL\x00LVL\x00LVR\x00LYD\x1bMAD\x00MAF\x00MCF\x00MDC\x00MDL" + + "\x00MGA\x09MGF\x09MKD\x00MKN\x00MLF\x00MMK\x09MNT\x09MOP\x00MRO\x09MTL" + + "\x00MTP\x00MUR\x09MVP\x00MVR\x00MWK\x00MXN\x00MXP\x00MXV\x00MYR\x00MZE" + + "\x00MZM\x00MZN\x00NAD\x00NGN\x00NIC\x00NIO\x00NLG\x00NOK\x08NPR\x00NZD" + + "\x00OMR\x1bPAB\x00PEI\x00PEN\x00PES\x00PGK\x00PHP\x00PKR\x09PLN\x00PLZ" + + "\x00PTE\x00PYG\x09QAR\x00RHD\x00ROL\x00RON\x00RSD\x09RUB\x00RUR\x00RWF" + + "\x09SAR\x00SBD\x00SCR\x00SDD\x00SDG\x00SDP\x00SEK\x08SGD\x00SHP\x00SIT" + + "\x00SKK\x00SLL\x09SOS\x09SRD\x00SRG\x00SSP\x00STD\x09STN\x00SUR\x00SVC" + + "\x00SYP\x09SZL\x00THB\x00TJR\x00TJS\x00TMM\x09TMT\x00TND\x1bTOP\x00TPE" + + "\x00TRL\x09TRY\x00TTD\x00TWD\x08TZS\x09UAH\x00UAK\x00UGS\x00UGX\x09USD" + + "\x00USN\x00USS\x00UYI\x09UYP\x00UYU\x00UZS\x09VEB\x00VEF\x00VND\x09VNN" + + "\x00VUV\x09WST\x00XAF\x09XAG\x00XAU\x00XBA\x00XBB\x00XBC\x00XBD\x00XCD" + + "\x00XDR\x00XEU\x00XFO\x00XFU\x00XOF\x09XPD\x00XPF\x09XPT\x00XRE\x00XSU" + + "\x00XTS\x00XUA\x00XXX\x00YDD\x00YER\x09YUD\x00YUM\x00YUN\x00YUR\x00ZAL" + + "\x00ZAR\x00ZMK\x09ZMW\x00ZRN\x00ZRZ\x00ZWD\x09ZWL\x00ZWR\x00\xff\xff\xff" + + "\xff" + +const numCurrencies = 300 + +type toCurrency struct { + region uint16 + code uint16 +} + +var regionToCurrency = []toCurrency{ // 255 elements + 0: {region: 0x4143, code: 0xdd}, + 1: {region: 0x4144, code: 0x5e}, + 2: {region: 0x4145, code: 0x2}, + 3: {region: 0x4146, code: 0x4}, + 4: {region: 0x4147, code: 0x110}, + 5: {region: 0x4149, code: 0x110}, + 6: {region: 0x414c, code: 0x6}, + 7: {region: 0x414d, code: 0x7}, + 8: {region: 0x414f, code: 0x9}, + 9: {region: 0x4152, code: 0x11}, + 10: {region: 0x4153, code: 0xfc}, + 11: {region: 0x4154, code: 0x5e}, + 12: {region: 0x4155, code: 0x13}, + 13: {region: 0x4157, code: 0x14}, + 14: {region: 0x4158, code: 0x5e}, + 15: {region: 0x415a, code: 0x16}, + 16: {region: 0x4241, code: 0x18}, + 17: {region: 0x4242, code: 0x1a}, + 18: {region: 0x4244, code: 0x1b}, + 19: {region: 0x4245, code: 0x5e}, + 20: {region: 0x4246, code: 0x115}, + 21: {region: 0x4247, code: 0x21}, + 22: {region: 0x4248, code: 0x23}, + 23: {region: 0x4249, code: 0x24}, + 24: {region: 0x424a, code: 0x115}, + 25: {region: 0x424c, code: 0x5e}, + 26: {region: 0x424d, code: 0x25}, + 27: {region: 0x424e, code: 0x26}, + 28: {region: 0x424f, code: 0x27}, + 29: {region: 0x4251, code: 0xfc}, + 30: {region: 0x4252, code: 0x2e}, + 31: {region: 0x4253, code: 0x32}, + 32: {region: 0x4254, code: 0x33}, + 33: {region: 0x4256, code: 0xbe}, + 34: {region: 0x4257, code: 0x35}, + 35: {region: 0x4259, code: 0x37}, + 36: {region: 0x425a, code: 0x39}, + 37: {region: 0x4341, code: 0x3a}, + 38: {region: 0x4343, code: 0x13}, + 39: {region: 0x4344, code: 0x3b}, + 40: {region: 0x4346, code: 0x109}, + 41: {region: 0x4347, code: 0x109}, + 42: {region: 0x4348, code: 0x3d}, + 43: {region: 0x4349, code: 0x115}, + 44: {region: 0x434b, code: 0xc0}, + 45: {region: 0x434c, code: 0x41}, + 46: {region: 0x434d, code: 0x109}, + 47: {region: 0x434e, code: 0x44}, + 48: {region: 0x434f, code: 0x45}, + 49: {region: 0x4352, code: 0x47}, + 50: {region: 0x4355, code: 0x4b}, + 51: {region: 0x4356, code: 0x4c}, + 52: {region: 0x4357, code: 0x8}, + 53: {region: 0x4358, code: 0x13}, + 54: {region: 0x4359, code: 0x5e}, + 55: {region: 0x435a, code: 0x4e}, + 56: {region: 0x4445, code: 0x5e}, + 57: {region: 0x4447, code: 0xfc}, + 58: {region: 0x444a, code: 0x51}, + 59: {region: 0x444b, code: 0x52}, + 60: {region: 0x444d, code: 0x110}, + 61: {region: 0x444f, code: 0x53}, + 62: {region: 0x445a, code: 0x54}, + 63: {region: 0x4541, code: 0x5e}, + 64: {region: 0x4543, code: 0xfc}, + 65: {region: 0x4545, code: 0x5e}, + 66: {region: 0x4547, code: 0x58}, + 67: {region: 0x4548, code: 0x9e}, + 68: {region: 0x4552, code: 0x59}, + 69: {region: 0x4553, code: 0x5e}, + 70: {region: 0x4554, code: 0x5d}, + 71: {region: 0x4555, code: 0x5e}, + 72: {region: 0x4649, code: 0x5e}, + 73: {region: 0x464a, code: 0x60}, + 74: {region: 0x464b, code: 0x61}, + 75: {region: 0x464d, code: 0xfc}, + 76: {region: 0x464f, code: 0x52}, + 77: {region: 0x4652, code: 0x5e}, + 78: {region: 0x4741, code: 0x109}, + 79: {region: 0x4742, code: 0x63}, + 80: {region: 0x4744, code: 0x110}, + 81: {region: 0x4745, code: 0x65}, + 82: {region: 0x4746, code: 0x5e}, + 83: {region: 0x4747, code: 0x63}, + 84: {region: 0x4748, code: 0x67}, + 85: {region: 0x4749, code: 0x68}, + 86: {region: 0x474c, code: 0x52}, + 87: {region: 0x474d, code: 0x69}, + 88: {region: 0x474e, code: 0x6a}, + 89: {region: 0x4750, code: 0x5e}, + 90: {region: 0x4751, code: 0x109}, + 91: {region: 0x4752, code: 0x5e}, + 92: {region: 0x4753, code: 0x63}, + 93: {region: 0x4754, code: 0x6e}, + 94: {region: 0x4755, code: 0xfc}, + 95: {region: 0x4757, code: 0x115}, + 96: {region: 0x4759, code: 0x71}, + 97: {region: 0x484b, code: 0x72}, + 98: {region: 0x484d, code: 0x13}, + 99: {region: 0x484e, code: 0x73}, + 100: {region: 0x4852, code: 0x75}, + 101: {region: 0x4854, code: 0x76}, + 102: {region: 0x4855, code: 0x77}, + 103: {region: 0x4943, code: 0x5e}, + 104: {region: 0x4944, code: 0x78}, + 105: {region: 0x4945, code: 0x5e}, + 106: {region: 0x494c, code: 0x7c}, + 107: {region: 0x494d, code: 0x63}, + 108: {region: 0x494e, code: 0x7d}, + 109: {region: 0x494f, code: 0xfc}, + 110: {region: 0x4951, code: 0x7e}, + 111: {region: 0x4952, code: 0x7f}, + 112: {region: 0x4953, code: 0x81}, + 113: {region: 0x4954, code: 0x5e}, + 114: {region: 0x4a45, code: 0x63}, + 115: {region: 0x4a4d, code: 0x83}, + 116: {region: 0x4a4f, code: 0x84}, + 117: {region: 0x4a50, code: 0x85}, + 118: {region: 0x4b45, code: 0x86}, + 119: {region: 0x4b47, code: 0x87}, + 120: {region: 0x4b48, code: 0x88}, + 121: {region: 0x4b49, code: 0x13}, + 122: {region: 0x4b4d, code: 0x89}, + 123: {region: 0x4b4e, code: 0x110}, + 124: {region: 0x4b50, code: 0x8a}, + 125: {region: 0x4b52, code: 0x8d}, + 126: {region: 0x4b57, code: 0x8e}, + 127: {region: 0x4b59, code: 0x8f}, + 128: {region: 0x4b5a, code: 0x90}, + 129: {region: 0x4c41, code: 0x91}, + 130: {region: 0x4c42, code: 0x92}, + 131: {region: 0x4c43, code: 0x110}, + 132: {region: 0x4c49, code: 0x3d}, + 133: {region: 0x4c4b, code: 0x93}, + 134: {region: 0x4c52, code: 0x94}, + 135: {region: 0x4c53, code: 0x125}, + 136: {region: 0x4c54, code: 0x5e}, + 137: {region: 0x4c55, code: 0x5e}, + 138: {region: 0x4c56, code: 0x5e}, + 139: {region: 0x4c59, code: 0x9d}, + 140: {region: 0x4d41, code: 0x9e}, + 141: {region: 0x4d43, code: 0x5e}, + 142: {region: 0x4d44, code: 0xa2}, + 143: {region: 0x4d45, code: 0x5e}, + 144: {region: 0x4d46, code: 0x5e}, + 145: {region: 0x4d47, code: 0xa3}, + 146: {region: 0x4d48, code: 0xfc}, + 147: {region: 0x4d4b, code: 0xa5}, + 148: {region: 0x4d4c, code: 0x115}, + 149: {region: 0x4d4d, code: 0xa8}, + 150: {region: 0x4d4e, code: 0xa9}, + 151: {region: 0x4d4f, code: 0xaa}, + 152: {region: 0x4d50, code: 0xfc}, + 153: {region: 0x4d51, code: 0x5e}, + 154: {region: 0x4d52, code: 0xab}, + 155: {region: 0x4d53, code: 0x110}, + 156: {region: 0x4d54, code: 0x5e}, + 157: {region: 0x4d55, code: 0xae}, + 158: {region: 0x4d56, code: 0xb0}, + 159: {region: 0x4d57, code: 0xb1}, + 160: {region: 0x4d58, code: 0xb2}, + 161: {region: 0x4d59, code: 0xb5}, + 162: {region: 0x4d5a, code: 0xb8}, + 163: {region: 0x4e41, code: 0xb9}, + 164: {region: 0x4e43, code: 0x117}, + 165: {region: 0x4e45, code: 0x115}, + 166: {region: 0x4e46, code: 0x13}, + 167: {region: 0x4e47, code: 0xba}, + 168: {region: 0x4e49, code: 0xbc}, + 169: {region: 0x4e4c, code: 0x5e}, + 170: {region: 0x4e4f, code: 0xbe}, + 171: {region: 0x4e50, code: 0xbf}, + 172: {region: 0x4e52, code: 0x13}, + 173: {region: 0x4e55, code: 0xc0}, + 174: {region: 0x4e5a, code: 0xc0}, + 175: {region: 0x4f4d, code: 0xc1}, + 176: {region: 0x5041, code: 0xc2}, + 177: {region: 0x5045, code: 0xc4}, + 178: {region: 0x5046, code: 0x117}, + 179: {region: 0x5047, code: 0xc6}, + 180: {region: 0x5048, code: 0xc7}, + 181: {region: 0x504b, code: 0xc8}, + 182: {region: 0x504c, code: 0xc9}, + 183: {region: 0x504d, code: 0x5e}, + 184: {region: 0x504e, code: 0xc0}, + 185: {region: 0x5052, code: 0xfc}, + 186: {region: 0x5053, code: 0x7c}, + 187: {region: 0x5054, code: 0x5e}, + 188: {region: 0x5057, code: 0xfc}, + 189: {region: 0x5059, code: 0xcc}, + 190: {region: 0x5141, code: 0xcd}, + 191: {region: 0x5245, code: 0x5e}, + 192: {region: 0x524f, code: 0xd0}, + 193: {region: 0x5253, code: 0xd1}, + 194: {region: 0x5255, code: 0xd2}, + 195: {region: 0x5257, code: 0xd4}, + 196: {region: 0x5341, code: 0xd5}, + 197: {region: 0x5342, code: 0xd6}, + 198: {region: 0x5343, code: 0xd7}, + 199: {region: 0x5344, code: 0xd9}, + 200: {region: 0x5345, code: 0xdb}, + 201: {region: 0x5347, code: 0xdc}, + 202: {region: 0x5348, code: 0xdd}, + 203: {region: 0x5349, code: 0x5e}, + 204: {region: 0x534a, code: 0xbe}, + 205: {region: 0x534b, code: 0x5e}, + 206: {region: 0x534c, code: 0xe0}, + 207: {region: 0x534d, code: 0x5e}, + 208: {region: 0x534e, code: 0x115}, + 209: {region: 0x534f, code: 0xe1}, + 210: {region: 0x5352, code: 0xe2}, + 211: {region: 0x5353, code: 0xe4}, + 212: {region: 0x5354, code: 0xe6}, + 213: {region: 0x5356, code: 0xfc}, + 214: {region: 0x5358, code: 0x8}, + 215: {region: 0x5359, code: 0xe9}, + 216: {region: 0x535a, code: 0xea}, + 217: {region: 0x5441, code: 0x63}, + 218: {region: 0x5443, code: 0xfc}, + 219: {region: 0x5444, code: 0x109}, + 220: {region: 0x5446, code: 0x5e}, + 221: {region: 0x5447, code: 0x115}, + 222: {region: 0x5448, code: 0xeb}, + 223: {region: 0x544a, code: 0xed}, + 224: {region: 0x544b, code: 0xc0}, + 225: {region: 0x544c, code: 0xfc}, + 226: {region: 0x544d, code: 0xef}, + 227: {region: 0x544e, code: 0xf0}, + 228: {region: 0x544f, code: 0xf1}, + 229: {region: 0x5452, code: 0xf4}, + 230: {region: 0x5454, code: 0xf5}, + 231: {region: 0x5456, code: 0x13}, + 232: {region: 0x5457, code: 0xf6}, + 233: {region: 0x545a, code: 0xf7}, + 234: {region: 0x5541, code: 0xf8}, + 235: {region: 0x5547, code: 0xfb}, + 236: {region: 0x554d, code: 0xfc}, + 237: {region: 0x5553, code: 0xfc}, + 238: {region: 0x5559, code: 0x101}, + 239: {region: 0x555a, code: 0x102}, + 240: {region: 0x5641, code: 0x5e}, + 241: {region: 0x5643, code: 0x110}, + 242: {region: 0x5645, code: 0x104}, + 243: {region: 0x5647, code: 0xfc}, + 244: {region: 0x5649, code: 0xfc}, + 245: {region: 0x564e, code: 0x105}, + 246: {region: 0x5655, code: 0x107}, + 247: {region: 0x5746, code: 0x117}, + 248: {region: 0x5753, code: 0x108}, + 249: {region: 0x584b, code: 0x5e}, + 250: {region: 0x5945, code: 0x11f}, + 251: {region: 0x5954, code: 0x5e}, + 252: {region: 0x5a41, code: 0x125}, + 253: {region: 0x5a4d, code: 0x127}, + 254: {region: 0x5a57, code: 0xfc}, +} // Size: 1044 bytes + +type regionInfo struct { + region uint16 + code uint16 + from uint32 + to uint32 +} + +var regionData = []regionInfo{ // 495 elements + 0: {region: 0x4143, code: 0xdd, from: 0xf7021, to: 0x0}, + 1: {region: 0x4144, code: 0x5e, from: 0xf9e21, to: 0x0}, + 2: {region: 0x4144, code: 0x5c, from: 0xea221, to: 0xfa45c}, + 3: {region: 0x4144, code: 0x62, from: 0xf5021, to: 0xfa451}, + 4: {region: 0x4144, code: 0x1, from: 0xf2021, to: 0xfa39f}, + 5: {region: 0x4145, code: 0x2, from: 0xf6ab3, to: 0x0}, + 6: {region: 0x4146, code: 0x4, from: 0xfa547, to: 0x0}, + 7: {region: 0x4146, code: 0x3, from: 0xf0e6e, to: 0xfa59f}, + 8: {region: 0x4147, code: 0x110, from: 0xf5b46, to: 0x0}, + 9: {region: 0x4149, code: 0x110, from: 0xf5b46, to: 0x0}, + 10: {region: 0x414c, code: 0x6, from: 0xf5b10, to: 0x0}, + 11: {region: 0x414c, code: 0x5, from: 0xf3561, to: 0xf5b10}, + 12: {region: 0x414d, code: 0x7, from: 0xf9376, to: 0x0}, + 13: {region: 0x414d, code: 0xd3, from: 0xf8f99, to: 0xf9376}, + 14: {region: 0x414d, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 15: {region: 0x414f, code: 0x9, from: 0xf9f8d, to: 0x0}, + 16: {region: 0x414f, code: 0xc, from: 0xf96e1, to: 0xfa041}, + 17: {region: 0x414f, code: 0xb, from: 0xf8d39, to: 0xfa041}, + 18: {region: 0x414f, code: 0xa, from: 0xf7228, to: 0xf8e61}, + 19: {region: 0x4151, code: 0x811d, from: 0x0, to: 0x0}, + 20: {region: 0x4152, code: 0x11, from: 0xf9021, to: 0x0}, + 21: {region: 0x4152, code: 0xd, from: 0xf82ce, to: 0xf9021}, + 22: {region: 0x4152, code: 0x10, from: 0xf7ec1, to: 0xf82ce}, + 23: {region: 0x4152, code: 0xe, from: 0xf6421, to: 0xf7ec1}, + 24: {region: 0x4152, code: 0xf, from: 0xeb365, to: 0xf6421}, + 25: {region: 0x4153, code: 0xfc, from: 0xee0f0, to: 0x0}, + 26: {region: 0x4154, code: 0x5e, from: 0xf9e21, to: 0x0}, + 27: {region: 0x4154, code: 0x12, from: 0xf3784, to: 0xfa45c}, + 28: {region: 0x4155, code: 0x13, from: 0xf5c4e, to: 0x0}, + 29: {region: 0x4157, code: 0x14, from: 0xf8421, to: 0x0}, + 30: {region: 0x4157, code: 0x8, from: 0xf28aa, to: 0xf8421}, + 31: {region: 0x4158, code: 0x5e, from: 0xf9e21, to: 0x0}, + 32: {region: 0x415a, code: 0x16, from: 0xfac21, to: 0x0}, + 33: {region: 0x415a, code: 0x15, from: 0xf9376, to: 0xfad9f}, + 34: {region: 0x415a, code: 0xd3, from: 0xf8f99, to: 0xf9421}, + 35: {region: 0x415a, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 36: {region: 0x4241, code: 0x18, from: 0xf9621, to: 0x0}, + 37: {region: 0x4241, code: 0x19, from: 0xf950f, to: 0xf9ae1}, + 38: {region: 0x4241, code: 0x17, from: 0xf90e1, to: 0xf950f}, + 39: {region: 0x4241, code: 0x123, from: 0xf90e1, to: 0xf9341}, + 40: {region: 0x4241, code: 0x122, from: 0xf8c21, to: 0xf90e1}, + 41: {region: 0x4241, code: 0x120, from: 0xf5c21, to: 0xf8c21}, + 42: {region: 0x4242, code: 0x1a, from: 0xf6b83, to: 0x0}, + 43: {region: 0x4242, code: 0x110, from: 0xf5b46, to: 0xf6b83}, + 44: {region: 0x4244, code: 0x1b, from: 0xf6821, to: 0x0}, + 45: {region: 0x4244, code: 0xc8, from: 0xf3881, to: 0xf6821}, + 46: {region: 0x4244, code: 0x7d, from: 0xe5711, to: 0xf3881}, + 47: {region: 0x4245, code: 0x5e, from: 0xf9e21, to: 0x0}, + 48: {region: 0x4245, code: 0x1d, from: 0xe4e47, to: 0xfa45c}, + 49: {region: 0x4245, code: 0xbd, from: 0xe318f, to: 0xe4e47}, + 50: {region: 0x4245, code: 0x801e, from: 0xf6421, to: 0xf8c65}, + 51: {region: 0x4245, code: 0x801c, from: 0xf6421, to: 0xf8c65}, + 52: {region: 0x4246, code: 0x115, from: 0xf8104, to: 0x0}, + 53: {region: 0x4247, code: 0x21, from: 0xf9ee5, to: 0x0}, + 54: {region: 0x4247, code: 0x1f, from: 0xf5421, to: 0xf9ee5}, + 55: {region: 0x4247, code: 0x20, from: 0xf40ac, to: 0xf5421}, + 56: {region: 0x4247, code: 0x22, from: 0xeaee8, to: 0xf40ac}, + 57: {region: 0x4248, code: 0x23, from: 0xf5b50, to: 0x0}, + 58: {region: 0x4249, code: 0x24, from: 0xf58b3, to: 0x0}, + 59: {region: 0x424a, code: 0x115, from: 0xf6f7e, to: 0x0}, + 60: {region: 0x424c, code: 0x5e, from: 0xf9e21, to: 0x0}, + 61: {region: 0x424c, code: 0x62, from: 0xf5021, to: 0xfa451}, + 62: {region: 0x424d, code: 0x25, from: 0xf6446, to: 0x0}, + 63: {region: 0x424e, code: 0x26, from: 0xf5ecc, to: 0x0}, + 64: {region: 0x424e, code: 0xb5, from: 0xf5730, to: 0xf5ecc}, + 65: {region: 0x424f, code: 0x27, from: 0xf8621, to: 0x0}, + 66: {region: 0x424f, code: 0x29, from: 0xf5621, to: 0xf859f}, + 67: {region: 0x424f, code: 0x28, from: 0xe8ed7, to: 0xf5621}, + 68: {region: 0x424f, code: 0x802a, from: 0x0, to: 0x0}, + 69: {region: 0x4251, code: 0xfc, from: 0xfb621, to: 0x0}, + 70: {region: 0x4251, code: 0x8, from: 0xfb54a, to: 0xfb621}, + 71: {region: 0x4252, code: 0x2e, from: 0xf94e1, to: 0x0}, + 72: {region: 0x4252, code: 0x30, from: 0xf9301, to: 0xf94e1}, + 73: {region: 0x4252, code: 0x2d, from: 0xf8c70, to: 0xf9301}, + 74: {region: 0x4252, code: 0x2f, from: 0xf8a2f, to: 0xf8c70}, + 75: {region: 0x4252, code: 0x2c, from: 0xf845c, to: 0xf8a2f}, + 76: {region: 0x4252, code: 0x2b, from: 0xf5e4d, to: 0xf845c}, + 77: {region: 0x4252, code: 0x31, from: 0xf2d61, to: 0xf5e4d}, + 78: {region: 0x4253, code: 0x32, from: 0xf5cb9, to: 0x0}, + 79: {region: 0x4254, code: 0x33, from: 0xf6c90, to: 0x0}, + 80: {region: 0x4254, code: 0x7d, from: 0xee621, to: 0x0}, + 81: {region: 0x4255, code: 0x34, from: 0xf40e1, to: 0xf8ad2}, + 82: {region: 0x4256, code: 0xbe, from: 0xee2c7, to: 0x0}, + 83: {region: 0x4257, code: 0x35, from: 0xf7117, to: 0x0}, + 84: {region: 0x4257, code: 0x125, from: 0xf524e, to: 0xf7117}, + 85: {region: 0x4259, code: 0x37, from: 0xfc0e1, to: 0x0}, + 86: {region: 0x4259, code: 0x38, from: 0xfa021, to: 0xfc221}, + 87: {region: 0x4259, code: 0x36, from: 0xf9501, to: 0xfa19f}, + 88: {region: 0x4259, code: 0xd3, from: 0xf8f99, to: 0xf9568}, + 89: {region: 0x4259, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 90: {region: 0x425a, code: 0x39, from: 0xf6c21, to: 0x0}, + 91: {region: 0x4341, code: 0x3a, from: 0xe8421, to: 0x0}, + 92: {region: 0x4343, code: 0x13, from: 0xf5c4e, to: 0x0}, + 93: {region: 0x4344, code: 0x3b, from: 0xf9ce1, to: 0x0}, + 94: {region: 0x4344, code: 0x128, from: 0xf9361, to: 0xf9ce1}, + 95: {region: 0x4344, code: 0x129, from: 0xf675b, to: 0xf9361}, + 96: {region: 0x4346, code: 0x109, from: 0xf9221, to: 0x0}, + 97: {region: 0x4347, code: 0x109, from: 0xf9221, to: 0x0}, + 98: {region: 0x4348, code: 0x3d, from: 0xe0e71, to: 0x0}, + 99: {region: 0x4348, code: 0x803c, from: 0x0, to: 0x0}, + 100: {region: 0x4348, code: 0x803e, from: 0x0, to: 0x0}, + 101: {region: 0x4349, code: 0x115, from: 0xf4d84, to: 0x0}, + 102: {region: 0x434b, code: 0xc0, from: 0xf5eea, to: 0x0}, + 103: {region: 0x434c, code: 0x41, from: 0xf6f3d, to: 0x0}, + 104: {region: 0x434c, code: 0x3f, from: 0xf5021, to: 0xf6f3d}, + 105: {region: 0x434c, code: 0x8040, from: 0x0, to: 0x0}, + 106: {region: 0x434d, code: 0x109, from: 0xf6a81, to: 0x0}, + 107: {region: 0x434e, code: 0x44, from: 0xf4261, to: 0x0}, + 108: {region: 0x434e, code: 0x8043, from: 0xf7621, to: 0xf9d9f}, + 109: {region: 0x434e, code: 0x8042, from: 0xfb4f3, to: 0x0}, + 110: {region: 0x434f, code: 0x45, from: 0xee221, to: 0x0}, + 111: {region: 0x434f, code: 0x8046, from: 0x0, to: 0x0}, + 112: {region: 0x4350, code: 0x811d, from: 0x0, to: 0x0}, + 113: {region: 0x4352, code: 0x47, from: 0xed15a, to: 0x0}, + 114: {region: 0x4353, code: 0x48, from: 0xfa4af, to: 0xfacc3}, + 115: {region: 0x4353, code: 0x5e, from: 0xfa644, to: 0xfacc3}, + 116: {region: 0x4353, code: 0x121, from: 0xf9438, to: 0xfa4af}, + 117: {region: 0x4355, code: 0x4b, from: 0xe8621, to: 0x0}, + 118: {region: 0x4355, code: 0x4a, from: 0xf9421, to: 0x0}, + 119: {region: 0x4355, code: 0xfc, from: 0xed621, to: 0xf4e21}, + 120: {region: 0x4356, code: 0x4c, from: 0xef421, to: 0x0}, + 121: {region: 0x4356, code: 0xcb, from: 0xeeeb6, to: 0xf6ee5}, + 122: {region: 0x4357, code: 0x8, from: 0xfb54a, to: 0x0}, + 123: {region: 0x4358, code: 0x13, from: 0xf5c4e, to: 0x0}, + 124: {region: 0x4359, code: 0x5e, from: 0xfb021, to: 0x0}, + 125: {region: 0x4359, code: 0x4d, from: 0xef52a, to: 0xfb03f}, + 126: {region: 0x435a, code: 0x4e, from: 0xf9221, to: 0x0}, + 127: {region: 0x435a, code: 0x49, from: 0xf42c1, to: 0xf9261}, + 128: {region: 0x4444, code: 0x4f, from: 0xf38f4, to: 0xf8d42}, + 129: {region: 0x4445, code: 0x5e, from: 0xf9e21, to: 0x0}, + 130: {region: 0x4445, code: 0x50, from: 0xf38d4, to: 0xfa45c}, + 131: {region: 0x4447, code: 0xfc, from: 0xf5b68, to: 0x0}, + 132: {region: 0x444a, code: 0x51, from: 0xf72db, to: 0x0}, + 133: {region: 0x444b, code: 0x52, from: 0xea2bb, to: 0x0}, + 134: {region: 0x444d, code: 0x110, from: 0xf5b46, to: 0x0}, + 135: {region: 0x444f, code: 0x53, from: 0xf3741, to: 0x0}, + 136: {region: 0x444f, code: 0xfc, from: 0xee2d5, to: 0xf3741}, + 137: {region: 0x445a, code: 0x54, from: 0xf5881, to: 0x0}, + 138: {region: 0x4541, code: 0x5e, from: 0xf9e21, to: 0x0}, + 139: {region: 0x4543, code: 0xfc, from: 0xfa142, to: 0x0}, + 140: {region: 0x4543, code: 0x55, from: 0xeb881, to: 0xfa142}, + 141: {region: 0x4543, code: 0x8056, from: 0xf92b7, to: 0xfa029}, + 142: {region: 0x4545, code: 0x5e, from: 0xfb621, to: 0x0}, + 143: {region: 0x4545, code: 0x57, from: 0xf90d5, to: 0xfb59f}, + 144: {region: 0x4545, code: 0xe7, from: 0xf5221, to: 0xf90d4}, + 145: {region: 0x4547, code: 0x58, from: 0xebb6e, to: 0x0}, + 146: {region: 0x4548, code: 0x9e, from: 0xf705a, to: 0x0}, + 147: {region: 0x4552, code: 0x59, from: 0xf9b68, to: 0x0}, + 148: {region: 0x4552, code: 0x5d, from: 0xf92b8, to: 0xf9b68}, + 149: {region: 0x4553, code: 0x5e, from: 0xf9e21, to: 0x0}, + 150: {region: 0x4553, code: 0x5c, from: 0xe9953, to: 0xfa45c}, + 151: {region: 0x4553, code: 0x805a, from: 0xf7421, to: 0xf7b9f}, + 152: {region: 0x4553, code: 0x805b, from: 0xf6e21, to: 0xf959f}, + 153: {region: 0x4554, code: 0x5d, from: 0xf712f, to: 0x0}, + 154: {region: 0x4555, code: 0x5e, from: 0xf9e21, to: 0x0}, + 155: {region: 0x4555, code: 0x8112, from: 0xf7621, to: 0xf9d9f}, + 156: {region: 0x4649, code: 0x5e, from: 0xf9e21, to: 0x0}, + 157: {region: 0x4649, code: 0x5f, from: 0xf5621, to: 0xfa45c}, + 158: {region: 0x464a, code: 0x60, from: 0xf622d, to: 0x0}, + 159: {region: 0x464b, code: 0x61, from: 0xeda21, to: 0x0}, + 160: {region: 0x464d, code: 0xfc, from: 0xf3021, to: 0x0}, + 161: {region: 0x464d, code: 0x85, from: 0xef543, to: 0xf3021}, + 162: {region: 0x464f, code: 0x52, from: 0xf3821, to: 0x0}, + 163: {region: 0x4652, code: 0x5e, from: 0xf9e21, to: 0x0}, + 164: {region: 0x4652, code: 0x62, from: 0xf5021, to: 0xfa451}, + 165: {region: 0x4741, code: 0x109, from: 0xf9221, to: 0x0}, + 166: {region: 0x4742, code: 0x63, from: 0xd3cfb, to: 0x0}, + 167: {region: 0x4744, code: 0x110, from: 0xf5e5b, to: 0x0}, + 168: {region: 0x4745, code: 0x65, from: 0xf9737, to: 0x0}, + 169: {region: 0x4745, code: 0x64, from: 0xf9285, to: 0xf9739}, + 170: {region: 0x4745, code: 0xd3, from: 0xf8f99, to: 0xf92cb}, + 171: {region: 0x4745, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 172: {region: 0x4746, code: 0x5e, from: 0xf9e21, to: 0x0}, + 173: {region: 0x4746, code: 0x62, from: 0xf5021, to: 0xfa451}, + 174: {region: 0x4747, code: 0x63, from: 0xe4c21, to: 0x0}, + 175: {region: 0x4748, code: 0x67, from: 0xfaee3, to: 0x0}, + 176: {region: 0x4748, code: 0x66, from: 0xf7669, to: 0xfaf9f}, + 177: {region: 0x4749, code: 0x68, from: 0xd6221, to: 0x0}, + 178: {region: 0x474c, code: 0x52, from: 0xea2bb, to: 0x0}, + 179: {region: 0x474d, code: 0x69, from: 0xf66e1, to: 0x0}, + 180: {region: 0x474e, code: 0x6a, from: 0xf8426, to: 0x0}, + 181: {region: 0x474e, code: 0x6b, from: 0xf6942, to: 0xf8426}, + 182: {region: 0x4750, code: 0x5e, from: 0xf9e21, to: 0x0}, + 183: {region: 0x4750, code: 0x62, from: 0xf5021, to: 0xfa451}, + 184: {region: 0x4751, code: 0x109, from: 0xf9221, to: 0x0}, + 185: {region: 0x4751, code: 0x6c, from: 0xf6ee7, to: 0xf84c1}, + 186: {region: 0x4752, code: 0x5e, from: 0xfa221, to: 0x0}, + 187: {region: 0x4752, code: 0x6d, from: 0xf44a1, to: 0xfa45c}, + 188: {region: 0x4753, code: 0x63, from: 0xee821, to: 0x0}, + 189: {region: 0x4754, code: 0x6e, from: 0xf0abb, to: 0x0}, + 190: {region: 0x4755, code: 0xfc, from: 0xf3115, to: 0x0}, + 191: {region: 0x4757, code: 0x115, from: 0xf9a7f, to: 0x0}, + 192: {region: 0x4757, code: 0x70, from: 0xf705c, to: 0xf9a7f}, + 193: {region: 0x4757, code: 0x6f, from: 0xef421, to: 0xf705c}, + 194: {region: 0x4759, code: 0x71, from: 0xf5cba, to: 0x0}, + 195: {region: 0x484b, code: 0x72, from: 0xece42, to: 0x0}, + 196: {region: 0x484d, code: 0x13, from: 0xf5e50, to: 0x0}, + 197: {region: 0x484e, code: 0x73, from: 0xf0c83, to: 0x0}, + 198: {region: 0x4852, code: 0x75, from: 0xf94be, to: 0x0}, + 199: {region: 0x4852, code: 0x74, from: 0xf8f97, to: 0xf9621}, + 200: {region: 0x4852, code: 0x122, from: 0xf8c21, to: 0xf8f97}, + 201: {region: 0x4852, code: 0x120, from: 0xf5c21, to: 0xf8c21}, + 202: {region: 0x4854, code: 0x76, from: 0xea11a, to: 0x0}, + 203: {region: 0x4854, code: 0xfc, from: 0xef621, to: 0x0}, + 204: {region: 0x4855, code: 0x77, from: 0xf34f7, to: 0x0}, + 205: {region: 0x4943, code: 0x5e, from: 0xf9e21, to: 0x0}, + 206: {region: 0x4944, code: 0x78, from: 0xf5b8d, to: 0x0}, + 207: {region: 0x4945, code: 0x5e, from: 0xf9e21, to: 0x0}, + 208: {region: 0x4945, code: 0x79, from: 0xf0421, to: 0xfa449}, + 209: {region: 0x4945, code: 0x63, from: 0xe1021, to: 0xf0421}, + 210: {region: 0x494c, code: 0x7c, from: 0xf8324, to: 0x0}, + 211: {region: 0x494c, code: 0x7b, from: 0xf7856, to: 0xf8324}, + 212: {region: 0x494c, code: 0x7a, from: 0xf3910, to: 0xf7856}, + 213: {region: 0x494d, code: 0x63, from: 0xe6023, to: 0x0}, + 214: {region: 0x494e, code: 0x7d, from: 0xe5711, to: 0x0}, + 215: {region: 0x494f, code: 0xfc, from: 0xf5b68, to: 0x0}, + 216: {region: 0x4951, code: 0x7e, from: 0xf1693, to: 0x0}, + 217: {region: 0x4951, code: 0x58, from: 0xf016b, to: 0xf1693}, + 218: {region: 0x4951, code: 0x7d, from: 0xf016b, to: 0xf1693}, + 219: {region: 0x4952, code: 0x7f, from: 0xf18ad, to: 0x0}, + 220: {region: 0x4953, code: 0x81, from: 0xf7a21, to: 0x0}, + 221: {region: 0x4953, code: 0x80, from: 0xefd81, to: 0xf7a21}, + 222: {region: 0x4953, code: 0x52, from: 0xea2bb, to: 0xefd81}, + 223: {region: 0x4954, code: 0x5e, from: 0xf9e21, to: 0x0}, + 224: {region: 0x4954, code: 0x82, from: 0xe8d18, to: 0xfa45c}, + 225: {region: 0x4a45, code: 0x63, from: 0xe5a21, to: 0x0}, + 226: {region: 0x4a4d, code: 0x83, from: 0xf6328, to: 0x0}, + 227: {region: 0x4a4f, code: 0x84, from: 0xf3ce1, to: 0x0}, + 228: {region: 0x4a50, code: 0x85, from: 0xe9ec1, to: 0x0}, + 229: {region: 0x4b45, code: 0x86, from: 0xf5d2e, to: 0x0}, + 230: {region: 0x4b47, code: 0x87, from: 0xf92aa, to: 0x0}, + 231: {region: 0x4b47, code: 0xd3, from: 0xf8f99, to: 0xf92aa}, + 232: {region: 0x4b47, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 233: {region: 0x4b48, code: 0x88, from: 0xf7874, to: 0x0}, + 234: {region: 0x4b49, code: 0x13, from: 0xf5c4e, to: 0x0}, + 235: {region: 0x4b4d, code: 0x89, from: 0xf6ee6, to: 0x0}, + 236: {region: 0x4b4e, code: 0x110, from: 0xf5b46, to: 0x0}, + 237: {region: 0x4b50, code: 0x8a, from: 0xf4e91, to: 0x0}, + 238: {region: 0x4b52, code: 0x8d, from: 0xf54ca, to: 0x0}, + 239: {region: 0x4b52, code: 0x8b, from: 0xf424f, to: 0xf54ca}, + 240: {region: 0x4b52, code: 0x8c, from: 0xf330f, to: 0xf424f}, + 241: {region: 0x4b57, code: 0x8e, from: 0xf5281, to: 0x0}, + 242: {region: 0x4b59, code: 0x8f, from: 0xf6621, to: 0x0}, + 243: {region: 0x4b59, code: 0x83, from: 0xf6328, to: 0xf6621}, + 244: {region: 0x4b5a, code: 0x90, from: 0xf9365, to: 0x0}, + 245: {region: 0x4c41, code: 0x91, from: 0xf778a, to: 0x0}, + 246: {region: 0x4c42, code: 0x92, from: 0xf3842, to: 0x0}, + 247: {region: 0x4c43, code: 0x110, from: 0xf5b46, to: 0x0}, + 248: {region: 0x4c49, code: 0x3d, from: 0xf0241, to: 0x0}, + 249: {region: 0x4c4b, code: 0x93, from: 0xf74b6, to: 0x0}, + 250: {region: 0x4c52, code: 0x94, from: 0xf3021, to: 0x0}, + 251: {region: 0x4c53, code: 0x125, from: 0xf524e, to: 0x0}, + 252: {region: 0x4c53, code: 0x95, from: 0xf7836, to: 0x0}, + 253: {region: 0x4c54, code: 0x5e, from: 0xfbe21, to: 0x0}, + 254: {region: 0x4c54, code: 0x96, from: 0xf92d9, to: 0xfbd9f}, + 255: {region: 0x4c54, code: 0x97, from: 0xf9141, to: 0xf92d9}, + 256: {region: 0x4c54, code: 0xe7, from: 0xf5221, to: 0xf9141}, + 257: {region: 0x4c55, code: 0x5e, from: 0xf9e21, to: 0x0}, + 258: {region: 0x4c55, code: 0x99, from: 0xf3124, to: 0xfa45c}, + 259: {region: 0x4c55, code: 0x8098, from: 0xf6421, to: 0xf8c65}, + 260: {region: 0x4c55, code: 0x809a, from: 0xf6421, to: 0xf8c65}, + 261: {region: 0x4c56, code: 0x5e, from: 0xfbc21, to: 0x0}, + 262: {region: 0x4c56, code: 0x9b, from: 0xf92dc, to: 0xfbb9f}, + 263: {region: 0x4c56, code: 0x9c, from: 0xf90a7, to: 0xf9351}, + 264: {region: 0x4c56, code: 0xe7, from: 0xf5221, to: 0xf90f4}, + 265: {region: 0x4c59, code: 0x9d, from: 0xf6721, to: 0x0}, + 266: {region: 0x4d41, code: 0x9e, from: 0xf4f51, to: 0x0}, + 267: {region: 0x4d41, code: 0x9f, from: 0xeb221, to: 0xf4f51}, + 268: {region: 0x4d43, code: 0x5e, from: 0xf9e21, to: 0x0}, + 269: {region: 0x4d43, code: 0x62, from: 0xf5021, to: 0xfa451}, + 270: {region: 0x4d43, code: 0xa0, from: 0xf5021, to: 0xfa451}, + 271: {region: 0x4d44, code: 0xa2, from: 0xf937d, to: 0x0}, + 272: {region: 0x4d44, code: 0xa1, from: 0xf90c1, to: 0xf937d}, + 273: {region: 0x4d45, code: 0x5e, from: 0xfa421, to: 0x0}, + 274: {region: 0x4d45, code: 0x50, from: 0xf9f42, to: 0xfa4af}, + 275: {region: 0x4d45, code: 0x121, from: 0xf9438, to: 0xfa4af}, + 276: {region: 0x4d46, code: 0x5e, from: 0xf9e21, to: 0x0}, + 277: {region: 0x4d46, code: 0x62, from: 0xf5021, to: 0xfa451}, + 278: {region: 0x4d47, code: 0xa3, from: 0xf7f61, to: 0x0}, + 279: {region: 0x4d47, code: 0xa4, from: 0xf56e1, to: 0xfa99f}, + 280: {region: 0x4d48, code: 0xfc, from: 0xf3021, to: 0x0}, + 281: {region: 0x4d4b, code: 0xa5, from: 0xf92b4, to: 0x0}, + 282: {region: 0x4d4b, code: 0xa6, from: 0xf909a, to: 0xf92b4}, + 283: {region: 0x4d4c, code: 0x115, from: 0xf80c1, to: 0x0}, + 284: {region: 0x4d4c, code: 0xa7, from: 0xf54e2, to: 0xf811f}, + 285: {region: 0x4d4c, code: 0x115, from: 0xf4d78, to: 0xf54e2}, + 286: {region: 0x4d4d, code: 0xa8, from: 0xf8ad2, to: 0x0}, + 287: {region: 0x4d4d, code: 0x34, from: 0xf40e1, to: 0xf8ad2}, + 288: {region: 0x4d4e, code: 0xa9, from: 0xef661, to: 0x0}, + 289: {region: 0x4d4f, code: 0xaa, from: 0xeda21, to: 0x0}, + 290: {region: 0x4d50, code: 0xfc, from: 0xf3021, to: 0x0}, + 291: {region: 0x4d51, code: 0x5e, from: 0xf9e21, to: 0x0}, + 292: {region: 0x4d51, code: 0x62, from: 0xf5021, to: 0xfa451}, + 293: {region: 0x4d52, code: 0xab, from: 0xf6add, to: 0x0}, + 294: {region: 0x4d52, code: 0x115, from: 0xf4d7c, to: 0xf6add}, + 295: {region: 0x4d53, code: 0x110, from: 0xf5e5b, to: 0x0}, + 296: {region: 0x4d54, code: 0x5e, from: 0xfb021, to: 0x0}, + 297: {region: 0x4d54, code: 0xac, from: 0xf60c7, to: 0xfb03f}, + 298: {region: 0x4d54, code: 0xad, from: 0xef50d, to: 0xf60c7}, + 299: {region: 0x4d55, code: 0xae, from: 0xf1c81, to: 0x0}, + 300: {region: 0x4d56, code: 0xb0, from: 0xf7ae1, to: 0x0}, + 301: {region: 0x4d57, code: 0xb1, from: 0xf664f, to: 0x0}, + 302: {region: 0x4d58, code: 0xb2, from: 0xf9221, to: 0x0}, + 303: {region: 0x4d58, code: 0xb3, from: 0xe3c21, to: 0xf919f}, + 304: {region: 0x4d58, code: 0x80b4, from: 0x0, to: 0x0}, + 305: {region: 0x4d59, code: 0xb5, from: 0xf5730, to: 0x0}, + 306: {region: 0x4d5a, code: 0xb8, from: 0xface1, to: 0x0}, + 307: {region: 0x4d5a, code: 0xb7, from: 0xf78d0, to: 0xfad9f}, + 308: {region: 0x4d5a, code: 0xb6, from: 0xf6ed9, to: 0xf78d0}, + 309: {region: 0x4e41, code: 0xb9, from: 0xf9221, to: 0x0}, + 310: {region: 0x4e41, code: 0x125, from: 0xf524e, to: 0x0}, + 311: {region: 0x4e43, code: 0x117, from: 0xf8221, to: 0x0}, + 312: {region: 0x4e45, code: 0x115, from: 0xf4d93, to: 0x0}, + 313: {region: 0x4e46, code: 0x13, from: 0xf5c4e, to: 0x0}, + 314: {region: 0x4e47, code: 0xba, from: 0xf6a21, to: 0x0}, + 315: {region: 0x4e49, code: 0xbc, from: 0xf8e9e, to: 0x0}, + 316: {region: 0x4e49, code: 0xbb, from: 0xf884f, to: 0xf8e9e}, + 317: {region: 0x4e4c, code: 0x5e, from: 0xf9e21, to: 0x0}, + 318: {region: 0x4e4c, code: 0xbd, from: 0xe2a21, to: 0xfa45c}, + 319: {region: 0x4e4f, code: 0xbe, from: 0xee2c7, to: 0x0}, + 320: {region: 0x4e4f, code: 0xdb, from: 0xea2bb, to: 0xee2c7}, + 321: {region: 0x4e50, code: 0xbf, from: 0xf1a21, to: 0x0}, + 322: {region: 0x4e50, code: 0x7d, from: 0xe9c21, to: 0xf5d51}, + 323: {region: 0x4e52, code: 0x13, from: 0xf5c4e, to: 0x0}, + 324: {region: 0x4e55, code: 0xc0, from: 0xf5eea, to: 0x0}, + 325: {region: 0x4e5a, code: 0xc0, from: 0xf5eea, to: 0x0}, + 326: {region: 0x4f4d, code: 0xc1, from: 0xf696b, to: 0x0}, + 327: {region: 0x5041, code: 0xc2, from: 0xedf64, to: 0x0}, + 328: {region: 0x5041, code: 0xfc, from: 0xedf72, to: 0x0}, + 329: {region: 0x5045, code: 0xc4, from: 0xf8ee1, to: 0x0}, + 330: {region: 0x5045, code: 0xc3, from: 0xf8241, to: 0xf8ee1}, + 331: {region: 0x5045, code: 0xc5, from: 0xe8e4e, to: 0xf8241}, + 332: {region: 0x5046, code: 0x117, from: 0xf339a, to: 0x0}, + 333: {region: 0x5047, code: 0xc6, from: 0xf6f30, to: 0x0}, + 334: {region: 0x5047, code: 0x13, from: 0xf5c4e, to: 0xf6f30}, + 335: {region: 0x5048, code: 0xc7, from: 0xf34e4, to: 0x0}, + 336: {region: 0x504b, code: 0xc8, from: 0xf3881, to: 0x0}, + 337: {region: 0x504b, code: 0x7d, from: 0xe5711, to: 0xf370f}, + 338: {region: 0x504c, code: 0xc9, from: 0xf9621, to: 0x0}, + 339: {region: 0x504c, code: 0xca, from: 0xf3d5c, to: 0xf959f}, + 340: {region: 0x504d, code: 0x5e, from: 0xf9e21, to: 0x0}, + 341: {region: 0x504d, code: 0x62, from: 0xf6995, to: 0xfa451}, + 342: {region: 0x504e, code: 0xc0, from: 0xf622d, to: 0x0}, + 343: {region: 0x5052, code: 0xfc, from: 0xed58a, to: 0x0}, + 344: {region: 0x5052, code: 0x5c, from: 0xe1021, to: 0xed58a}, + 345: {region: 0x5053, code: 0x7c, from: 0xf8324, to: 0x0}, + 346: {region: 0x5053, code: 0x84, from: 0xf984c, to: 0x0}, + 347: {region: 0x5053, code: 0x7a, from: 0xf5ec1, to: 0xf7856}, + 348: {region: 0x5053, code: 0x84, from: 0xf3ce1, to: 0xf5ec1}, + 349: {region: 0x5054, code: 0x5e, from: 0xf9e21, to: 0x0}, + 350: {region: 0x5054, code: 0xcb, from: 0xeeeb6, to: 0xfa45c}, + 351: {region: 0x5057, code: 0xfc, from: 0xf3021, to: 0x0}, + 352: {region: 0x5059, code: 0xcc, from: 0xf2f61, to: 0x0}, + 353: {region: 0x5141, code: 0xcd, from: 0xf6ab3, to: 0x0}, + 354: {region: 0x5245, code: 0x5e, from: 0xf9e21, to: 0x0}, + 355: {region: 0x5245, code: 0x62, from: 0xf6e21, to: 0xfa451}, + 356: {region: 0x524f, code: 0xd0, from: 0xfaae1, to: 0x0}, + 357: {region: 0x524f, code: 0xcf, from: 0xf403c, to: 0xfad9f}, + 358: {region: 0x5253, code: 0xd1, from: 0xfad59, to: 0x0}, + 359: {region: 0x5253, code: 0x48, from: 0xfa4af, to: 0xfad59}, + 360: {region: 0x5253, code: 0x121, from: 0xf9438, to: 0xfa4af}, + 361: {region: 0x5255, code: 0xd2, from: 0xf9e21, to: 0x0}, + 362: {region: 0x5255, code: 0xd3, from: 0xf8f99, to: 0xf9d9f}, + 363: {region: 0x5257, code: 0xd4, from: 0xf58b3, to: 0x0}, + 364: {region: 0x5341, code: 0xd5, from: 0xf4156, to: 0x0}, + 365: {region: 0x5342, code: 0xd6, from: 0xf7358, to: 0x0}, + 366: {region: 0x5342, code: 0x13, from: 0xf5c4e, to: 0xf74de}, + 367: {region: 0x5343, code: 0xd7, from: 0xedf61, to: 0x0}, + 368: {region: 0x5344, code: 0xd9, from: 0xfae2a, to: 0x0}, + 369: {region: 0x5344, code: 0xd8, from: 0xf90c8, to: 0xfaede}, + 370: {region: 0x5344, code: 0xda, from: 0xf4a88, to: 0xf9cc1}, + 371: {region: 0x5344, code: 0x58, from: 0xec233, to: 0xf4c21}, + 372: {region: 0x5344, code: 0x63, from: 0xec233, to: 0xf4c21}, + 373: {region: 0x5345, code: 0xdb, from: 0xea2bb, to: 0x0}, + 374: {region: 0x5347, code: 0xdc, from: 0xf5ecc, to: 0x0}, + 375: {region: 0x5347, code: 0xb5, from: 0xf5730, to: 0xf5ecc}, + 376: {region: 0x5348, code: 0xdd, from: 0xefa4f, to: 0x0}, + 377: {region: 0x5349, code: 0x5e, from: 0xfae21, to: 0x0}, + 378: {region: 0x5349, code: 0xde, from: 0xf9147, to: 0xfae2e}, + 379: {region: 0x534a, code: 0xbe, from: 0xee2c7, to: 0x0}, + 380: {region: 0x534b, code: 0x5e, from: 0xfb221, to: 0x0}, + 381: {region: 0x534b, code: 0xdf, from: 0xf919f, to: 0xfb221}, + 382: {region: 0x534b, code: 0x49, from: 0xf42c1, to: 0xf919f}, + 383: {region: 0x534c, code: 0xe0, from: 0xf5904, to: 0x0}, + 384: {region: 0x534c, code: 0x63, from: 0xe217e, to: 0xf5c44}, + 385: {region: 0x534d, code: 0x5e, from: 0xf9e21, to: 0x0}, + 386: {region: 0x534d, code: 0x82, from: 0xe9397, to: 0xfa25c}, + 387: {region: 0x534e, code: 0x115, from: 0xf4e84, to: 0x0}, + 388: {region: 0x534f, code: 0xe1, from: 0xf50e1, to: 0x0}, + 389: {region: 0x5352, code: 0xe2, from: 0xfa821, to: 0x0}, + 390: {region: 0x5352, code: 0xe3, from: 0xf28aa, to: 0xfa79f}, + 391: {region: 0x5352, code: 0xbd, from: 0xe2f74, to: 0xf28aa}, + 392: {region: 0x5353, code: 0xe4, from: 0xfb6f2, to: 0x0}, + 393: {region: 0x5353, code: 0xd9, from: 0xfae2a, to: 0xfb721}, + 394: {region: 0x5354, code: 0xe6, from: 0xfc421, to: 0x0}, + 395: {region: 0x5354, code: 0xe5, from: 0xf7328, to: 0xfc39f}, + 396: {region: 0x5355, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 397: {region: 0x5356, code: 0xfc, from: 0xfa221, to: 0x0}, + 398: {region: 0x5356, code: 0xe8, from: 0xeff6b, to: 0xfa221}, + 399: {region: 0x5358, code: 0x8, from: 0xfb54a, to: 0x0}, + 400: {region: 0x5359, code: 0xe9, from: 0xf3821, to: 0x0}, + 401: {region: 0x535a, code: 0xea, from: 0xf6d26, to: 0x0}, + 402: {region: 0x5441, code: 0x63, from: 0xf242c, to: 0x0}, + 403: {region: 0x5443, code: 0xfc, from: 0xf6328, to: 0x0}, + 404: {region: 0x5444, code: 0x109, from: 0xf9221, to: 0x0}, + 405: {region: 0x5446, code: 0x5e, from: 0xf9e21, to: 0x0}, + 406: {region: 0x5446, code: 0x62, from: 0xf4e21, to: 0xfa451}, + 407: {region: 0x5447, code: 0x115, from: 0xf4d7c, to: 0x0}, + 408: {region: 0x5448, code: 0xeb, from: 0xf108f, to: 0x0}, + 409: {region: 0x544a, code: 0xed, from: 0xfa15a, to: 0x0}, + 410: {region: 0x544a, code: 0xec, from: 0xf96aa, to: 0xfa159}, + 411: {region: 0x544a, code: 0xd3, from: 0xf8f99, to: 0xf96aa}, + 412: {region: 0x544b, code: 0xc0, from: 0xf5eea, to: 0x0}, + 413: {region: 0x544c, code: 0xfc, from: 0xf9f54, to: 0x0}, + 414: {region: 0x544c, code: 0xf2, from: 0xf4e22, to: 0xfa4b4}, + 415: {region: 0x544c, code: 0x78, from: 0xf6f87, to: 0xfa4b4}, + 416: {region: 0x544d, code: 0xef, from: 0xfb221, to: 0x0}, + 417: {region: 0x544d, code: 0xee, from: 0xf9361, to: 0xfb221}, + 418: {region: 0x544d, code: 0xd3, from: 0xf8f99, to: 0xf9361}, + 419: {region: 0x544d, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 420: {region: 0x544e, code: 0xf0, from: 0xf4d61, to: 0x0}, + 421: {region: 0x544f, code: 0xf1, from: 0xf5c4e, to: 0x0}, + 422: {region: 0x5450, code: 0xf2, from: 0xf4e22, to: 0xfa4b4}, + 423: {region: 0x5450, code: 0x78, from: 0xf6f87, to: 0xfa4b4}, + 424: {region: 0x5452, code: 0xf4, from: 0xfaa21, to: 0x0}, + 425: {region: 0x5452, code: 0xf3, from: 0xf0561, to: 0xfab9f}, + 426: {region: 0x5454, code: 0xf5, from: 0xf5821, to: 0x0}, + 427: {region: 0x5456, code: 0x13, from: 0xf5c4e, to: 0x0}, + 428: {region: 0x5457, code: 0xf6, from: 0xf3acf, to: 0x0}, + 429: {region: 0x545a, code: 0xf7, from: 0xf5cce, to: 0x0}, + 430: {region: 0x5541, code: 0xf8, from: 0xf9922, to: 0x0}, + 431: {region: 0x5541, code: 0xf9, from: 0xf916d, to: 0xf9351}, + 432: {region: 0x5541, code: 0xd3, from: 0xf8f99, to: 0xf916d}, + 433: {region: 0x5541, code: 0xe7, from: 0xf5221, to: 0xf8f99}, + 434: {region: 0x5547, code: 0xfb, from: 0xf86af, to: 0x0}, + 435: {region: 0x5547, code: 0xfa, from: 0xf5d0f, to: 0xf86af}, + 436: {region: 0x554d, code: 0xfc, from: 0xf3021, to: 0x0}, + 437: {region: 0x5553, code: 0xfc, from: 0xe0021, to: 0x0}, + 438: {region: 0x5553, code: 0x80fd, from: 0x0, to: 0x0}, + 439: {region: 0x5553, code: 0x80fe, from: 0x0, to: 0xfbc61}, + 440: {region: 0x5559, code: 0x101, from: 0xf9261, to: 0x0}, + 441: {region: 0x5559, code: 0x100, from: 0xf6ee1, to: 0xf9261}, + 442: {region: 0x5559, code: 0x80ff, from: 0x0, to: 0x0}, + 443: {region: 0x555a, code: 0x102, from: 0xf94e1, to: 0x0}, + 444: {region: 0x5641, code: 0x5e, from: 0xf9e21, to: 0x0}, + 445: {region: 0x5641, code: 0x82, from: 0xe9d53, to: 0xfa45c}, + 446: {region: 0x5643, code: 0x110, from: 0xf5b46, to: 0x0}, + 447: {region: 0x5645, code: 0x104, from: 0xfb021, to: 0x0}, + 448: {region: 0x5645, code: 0x103, from: 0xe9eab, to: 0xfb0de}, + 449: {region: 0x5647, code: 0xfc, from: 0xe5221, to: 0x0}, + 450: {region: 0x5647, code: 0x63, from: 0xe5221, to: 0xf4e21}, + 451: {region: 0x5649, code: 0xfc, from: 0xe5a21, to: 0x0}, + 452: {region: 0x564e, code: 0x105, from: 0xf832e, to: 0x0}, + 453: {region: 0x564e, code: 0x106, from: 0xf74a3, to: 0xf832e}, + 454: {region: 0x5655, code: 0x107, from: 0xf7a21, to: 0x0}, + 455: {region: 0x5746, code: 0x117, from: 0xf52fe, to: 0x0}, + 456: {region: 0x5753, code: 0x108, from: 0xf5eea, to: 0x0}, + 457: {region: 0x584b, code: 0x5e, from: 0xfa421, to: 0x0}, + 458: {region: 0x584b, code: 0x50, from: 0xf9f21, to: 0xfa469}, + 459: {region: 0x584b, code: 0x121, from: 0xf9438, to: 0xf9f3e}, + 460: {region: 0x5944, code: 0x11e, from: 0xf5a81, to: 0xf9821}, + 461: {region: 0x5945, code: 0x11f, from: 0xf8cb6, to: 0x0}, + 462: {region: 0x5954, code: 0x5e, from: 0xf9e21, to: 0x0}, + 463: {region: 0x5954, code: 0x62, from: 0xf7057, to: 0xfa451}, + 464: {region: 0x5954, code: 0x89, from: 0xf6e21, to: 0xf7057}, + 465: {region: 0x5955, code: 0x121, from: 0xf9438, to: 0xfa4af}, + 466: {region: 0x5955, code: 0x122, from: 0xf8c21, to: 0xf90f8}, + 467: {region: 0x5955, code: 0x120, from: 0xf5c21, to: 0xf8c21}, + 468: {region: 0x5a41, code: 0x125, from: 0xf524e, to: 0x0}, + 469: {region: 0x5a41, code: 0x8124, from: 0xf8321, to: 0xf966d}, + 470: {region: 0x5a4d, code: 0x127, from: 0xfba21, to: 0x0}, + 471: {region: 0x5a4d, code: 0x126, from: 0xf6030, to: 0xfba21}, + 472: {region: 0x5a52, code: 0x128, from: 0xf9361, to: 0xf9cff}, + 473: {region: 0x5a52, code: 0x129, from: 0xf675b, to: 0xf9361}, + 474: {region: 0x5a57, code: 0xfc, from: 0xfb28c, to: 0x0}, + 475: {region: 0x5a57, code: 0x12b, from: 0xfb242, to: 0xfb28c}, + 476: {region: 0x5a57, code: 0x12c, from: 0xfb101, to: 0xfb242}, + 477: {region: 0x5a57, code: 0x12a, from: 0xf7892, to: 0xfb101}, + 478: {region: 0x5a57, code: 0xce, from: 0xf6451, to: 0xf7892}, + 479: {region: 0x5a5a, code: 0x810a, from: 0x0, to: 0x0}, + 480: {region: 0x5a5a, code: 0x810b, from: 0x0, to: 0x0}, + 481: {region: 0x5a5a, code: 0x810c, from: 0x0, to: 0x0}, + 482: {region: 0x5a5a, code: 0x810d, from: 0x0, to: 0x0}, + 483: {region: 0x5a5a, code: 0x810e, from: 0x0, to: 0x0}, + 484: {region: 0x5a5a, code: 0x810f, from: 0x0, to: 0x0}, + 485: {region: 0x5a5a, code: 0x8111, from: 0x0, to: 0x0}, + 486: {region: 0x5a5a, code: 0x8113, from: 0xf1421, to: 0xfa681}, + 487: {region: 0x5a5a, code: 0x8114, from: 0x0, to: 0xfbb7e}, + 488: {region: 0x5a5a, code: 0x8116, from: 0x0, to: 0x0}, + 489: {region: 0x5a5a, code: 0x8118, from: 0x0, to: 0x0}, + 490: {region: 0x5a5a, code: 0x8119, from: 0x0, to: 0xf9f7e}, + 491: {region: 0x5a5a, code: 0x811a, from: 0x0, to: 0x0}, + 492: {region: 0x5a5a, code: 0x811b, from: 0x0, to: 0x0}, + 493: {region: 0x5a5a, code: 0x811c, from: 0x0, to: 0x0}, + 494: {region: 0x5a5a, code: 0x811d, from: 0x0, to: 0x0}, +} // Size: 5964 bytes + +// symbols holds symbol data of the form , where n is the length of +// the symbol string str. +const symbols string = "" + // Size: 1445 bytes + "\x00\x02Kz\x01$\x02A$\x02KM\x03৳\x02Bs\x02R$\x01P\x03р.\x03CA$\x04CN¥" + + "\x02¥\x03₡\x03Kč\x02kr\x03E£\x03₧\x03€\x02£\x03₾\x02FG\x01Q\x03HK$\x01L" + + "\x02kn\x02Ft\x02Rp\x03₪\x03₹\x04JP¥\x03៛\x02CF\x03₩\x03₸\x03₭\x03L£\x02R" + + "s\x02Lt\x02Ls\x02Ar\x01K\x03₮\x03MX$\x02RM\x03₦\x02C$\x03NZ$\x03₱\x03zł" + + "\x03₲\x03lei\x03₽\x02RF\x02Db\x03฿\x02T$\x03₺\x03NT$\x03₴\x03US$\x03₫" + + "\x04FCFA\x03EC$\x03CFA\x04CFPF\x01R\x02ZK\x03leu\x05GH₵\x03AU$\x16የቻይና ዩ" + + "ዋን\x06ብር\x03***\x09د.إ.\u200f\x03AR$\x03BB$\x09د.ب.\u200f\x03BM$\x03BN" + + "$\x03BS$\x03BZ$\x03CL$\x03CO$\x03CU$\x03DO$\x09د.ج.\u200f\x09ج.م.\u200f" + + "\x03FJ$\x04UK£\x03GY$\x09د.ع.\u200f\x06ر.إ.\x03JM$\x09د.أ.\u200f\x09د.ك." + + "\u200f\x03KY$\x09ل.ل.\u200f\x09د.ل.\u200f\x09د.م.\u200f\x09أ.م.\u200f" + + "\x09ر.ع.\u200f\x09ر.ق.\u200f\x09ر.س.\u200f\x03SB$\x09د.س.\u200f\x06ج.س." + + "\x03SR$\x09ل.س.\u200f\x09د.ت.\u200f\x03TT$\x03UY$\x09ر.ي.\u200f\x03Fdj" + + "\x03Nfk\x01S\x04GB£\x03TSh\x03₼\x03ley\x03S£\x04Bds$\x03BD$\x02B$\x02Br" + + "\x04CUC$\x03$MN\x03RD$\x04FK£\x02G$\x04Íkr\x02J$\x03CI$\x02L$\x02N$\x07р" + + "уб.\x03SI$\x02S$\x02$U\x05лв.\x06щ.д.\x02$A\x03$CA\x04£ E\x05£ RU\x04$ " + + "HK\x03£L\x04$ ZN\x03$ T\x04$ SU\x04din.\x04КМ\x04Кч\x04зл\x07дин.\x04Тл" + + "\x01F\x06лей\x03USh\x04Kčs\x03ECU\x02TK\x03kr.\x03Ksh\x03öS\x03BGK\x03BG" + + "J\x04Cub$\x02DM\x04Fl£\x04F.G.\x02FC\x04F.Rw\x03Nu.\x05KR₩\x05TH฿\x06Δρχ" + + "\x02Tk\x02$b\x02Kr\x02Gs\x03CFP\x03FBu\x01D\x04MOP$\x02MK\x02SR\x02Le" + + "\x04NAf.\x01E\x02VT\x03WS$\x04SD£\x03BsF\x02p.\x03B/.\x02S/\x03Gs.\x03Bs" + + ".\x02؋\x04¥CN\x03$HK\x08ریال\x03$MX\x03$NZ\x03$EC\x02UM\x02mk\x03$AR\x03" + + "$AU\x02FB\x03$BM\x03$BN\x03$BS\x03$BZ\x03$CL\x03$CO\x04£CY\x03£E\x03$FJ" + + "\x04£FK\x04£GB\x04£GI\x04£IE\x04£IL\x05₤IT\x04£LB\x04£MT\x03$NA\x02$C" + + "\x03$RH\x02FR\x03$SB\x03$SG\x03$SR\x03$TT\x03$US\x03$UY\x04FCFP\x02Kw" + + "\x05$\u00a0AU\x05$\u00a0HK\x05$\u00a0NZ\x05$\u00a0SG\x05$\u00a0US\x02DA" + + "\x01G\x02LS\x02DT\x06руб\x07રૂ.\x0a\u200eCN¥\u200e\x06ל״י\x09लेई\x02֏" + + "\x03NKr\x03元\x03¥\x06レイ\x03\u200b\x06ಲೀ\x02LE\x02Kn\x06сом\x02zl\x02rb" + + "\x03MTn\x06ден\x04кр\x03NAf\x03Afl\x0cनेरू\x06रू\x04Afl.\x02ر\x03lej\x04" + + "Esc.\x06\u200bPTE\x04XXXX\x03ლ\x06ТМТ\x03Dkr\x03Skr\x03Nkr\x07රු.\x0fසිෆ" + + "්එ\x03NIS\x05Lekë\x03den\x02r.\x03BR$\x03Ekr\x04EG£\x04IE£\x03Ikr\x03R" + + "s.\x07сом.\x04AUD$\x04NZD$\x07крб.\x05soʻm\x06сўм\x03₩\x03ILS\x02P.\x03Z" + + "ł" + +type curToIndex struct { + cur uint16 + idx uint16 +} + +var normalLangIndex = []uint16{ // 776 elements + // Entry 0 - 3F + 0x0000, 0x0014, 0x0017, 0x0018, 0x0018, 0x0018, 0x0018, 0x0019, + 0x0019, 0x001d, 0x001d, 0x0034, 0x0034, 0x0034, 0x0034, 0x0035, + 0x0035, 0x0035, 0x0035, 0x0036, 0x0036, 0x0036, 0x0036, 0x0037, + 0x0037, 0x0038, 0x0038, 0x0038, 0x0038, 0x0038, 0x0038, 0x0038, + 0x0038, 0x0038, 0x0039, 0x003b, 0x003b, 0x003b, 0x003b, 0x003b, + 0x003b, 0x003b, 0x003b, 0x003c, 0x003c, 0x003f, 0x003f, 0x0041, + 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0049, 0x0049, + 0x004a, 0x004a, 0x004b, 0x004b, 0x005c, 0x005c, 0x005c, 0x005c, + // Entry 40 - 7F + 0x005c, 0x005e, 0x005e, 0x005e, 0x005f, 0x005f, 0x0060, 0x006e, + 0x006e, 0x006e, 0x006e, 0x007f, 0x0085, 0x0085, 0x0085, 0x0085, + 0x008e, 0x008e, 0x008e, 0x008f, 0x008f, 0x0091, 0x0091, 0x0091, + 0x0092, 0x0092, 0x0093, 0x0093, 0x0094, 0x0094, 0x0095, 0x0095, + 0x0095, 0x009c, 0x009c, 0x009d, 0x009d, 0x009f, 0x009f, 0x00a3, + 0x00a3, 0x00a3, 0x00a4, 0x00a4, 0x00ac, 0x00ac, 0x00ac, 0x00ad, + 0x00ad, 0x00ad, 0x00ae, 0x00af, 0x00af, 0x00af, 0x00b4, 0x00b4, + 0x00b4, 0x00b4, 0x00b4, 0x00b4, 0x00b4, 0x00ba, 0x00ba, 0x00bb, + // Entry 80 - BF + 0x00bb, 0x00be, 0x00be, 0x00be, 0x00c1, 0x00c1, 0x00c1, 0x00c3, + 0x00c5, 0x00c5, 0x00c6, 0x00c7, 0x00c7, 0x00c7, 0x00dc, 0x00dd, + 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, + 0x00e4, 0x00e5, 0x00e5, 0x00e6, 0x00e6, 0x00e6, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00e9, 0x00ea, 0x00ec, 0x00ec, 0x00ec, 0x00ed, + 0x00ed, 0x00ee, 0x00f0, 0x00f1, 0x00f1, 0x00f2, 0x00f2, 0x00f2, + 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f2, 0x00f3, 0x00f4, 0x00f5, + 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fb, 0x00fc, + // Entry C0 - FF + 0x00fc, 0x00fd, 0x00fe, 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, + 0x0104, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, + 0x010b, 0x010b, 0x010b, 0x010c, 0x010d, 0x010e, 0x010e, 0x010f, + 0x0110, 0x0112, 0x0112, 0x0113, 0x0115, 0x0116, 0x0117, 0x0117, + 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011d, 0x011d, + 0x011e, 0x011e, 0x011e, 0x011f, 0x0120, 0x0121, 0x0122, 0x0122, + 0x0122, 0x0122, 0x0133, 0x0138, 0x013a, 0x013b, 0x013c, 0x013d, + 0x013f, 0x0141, 0x0142, 0x0144, 0x0146, 0x0146, 0x0147, 0x0147, + // Entry 100 - 13F + 0x0148, 0x0149, 0x014a, 0x014a, 0x014b, 0x014c, 0x014d, 0x014e, + 0x014f, 0x0150, 0x0151, 0x0152, 0x0154, 0x0156, 0x0157, 0x015c, + 0x015c, 0x015e, 0x015e, 0x015e, 0x015e, 0x0169, 0x0169, 0x0169, + 0x0169, 0x0169, 0x016a, 0x016b, 0x016b, 0x017c, 0x017c, 0x0180, + 0x0180, 0x0181, 0x0182, 0x0182, 0x01a8, 0x01a8, 0x01a8, 0x01a9, + 0x01a9, 0x01a9, 0x01ca, 0x01cb, 0x01cb, 0x01cb, 0x01cb, 0x01cb, + 0x01cb, 0x01cc, 0x01cd, 0x01cd, 0x01cd, 0x01cd, 0x01ce, 0x01ce, + 0x01ce, 0x01cf, 0x01d0, 0x01d2, 0x01d2, 0x01d2, 0x01d2, 0x01d3, + // Entry 140 - 17F + 0x01d3, 0x01d3, 0x01d4, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, + 0x01d5, 0x01d6, 0x01d7, 0x01d7, 0x01d8, 0x01d8, 0x01d8, 0x01d9, + 0x01da, 0x01da, 0x01da, 0x01da, 0x01da, 0x01e0, 0x01e0, 0x01e3, + 0x01e3, 0x01e5, 0x01e5, 0x01e9, 0x01e9, 0x01ec, 0x01ec, 0x01ec, + 0x01ec, 0x01ed, 0x01ed, 0x01ed, 0x01ee, 0x01ee, 0x01ee, 0x01ee, + 0x01ef, 0x01f0, 0x01f0, 0x01f0, 0x01f1, 0x01f1, 0x01f6, 0x01f6, + 0x01f8, 0x01f8, 0x020a, 0x020b, 0x020b, 0x0210, 0x0210, 0x0222, + 0x0222, 0x0225, 0x0225, 0x0229, 0x0229, 0x022a, 0x022a, 0x022b, + // Entry 180 - 1BF + 0x022b, 0x022b, 0x022b, 0x0237, 0x0237, 0x023f, 0x023f, 0x023f, + 0x023f, 0x023f, 0x023f, 0x023f, 0x0242, 0x0242, 0x0242, 0x0242, + 0x0242, 0x0242, 0x0243, 0x0243, 0x0243, 0x0243, 0x024d, 0x024d, + 0x024e, 0x024e, 0x024e, 0x024f, 0x024f, 0x024f, 0x0250, 0x0250, + 0x0253, 0x0253, 0x0253, 0x0253, 0x0254, 0x0254, 0x0258, 0x0258, + 0x0258, 0x0258, 0x0259, 0x0259, 0x025a, 0x025a, 0x025d, 0x025d, + 0x025f, 0x025f, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, + 0x0260, 0x0261, 0x0261, 0x0261, 0x0261, 0x0261, 0x0261, 0x0261, + // Entry 1C0 - 1FF + 0x0261, 0x0261, 0x0270, 0x0270, 0x0271, 0x0271, 0x0276, 0x0276, + 0x0277, 0x0277, 0x0278, 0x0278, 0x0279, 0x027a, 0x027a, 0x027a, + 0x027a, 0x027c, 0x027c, 0x027d, 0x027d, 0x027d, 0x0290, 0x0290, + 0x0291, 0x0291, 0x0292, 0x0292, 0x0293, 0x0293, 0x0298, 0x0298, + 0x0299, 0x0299, 0x029a, 0x029b, 0x029b, 0x029c, 0x029c, 0x029d, + 0x029d, 0x029e, 0x029e, 0x029e, 0x029e, 0x02aa, 0x02aa, 0x02ad, + 0x02ad, 0x02b0, 0x02b0, 0x02b0, 0x02b2, 0x02b2, 0x02b6, 0x02b7, + 0x02b7, 0x02b8, 0x02b8, 0x02b8, 0x02b8, 0x02b8, 0x02bf, 0x02bf, + // Entry 200 - 23F + 0x02c0, 0x02c0, 0x02c0, 0x02c1, 0x02c1, 0x02d3, 0x02d3, 0x02d3, + 0x02d3, 0x02d3, 0x02d3, 0x02d3, 0x02d3, 0x02d5, 0x02d5, 0x02d5, + 0x02db, 0x02dc, 0x02dc, 0x02dd, 0x02de, 0x02de, 0x02df, 0x02e0, + 0x02e0, 0x02e0, 0x02f3, 0x02f3, 0x02f3, 0x02f3, 0x02f3, 0x02f3, + 0x02f3, 0x02f3, 0x02f5, 0x02f5, 0x02f5, 0x02f6, 0x02f6, 0x02f7, + 0x02f7, 0x02f8, 0x02fa, 0x02fa, 0x02fc, 0x02fc, 0x02fe, 0x02ff, + 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x030f, 0x030f, 0x030f, + 0x030f, 0x0310, 0x0310, 0x0313, 0x0314, 0x0314, 0x0314, 0x0316, + // Entry 240 - 27F + 0x0316, 0x0316, 0x0317, 0x0318, 0x0319, 0x031a, 0x031b, 0x031b, + 0x031c, 0x031e, 0x0320, 0x0320, 0x0320, 0x0320, 0x0321, 0x0321, + 0x0332, 0x0333, 0x0333, 0x0334, 0x0334, 0x033c, 0x033e, 0x033f, + 0x0340, 0x0341, 0x0341, 0x0341, 0x0342, 0x0342, 0x0343, 0x0343, + 0x0344, 0x0344, 0x0345, 0x0345, 0x0346, 0x0346, 0x0347, 0x0347, + 0x0347, 0x034b, 0x034b, 0x034b, 0x034d, 0x034e, 0x034e, 0x034e, + 0x034e, 0x034e, 0x034e, 0x034e, 0x034e, 0x034e, 0x034e, 0x034e, + 0x034e, 0x0351, 0x0351, 0x035f, 0x035f, 0x0369, 0x0369, 0x0369, + // Entry 280 - 2BF + 0x0369, 0x0369, 0x0369, 0x0369, 0x0369, 0x0369, 0x0369, 0x036a, + 0x036b, 0x036c, 0x036d, 0x036d, 0x036f, 0x036f, 0x0370, 0x0370, + 0x0376, 0x0376, 0x0376, 0x0376, 0x0376, 0x0376, 0x037c, 0x037c, + 0x037c, 0x037c, 0x037c, 0x037c, 0x037c, 0x037c, 0x0394, 0x0394, + 0x0394, 0x0394, 0x0397, 0x0398, 0x0398, 0x0398, 0x0399, 0x0399, + 0x039c, 0x039c, 0x039d, 0x039f, 0x03a2, 0x03a4, 0x03a4, 0x03a5, + 0x03a6, 0x03a6, 0x03a8, 0x03a8, 0x03aa, 0x03aa, 0x03ab, 0x03ac, + 0x03ac, 0x03ac, 0x03ae, 0x03ae, 0x03ae, 0x03ae, 0x03b1, 0x03b1, + // Entry 2C0 - 2FF + 0x03b6, 0x03b6, 0x03b6, 0x03b6, 0x03b8, 0x03b8, 0x03b8, 0x03b8, + 0x03b8, 0x03b8, 0x03ba, 0x03ba, 0x03cd, 0x03cd, 0x03d0, 0x03d1, + 0x03d1, 0x03d2, 0x03d3, 0x03d3, 0x03d5, 0x03d5, 0x03d5, 0x03d5, + 0x03d6, 0x03d7, 0x03d7, 0x03d7, 0x03d7, 0x03d7, 0x03d9, 0x03d9, + 0x03d9, 0x03d9, 0x03da, 0x03da, 0x03da, 0x03dc, 0x03dc, 0x03dd, + 0x03dd, 0x03dd, 0x03de, 0x03de, 0x03de, 0x03de, 0x03de, 0x03de, + 0x03df, 0x03df, 0x03df, 0x03e2, 0x03e5, 0x03e5, 0x03e5, 0x03e5, + 0x03e5, 0x03e5, 0x03e9, 0x03e9, 0x03e9, 0x03ea, 0x03ec, 0x03ee, + // Entry 300 - 33F + 0x03f2, 0x03f4, 0x03f5, 0x03f5, 0x03f7, 0x03f7, 0x03f7, 0x03f7, +} // Size: 1576 bytes + +var normalSymIndex = []curToIndex{ // 1015 elements + 0: {cur: 0x13, idx: 0x6}, + 1: {cur: 0x2e, idx: 0x13}, + 2: {cur: 0x3a, idx: 0x1c}, + 3: {cur: 0x44, idx: 0x20}, + 4: {cur: 0x5e, idx: 0x3b}, + 5: {cur: 0x63, idx: 0x3f}, + 6: {cur: 0x72, idx: 0x4b}, + 7: {cur: 0x7c, idx: 0x5a}, + 8: {cur: 0x7d, idx: 0x5e}, + 9: {cur: 0x85, idx: 0x62}, + 10: {cur: 0x8d, idx: 0x6e}, + 11: {cur: 0xb2, idx: 0x90}, + 12: {cur: 0xc0, idx: 0x9e}, + 13: {cur: 0xf6, idx: 0xc7}, + 14: {cur: 0xfc, idx: 0xcf}, + 15: {cur: 0x105, idx: 0xd3}, + 16: {cur: 0x109, idx: 0xd7}, + 17: {cur: 0x110, idx: 0xdc}, + 18: {cur: 0x115, idx: 0xe0}, + 19: {cur: 0x117, idx: 0xe4}, + 20: {cur: 0xb2, idx: 0x0}, + 21: {cur: 0xeb, idx: 0xbc}, + 22: {cur: 0x125, idx: 0xe9}, + 23: {cur: 0xb9, idx: 0x4}, + 24: {cur: 0x67, idx: 0xf2}, + 25: {cur: 0x13, idx: 0xf8}, + 26: {cur: 0x42, idx: 0xfc}, + 27: {cur: 0x5d, idx: 0x113}, + 28: {cur: 0xeb, idx: 0xbc}, + 29: {cur: 0x0, idx: 0x11a}, + 30: {cur: 0x2, idx: 0x11e}, + 31: {cur: 0x13, idx: 0xf8}, + 32: {cur: 0x23, idx: 0x130}, + 33: {cur: 0x54, idx: 0x15a}, + 34: {cur: 0x58, idx: 0x164}, + 35: {cur: 0x7e, idx: 0x17b}, + 36: {cur: 0x7f, idx: 0x185}, + 37: {cur: 0x84, idx: 0x190}, + 38: {cur: 0x8e, idx: 0x19a}, + 39: {cur: 0x92, idx: 0x1a8}, + 40: {cur: 0x9d, idx: 0x1b2}, + 41: {cur: 0x9e, idx: 0x1bc}, + 42: {cur: 0xab, idx: 0x1c6}, + 43: {cur: 0xc1, idx: 0x1d0}, + 44: {cur: 0xcd, idx: 0x1da}, + 45: {cur: 0xd5, idx: 0x1e4}, + 46: {cur: 0xd8, idx: 0x1f2}, + 47: {cur: 0xd9, idx: 0x1fc}, + 48: {cur: 0xe9, idx: 0x207}, + 49: {cur: 0xeb, idx: 0xbc}, + 50: {cur: 0xf0, idx: 0x211}, + 51: {cur: 0x11f, idx: 0x223}, + 52: {cur: 0x51, idx: 0x22d}, + 53: {cur: 0x59, idx: 0x231}, + 54: {cur: 0x89, idx: 0x6b}, + 55: {cur: 0xd9, idx: 0x0}, + 56: {cur: 0xe1, idx: 0x235}, + 57: {cur: 0x63, idx: 0x237}, + 58: {cur: 0xe4, idx: 0x3f}, + 59: {cur: 0xf7, idx: 0x23c}, + 60: {cur: 0x85, idx: 0x25}, + 61: {cur: 0xeb, idx: 0xbc}, + 62: {cur: 0xfc, idx: 0x4}, + 63: {cur: 0x16, idx: 0x240}, + 64: {cur: 0xeb, idx: 0xbc}, + 65: {cur: 0x16, idx: 0x240}, + 66: {cur: 0x2e, idx: 0x0}, + 67: {cur: 0x37, idx: 0x258}, + 68: {cur: 0x3a, idx: 0x0}, + 69: {cur: 0x85, idx: 0x25}, + 70: {cur: 0xc0, idx: 0x0}, + 71: {cur: 0xd2, idx: 0xb2}, + 72: {cur: 0xfc, idx: 0x4}, + 73: {cur: 0x127, idx: 0x8a}, + 74: {cur: 0xf7, idx: 0x23c}, + 75: {cur: 0x13, idx: 0x0}, + 76: {cur: 0x21, idx: 0x294}, + 77: {cur: 0x2e, idx: 0x0}, + 78: {cur: 0x3a, idx: 0x0}, + 79: {cur: 0x44, idx: 0x0}, + 80: {cur: 0x63, idx: 0x0}, + 81: {cur: 0x72, idx: 0x0}, + 82: {cur: 0x7c, idx: 0x0}, + 83: {cur: 0x7d, idx: 0x0}, + 84: {cur: 0x85, idx: 0x0}, + 85: {cur: 0x8d, idx: 0x0}, + 86: {cur: 0xb2, idx: 0x0}, + 87: {cur: 0xc0, idx: 0x0}, + 88: {cur: 0xf6, idx: 0x0}, + 89: {cur: 0xfc, idx: 0x29a}, + 90: {cur: 0x105, idx: 0x0}, + 91: {cur: 0x110, idx: 0x0}, + 92: {cur: 0x1b, idx: 0xc}, + 93: {cur: 0xeb, idx: 0xbc}, + 94: {cur: 0x44, idx: 0x25}, + 95: {cur: 0x44, idx: 0x20}, + 96: {cur: 0x13, idx: 0x2a1}, + 97: {cur: 0x2e, idx: 0x0}, + 98: {cur: 0x3a, idx: 0x2a4}, + 99: {cur: 0x44, idx: 0x0}, + 100: {cur: 0x63, idx: 0x2ad}, + 101: {cur: 0x72, idx: 0x2b3}, + 102: {cur: 0x7c, idx: 0x0}, + 103: {cur: 0x85, idx: 0x0}, + 104: {cur: 0x8d, idx: 0x0}, + 105: {cur: 0xc0, idx: 0x2bc}, + 106: {cur: 0xf6, idx: 0x0}, + 107: {cur: 0xfc, idx: 0x2c5}, + 108: {cur: 0x105, idx: 0x0}, + 109: {cur: 0x110, idx: 0x0}, + 110: {cur: 0x13, idx: 0x0}, + 111: {cur: 0x18, idx: 0x9}, + 112: {cur: 0x2e, idx: 0x0}, + 113: {cur: 0x3a, idx: 0x0}, + 114: {cur: 0x44, idx: 0x0}, + 115: {cur: 0x63, idx: 0x0}, + 116: {cur: 0x72, idx: 0x0}, + 117: {cur: 0x75, idx: 0x51}, + 118: {cur: 0x7c, idx: 0x0}, + 119: {cur: 0x85, idx: 0x25}, + 120: {cur: 0xb2, idx: 0x0}, + 121: {cur: 0xc0, idx: 0x0}, + 122: {cur: 0xd1, idx: 0x2ca}, + 123: {cur: 0xeb, idx: 0xbc}, + 124: {cur: 0xfc, idx: 0x0}, + 125: {cur: 0x110, idx: 0x0}, + 126: {cur: 0x117, idx: 0x0}, + 127: {cur: 0x18, idx: 0x2cf}, + 128: {cur: 0x4e, idx: 0x2d4}, + 129: {cur: 0x85, idx: 0x25}, + 130: {cur: 0xc9, idx: 0x2d9}, + 131: {cur: 0xd1, idx: 0x2de}, + 132: {cur: 0xf4, idx: 0x2e6}, + 133: {cur: 0x13, idx: 0xf8}, + 134: {cur: 0x2e, idx: 0x0}, + 135: {cur: 0x3a, idx: 0x0}, + 136: {cur: 0x44, idx: 0x25}, + 137: {cur: 0x5c, idx: 0x37}, + 138: {cur: 0xb2, idx: 0x0}, + 139: {cur: 0xeb, idx: 0xbc}, + 140: {cur: 0xfc, idx: 0x0}, + 141: {cur: 0x110, idx: 0x0}, + 142: {cur: 0x62, idx: 0x2eb}, + 143: {cur: 0x1b, idx: 0xc}, + 144: {cur: 0xeb, idx: 0xbc}, + 145: {cur: 0xd2, idx: 0xb2}, + 146: {cur: 0xfb, idx: 0x2f4}, + 147: {cur: 0xfc, idx: 0x4}, + 148: {cur: 0x7e, idx: 0x17b}, + 149: {cur: 0x13, idx: 0xf8}, + 150: {cur: 0x49, idx: 0x2f8}, + 151: {cur: 0x4e, idx: 0x2c}, + 152: {cur: 0x7c, idx: 0x0}, + 153: {cur: 0x7d, idx: 0x0}, + 154: {cur: 0x105, idx: 0x0}, + 155: {cur: 0x112, idx: 0x2fd}, + 156: {cur: 0xd2, idx: 0xb2}, + 157: {cur: 0x8d, idx: 0x0}, + 158: {cur: 0xeb, idx: 0xbc}, + 159: {cur: 0x13, idx: 0xf8}, + 160: {cur: 0x52, idx: 0x304}, + 161: {cur: 0xeb, idx: 0xbc}, + 162: {cur: 0xfc, idx: 0x4}, + 163: {cur: 0x86, idx: 0x308}, + 164: {cur: 0x12, idx: 0x30c}, + 165: {cur: 0x13, idx: 0xf8}, + 166: {cur: 0x20, idx: 0x310}, + 167: {cur: 0x22, idx: 0x314}, + 168: {cur: 0x50, idx: 0x31d}, + 169: {cur: 0x85, idx: 0x25}, + 170: {cur: 0xeb, idx: 0xbc}, + 171: {cur: 0xfc, idx: 0x4}, + 172: {cur: 0x5e, idx: 0x0}, + 173: {cur: 0x5e, idx: 0x0}, + 174: {cur: 0x99, idx: 0x2eb}, + 175: {cur: 0x13, idx: 0x0}, + 176: {cur: 0x85, idx: 0x25}, + 177: {cur: 0xc9, idx: 0xa6}, + 178: {cur: 0xeb, idx: 0xbc}, + 179: {cur: 0xfc, idx: 0x4}, + 180: {cur: 0x13, idx: 0xf8}, + 181: {cur: 0x33, idx: 0x332}, + 182: {cur: 0x7c, idx: 0x0}, + 183: {cur: 0x8d, idx: 0x336}, + 184: {cur: 0xeb, idx: 0x33c}, + 185: {cur: 0x109, idx: 0x0}, + 186: {cur: 0x86, idx: 0x308}, + 187: {cur: 0x13, idx: 0xf8}, + 188: {cur: 0x67, idx: 0xf2}, + 189: {cur: 0xeb, idx: 0xbc}, + 190: {cur: 0x6d, idx: 0x342}, + 191: {cur: 0xeb, idx: 0xbc}, + 192: {cur: 0xfc, idx: 0x4}, + 193: {cur: 0x85, idx: 0x25}, + 194: {cur: 0xfc, idx: 0x4}, + 195: {cur: 0x85, idx: 0x62}, + 196: {cur: 0xfc, idx: 0xcf}, + 197: {cur: 0x110, idx: 0x4}, + 198: {cur: 0x110, idx: 0x4}, + 199: {cur: 0x13, idx: 0x4}, + 200: {cur: 0x2e, idx: 0x0}, + 201: {cur: 0x3a, idx: 0x0}, + 202: {cur: 0x44, idx: 0x0}, + 203: {cur: 0x5e, idx: 0x0}, + 204: {cur: 0x63, idx: 0x0}, + 205: {cur: 0x72, idx: 0x0}, + 206: {cur: 0x7c, idx: 0x0}, + 207: {cur: 0x7d, idx: 0x0}, + 208: {cur: 0x85, idx: 0x0}, + 209: {cur: 0x8d, idx: 0x0}, + 210: {cur: 0xb2, idx: 0x0}, + 211: {cur: 0xc0, idx: 0x0}, + 212: {cur: 0xd7, idx: 0x7e}, + 213: {cur: 0xf6, idx: 0x0}, + 214: {cur: 0xfc, idx: 0x0}, + 215: {cur: 0x105, idx: 0x0}, + 216: {cur: 0x109, idx: 0x0}, + 217: {cur: 0x110, idx: 0x0}, + 218: {cur: 0x115, idx: 0x0}, + 219: {cur: 0x117, idx: 0x355}, + 220: {cur: 0x1a, idx: 0x4}, + 221: {cur: 0x24, idx: 0x359}, + 222: {cur: 0x25, idx: 0x4}, + 223: {cur: 0x32, idx: 0x4}, + 224: {cur: 0x35, idx: 0x16}, + 225: {cur: 0x39, idx: 0x4}, + 226: {cur: 0x3a, idx: 0x4}, + 227: {cur: 0x13, idx: 0x4}, + 228: {cur: 0xc0, idx: 0x4}, + 229: {cur: 0x13, idx: 0x4}, + 230: {cur: 0x52, idx: 0x304}, + 231: {cur: 0x110, idx: 0x4}, + 232: {cur: 0x59, idx: 0x231}, + 233: {cur: 0x60, idx: 0x4}, + 234: {cur: 0x61, idx: 0x3f}, + 235: {cur: 0x63, idx: 0x237}, + 236: {cur: 0x110, idx: 0x4}, + 237: {cur: 0x67, idx: 0xf2}, + 238: {cur: 0x63, idx: 0x237}, + 239: {cur: 0x68, idx: 0x3f}, + 240: {cur: 0x69, idx: 0x35d}, + 241: {cur: 0x71, idx: 0x4}, + 242: {cur: 0x83, idx: 0x4}, + 243: {cur: 0x86, idx: 0x308}, + 244: {cur: 0x13, idx: 0x4}, + 245: {cur: 0x110, idx: 0x4}, + 246: {cur: 0x8f, idx: 0x4}, + 247: {cur: 0x110, idx: 0x4}, + 248: {cur: 0x94, idx: 0x4}, + 249: {cur: 0x125, idx: 0xe9}, + 250: {cur: 0xa3, idx: 0x87}, + 251: {cur: 0xaa, idx: 0x35f}, + 252: {cur: 0x110, idx: 0x4}, + 253: {cur: 0x63, idx: 0x237}, + 254: {cur: 0xae, idx: 0x7e}, + 255: {cur: 0xb1, idx: 0x364}, + 256: {cur: 0xb5, idx: 0x94}, + 257: {cur: 0xb9, idx: 0x4}, + 258: {cur: 0x13, idx: 0x4}, + 259: {cur: 0xba, idx: 0x97}, + 260: {cur: 0x13, idx: 0x4}, + 261: {cur: 0xc0, idx: 0x4}, + 262: {cur: 0xc0, idx: 0x4}, + 263: {cur: 0xc6, idx: 0x8a}, + 264: {cur: 0xc7, idx: 0xa2}, + 265: {cur: 0xc8, idx: 0x7e}, + 266: {cur: 0xc0, idx: 0x4}, + 267: {cur: 0xd4, idx: 0xb6}, + 268: {cur: 0xd6, idx: 0x4}, + 269: {cur: 0xd7, idx: 0x367}, + 270: {cur: 0xdb, idx: 0x30}, + 271: {cur: 0xdc, idx: 0x4}, + 272: {cur: 0x63, idx: 0x237}, + 273: {cur: 0xdd, idx: 0x3f}, + 274: {cur: 0xe0, idx: 0x36a}, + 275: {cur: 0x63, idx: 0x237}, + 276: {cur: 0xe4, idx: 0x3f}, + 277: {cur: 0x8, idx: 0x36d}, + 278: {cur: 0xea, idx: 0x372}, + 279: {cur: 0xc0, idx: 0x4}, + 280: {cur: 0xf1, idx: 0xc0}, + 281: {cur: 0xf5, idx: 0x4}, + 282: {cur: 0x13, idx: 0x4}, + 283: {cur: 0xf7, idx: 0x23c}, + 284: {cur: 0xfb, idx: 0x2f4}, + 285: {cur: 0x110, idx: 0x4}, + 286: {cur: 0x107, idx: 0x374}, + 287: {cur: 0x108, idx: 0x377}, + 288: {cur: 0x125, idx: 0xe9}, + 289: {cur: 0x127, idx: 0x8a}, + 290: {cur: 0x13, idx: 0x0}, + 291: {cur: 0x2e, idx: 0x0}, + 292: {cur: 0x44, idx: 0x0}, + 293: {cur: 0x5c, idx: 0x37}, + 294: {cur: 0x63, idx: 0x0}, + 295: {cur: 0x72, idx: 0x0}, + 296: {cur: 0x7c, idx: 0x0}, + 297: {cur: 0x7d, idx: 0x0}, + 298: {cur: 0x85, idx: 0x0}, + 299: {cur: 0x8d, idx: 0x0}, + 300: {cur: 0xb2, idx: 0x0}, + 301: {cur: 0xc0, idx: 0x0}, + 302: {cur: 0xeb, idx: 0xbc}, + 303: {cur: 0xf6, idx: 0x0}, + 304: {cur: 0x109, idx: 0x0}, + 305: {cur: 0x110, idx: 0x0}, + 306: {cur: 0x115, idx: 0x0}, + 307: {cur: 0x3a, idx: 0x0}, + 308: {cur: 0x5e, idx: 0x0}, + 309: {cur: 0xeb, idx: 0x0}, + 310: {cur: 0xfc, idx: 0x0}, + 311: {cur: 0x105, idx: 0x0}, + 312: {cur: 0x11, idx: 0x4}, + 313: {cur: 0xfc, idx: 0xcf}, + 314: {cur: 0x27, idx: 0x10}, + 315: {cur: 0x2e, idx: 0x13}, + 316: {cur: 0x39, idx: 0x4}, + 317: {cur: 0x41, idx: 0x4}, + 318: {cur: 0xfc, idx: 0xcf}, + 319: {cur: 0x45, idx: 0x4}, + 320: {cur: 0xfc, idx: 0xcf}, + 321: {cur: 0x47, idx: 0x28}, + 322: {cur: 0x4b, idx: 0x4}, + 323: {cur: 0xfc, idx: 0xcf}, + 324: {cur: 0x53, idx: 0x264}, + 325: {cur: 0xfc, idx: 0xcf}, + 326: {cur: 0xfc, idx: 0x4}, + 327: {cur: 0x109, idx: 0xd7}, + 328: {cur: 0x6e, idx: 0x49}, + 329: {cur: 0x73, idx: 0x4f}, + 330: {cur: 0xb2, idx: 0x4}, + 331: {cur: 0xbc, idx: 0x9b}, + 332: {cur: 0xc2, idx: 0x387}, + 333: {cur: 0xc4, idx: 0x38b}, + 334: {cur: 0xc7, idx: 0xa2}, + 335: {cur: 0xfc, idx: 0x4}, + 336: {cur: 0xcc, idx: 0x38e}, + 337: {cur: 0xfc, idx: 0x4}, + 338: {cur: 0x85, idx: 0x25}, + 339: {cur: 0xfc, idx: 0x4}, + 340: {cur: 0xfc, idx: 0xcf}, + 341: {cur: 0x101, idx: 0x4}, + 342: {cur: 0x104, idx: 0x392}, + 343: {cur: 0x13, idx: 0xf8}, + 344: {cur: 0x57, idx: 0x30}, + 345: {cur: 0x85, idx: 0x25}, + 346: {cur: 0xeb, idx: 0xbc}, + 347: {cur: 0xfc, idx: 0x4}, + 348: {cur: 0x5c, idx: 0x37}, + 349: {cur: 0xeb, idx: 0xbc}, + 350: {cur: 0x4, idx: 0x396}, + 351: {cur: 0x3a, idx: 0x2a4}, + 352: {cur: 0x44, idx: 0x399}, + 353: {cur: 0x72, idx: 0x39e}, + 354: {cur: 0x7f, idx: 0x3a2}, + 355: {cur: 0x85, idx: 0x25}, + 356: {cur: 0xb2, idx: 0x3ab}, + 357: {cur: 0xc0, idx: 0x3af}, + 358: {cur: 0xeb, idx: 0xbc}, + 359: {cur: 0xfc, idx: 0x4}, + 360: {cur: 0x110, idx: 0x3b3}, + 361: {cur: 0x6a, idx: 0x46}, + 362: {cur: 0xab, idx: 0x3b7}, + 363: {cur: 0x13, idx: 0x0}, + 364: {cur: 0x2e, idx: 0x0}, + 365: {cur: 0x3a, idx: 0x0}, + 366: {cur: 0x44, idx: 0x0}, + 367: {cur: 0x5f, idx: 0x3ba}, + 368: {cur: 0x72, idx: 0x0}, + 369: {cur: 0x7c, idx: 0x0}, + 370: {cur: 0x7d, idx: 0x0}, + 371: {cur: 0x85, idx: 0x25}, + 372: {cur: 0x8d, idx: 0x0}, + 373: {cur: 0xb2, idx: 0x0}, + 374: {cur: 0xc0, idx: 0x0}, + 375: {cur: 0xf6, idx: 0x0}, + 376: {cur: 0xfc, idx: 0x4}, + 377: {cur: 0x105, idx: 0x0}, + 378: {cur: 0x110, idx: 0x0}, + 379: {cur: 0x117, idx: 0x0}, + 380: {cur: 0x85, idx: 0x25}, + 381: {cur: 0xc7, idx: 0xa2}, + 382: {cur: 0xeb, idx: 0xbc}, + 383: {cur: 0xfc, idx: 0x4}, + 384: {cur: 0x52, idx: 0x30}, + 385: {cur: 0x52, idx: 0x304}, + 386: {cur: 0x11, idx: 0x3bd}, + 387: {cur: 0x13, idx: 0x3c1}, + 388: {cur: 0x1d, idx: 0x3c5}, + 389: {cur: 0x25, idx: 0x3c8}, + 390: {cur: 0x26, idx: 0x3cc}, + 391: {cur: 0x32, idx: 0x3d0}, + 392: {cur: 0x39, idx: 0x3d4}, + 393: {cur: 0x3a, idx: 0x2a4}, + 394: {cur: 0x41, idx: 0x3d8}, + 395: {cur: 0x44, idx: 0x0}, + 396: {cur: 0x45, idx: 0x3dc}, + 397: {cur: 0x4d, idx: 0x3e0}, + 398: {cur: 0x60, idx: 0x3e9}, + 399: {cur: 0x61, idx: 0x3ed}, + 400: {cur: 0x62, idx: 0x2eb}, + 401: {cur: 0x63, idx: 0x3f2}, + 402: {cur: 0x68, idx: 0x3f7}, + 403: {cur: 0x72, idx: 0x0}, + 404: {cur: 0x79, idx: 0x3fc}, + 405: {cur: 0x7a, idx: 0x401}, + 406: {cur: 0x82, idx: 0x406}, + 407: {cur: 0x85, idx: 0x0}, + 408: {cur: 0x92, idx: 0x40c}, + 409: {cur: 0xad, idx: 0x411}, + 410: {cur: 0xb2, idx: 0x3ab}, + 411: {cur: 0xb9, idx: 0x416}, + 412: {cur: 0xc0, idx: 0x3af}, + 413: {cur: 0xce, idx: 0x41d}, + 414: {cur: 0xd6, idx: 0x424}, + 415: {cur: 0xdc, idx: 0x428}, + 416: {cur: 0xe2, idx: 0x42c}, + 417: {cur: 0xf5, idx: 0x430}, + 418: {cur: 0xf6, idx: 0x0}, + 419: {cur: 0xfc, idx: 0x434}, + 420: {cur: 0x101, idx: 0x438}, + 421: {cur: 0x108, idx: 0x377}, + 422: {cur: 0x110, idx: 0x0}, + 423: {cur: 0x117, idx: 0x43c}, + 424: {cur: 0x24, idx: 0x359}, + 425: {cur: 0x11, idx: 0x0}, + 426: {cur: 0x13, idx: 0x444}, + 427: {cur: 0x25, idx: 0x0}, + 428: {cur: 0x26, idx: 0x0}, + 429: {cur: 0x32, idx: 0x0}, + 430: {cur: 0x39, idx: 0x0}, + 431: {cur: 0x3a, idx: 0x4}, + 432: {cur: 0x41, idx: 0x0}, + 433: {cur: 0x44, idx: 0x20}, + 434: {cur: 0x45, idx: 0x0}, + 435: {cur: 0x60, idx: 0x0}, + 436: {cur: 0x61, idx: 0x0}, + 437: {cur: 0x63, idx: 0x3f}, + 438: {cur: 0x68, idx: 0x0}, + 439: {cur: 0x72, idx: 0x44a}, + 440: {cur: 0x7c, idx: 0x0}, + 441: {cur: 0x7d, idx: 0x0}, + 442: {cur: 0x85, idx: 0x25}, + 443: {cur: 0x8d, idx: 0x0}, + 444: {cur: 0x92, idx: 0x0}, + 445: {cur: 0xb2, idx: 0x0}, + 446: {cur: 0xb9, idx: 0x0}, + 447: {cur: 0xc0, idx: 0x450}, + 448: {cur: 0xd6, idx: 0x0}, + 449: {cur: 0xdc, idx: 0x456}, + 450: {cur: 0xe2, idx: 0x0}, + 451: {cur: 0xf5, idx: 0x0}, + 452: {cur: 0xfc, idx: 0x45c}, + 453: {cur: 0x101, idx: 0x0}, + 454: {cur: 0x105, idx: 0x0}, + 455: {cur: 0x109, idx: 0x0}, + 456: {cur: 0x115, idx: 0x0}, + 457: {cur: 0x117, idx: 0x0}, + 458: {cur: 0x3b, idx: 0x32a}, + 459: {cur: 0x51, idx: 0x22d}, + 460: {cur: 0x54, idx: 0x462}, + 461: {cur: 0x6a, idx: 0x46}, + 462: {cur: 0x76, idx: 0x465}, + 463: {cur: 0x89, idx: 0x6b}, + 464: {cur: 0x62, idx: 0x0}, + 465: {cur: 0x99, idx: 0x2eb}, + 466: {cur: 0xa3, idx: 0x87}, + 467: {cur: 0xab, idx: 0x3b7}, + 468: {cur: 0xae, idx: 0x7e}, + 469: {cur: 0xd4, idx: 0xb6}, + 470: {cur: 0xd7, idx: 0x367}, + 471: {cur: 0xe9, idx: 0x467}, + 472: {cur: 0xf0, idx: 0x46a}, + 473: {cur: 0x107, idx: 0x374}, + 474: {cur: 0x13, idx: 0xf8}, + 475: {cur: 0x3a, idx: 0x9b}, + 476: {cur: 0x60, idx: 0x16e}, + 477: {cur: 0xd6, idx: 0x28a}, + 478: {cur: 0xeb, idx: 0xbc}, + 479: {cur: 0x117, idx: 0x0}, + 480: {cur: 0x85, idx: 0x25}, + 481: {cur: 0xeb, idx: 0xbc}, + 482: {cur: 0xfc, idx: 0x4}, + 483: {cur: 0xeb, idx: 0xbc}, + 484: {cur: 0xfc, idx: 0x4}, + 485: {cur: 0x5c, idx: 0x37}, + 486: {cur: 0xb2, idx: 0x3ab}, + 487: {cur: 0xeb, idx: 0xbc}, + 488: {cur: 0xfc, idx: 0x4}, + 489: {cur: 0x12, idx: 0x30c}, + 490: {cur: 0x85, idx: 0x25}, + 491: {cur: 0xfc, idx: 0x4}, + 492: {cur: 0xeb, idx: 0xbc}, + 493: {cur: 0x86, idx: 0x308}, + 494: {cur: 0xba, idx: 0x97}, + 495: {cur: 0x67, idx: 0xf2}, + 496: {cur: 0xfc, idx: 0x4}, + 497: {cur: 0x44, idx: 0x47c}, + 498: {cur: 0x7a, idx: 0x487}, + 499: {cur: 0x85, idx: 0x25}, + 500: {cur: 0xeb, idx: 0xbc}, + 501: {cur: 0xfc, idx: 0x4}, + 502: {cur: 0xeb, idx: 0xbc}, + 503: {cur: 0xfc, idx: 0x4}, + 504: {cur: 0x13, idx: 0x0}, + 505: {cur: 0x2e, idx: 0x0}, + 506: {cur: 0x3a, idx: 0x0}, + 507: {cur: 0x44, idx: 0x0}, + 508: {cur: 0x5e, idx: 0x0}, + 509: {cur: 0x63, idx: 0x0}, + 510: {cur: 0x72, idx: 0x0}, + 511: {cur: 0x7c, idx: 0x0}, + 512: {cur: 0x7d, idx: 0x0}, + 513: {cur: 0x85, idx: 0x0}, + 514: {cur: 0x8d, idx: 0x0}, + 515: {cur: 0xb2, idx: 0x0}, + 516: {cur: 0xc0, idx: 0x0}, + 517: {cur: 0xf6, idx: 0x0}, + 518: {cur: 0xfc, idx: 0x0}, + 519: {cur: 0x105, idx: 0x0}, + 520: {cur: 0x110, idx: 0x0}, + 521: {cur: 0x117, idx: 0x0}, + 522: {cur: 0x18, idx: 0x9}, + 523: {cur: 0x13, idx: 0x0}, + 524: {cur: 0x85, idx: 0x25}, + 525: {cur: 0xc9, idx: 0xa6}, + 526: {cur: 0xeb, idx: 0xbc}, + 527: {cur: 0xfc, idx: 0x4}, + 528: {cur: 0x13, idx: 0x0}, + 529: {cur: 0x2e, idx: 0x0}, + 530: {cur: 0x3a, idx: 0x0}, + 531: {cur: 0x44, idx: 0x0}, + 532: {cur: 0x5e, idx: 0x0}, + 533: {cur: 0x63, idx: 0x0}, + 534: {cur: 0x72, idx: 0x0}, + 535: {cur: 0x77, idx: 0x54}, + 536: {cur: 0x7c, idx: 0x0}, + 537: {cur: 0x7d, idx: 0x0}, + 538: {cur: 0x85, idx: 0x25}, + 539: {cur: 0x8d, idx: 0x0}, + 540: {cur: 0xb2, idx: 0x0}, + 541: {cur: 0xc0, idx: 0x0}, + 542: {cur: 0xf6, idx: 0x0}, + 543: {cur: 0xfc, idx: 0x0}, + 544: {cur: 0x105, idx: 0x0}, + 545: {cur: 0x110, idx: 0x0}, + 546: {cur: 0x7, idx: 0x498}, + 547: {cur: 0xeb, idx: 0xbc}, + 548: {cur: 0xfc, idx: 0x4}, + 549: {cur: 0x13, idx: 0xf8}, + 550: {cur: 0x78, idx: 0x57}, + 551: {cur: 0x7d, idx: 0x7e}, + 552: {cur: 0xeb, idx: 0xbc}, + 553: {cur: 0xba, idx: 0x97}, + 554: {cur: 0x44, idx: 0x25}, + 555: {cur: 0x13, idx: 0x0}, + 556: {cur: 0x2e, idx: 0x0}, + 557: {cur: 0x3a, idx: 0x0}, + 558: {cur: 0x5e, idx: 0x0}, + 559: {cur: 0x63, idx: 0x0}, + 560: {cur: 0x7d, idx: 0x0}, + 561: {cur: 0x8d, idx: 0x0}, + 562: {cur: 0xb2, idx: 0x0}, + 563: {cur: 0xc0, idx: 0x0}, + 564: {cur: 0xf6, idx: 0x0}, + 565: {cur: 0xfc, idx: 0x0}, + 566: {cur: 0x105, idx: 0x0}, + 567: {cur: 0x2e, idx: 0x0}, + 568: {cur: 0x72, idx: 0x0}, + 569: {cur: 0x85, idx: 0x0}, + 570: {cur: 0x8d, idx: 0x0}, + 571: {cur: 0xb2, idx: 0x0}, + 572: {cur: 0xeb, idx: 0xbc}, + 573: {cur: 0xf6, idx: 0x0}, + 574: {cur: 0xfc, idx: 0x0}, + 575: {cur: 0x44, idx: 0x49f}, + 576: {cur: 0x85, idx: 0x4a3}, + 577: {cur: 0xfc, idx: 0x4}, + 578: {cur: 0xf7, idx: 0x23c}, + 579: {cur: 0x13, idx: 0x0}, + 580: {cur: 0x44, idx: 0x0}, + 581: {cur: 0x65, idx: 0x42}, + 582: {cur: 0x72, idx: 0x0}, + 583: {cur: 0x7c, idx: 0x0}, + 584: {cur: 0x7d, idx: 0x0}, + 585: {cur: 0x85, idx: 0x0}, + 586: {cur: 0x8d, idx: 0x0}, + 587: {cur: 0xc0, idx: 0x0}, + 588: {cur: 0x105, idx: 0x0}, + 589: {cur: 0x54, idx: 0x462}, + 590: {cur: 0x86, idx: 0x308}, + 591: {cur: 0xf7, idx: 0x23c}, + 592: {cur: 0x13, idx: 0xf8}, + 593: {cur: 0x4c, idx: 0x4ae}, + 594: {cur: 0xeb, idx: 0xbc}, + 595: {cur: 0x86, idx: 0x308}, + 596: {cur: 0x90, idx: 0x72}, + 597: {cur: 0xd2, idx: 0xb2}, + 598: {cur: 0xeb, idx: 0xbc}, + 599: {cur: 0xfc, idx: 0x4}, + 600: {cur: 0x52, idx: 0x304}, + 601: {cur: 0x86, idx: 0x308}, + 602: {cur: 0x88, idx: 0x67}, + 603: {cur: 0xeb, idx: 0xbc}, + 604: {cur: 0xfc, idx: 0x4}, + 605: {cur: 0xeb, idx: 0xbc}, + 606: {cur: 0xfc, idx: 0x4}, + 607: {cur: 0x13, idx: 0xf8}, + 608: {cur: 0xf7, idx: 0x23c}, + 609: {cur: 0x13, idx: 0x0}, + 610: {cur: 0x2e, idx: 0x0}, + 611: {cur: 0x3a, idx: 0x0}, + 612: {cur: 0x63, idx: 0x0}, + 613: {cur: 0x72, idx: 0x0}, + 614: {cur: 0x7c, idx: 0x0}, + 615: {cur: 0x7d, idx: 0x0}, + 616: {cur: 0x87, idx: 0x4bf}, + 617: {cur: 0x8d, idx: 0x0}, + 618: {cur: 0xb2, idx: 0x0}, + 619: {cur: 0xc0, idx: 0x0}, + 620: {cur: 0xeb, idx: 0xbc}, + 621: {cur: 0xf6, idx: 0x0}, + 622: {cur: 0xfc, idx: 0x0}, + 623: {cur: 0x110, idx: 0x0}, + 624: {cur: 0xf7, idx: 0x23c}, + 625: {cur: 0x12, idx: 0x30c}, + 626: {cur: 0x13, idx: 0xf8}, + 627: {cur: 0x85, idx: 0x25}, + 628: {cur: 0xeb, idx: 0xbc}, + 629: {cur: 0xfc, idx: 0x4}, + 630: {cur: 0xfb, idx: 0x2f4}, + 631: {cur: 0xfc, idx: 0x4}, + 632: {cur: 0x3b, idx: 0x32a}, + 633: {cur: 0x9, idx: 0x1}, + 634: {cur: 0x91, idx: 0x76}, + 635: {cur: 0xeb, idx: 0xbc}, + 636: {cur: 0x7e, idx: 0x17b}, + 637: {cur: 0x13, idx: 0x0}, + 638: {cur: 0x2e, idx: 0x0}, + 639: {cur: 0x3a, idx: 0x0}, + 640: {cur: 0x44, idx: 0x0}, + 641: {cur: 0x63, idx: 0x0}, + 642: {cur: 0x72, idx: 0x0}, + 643: {cur: 0x7c, idx: 0x0}, + 644: {cur: 0x7d, idx: 0x0}, + 645: {cur: 0x85, idx: 0x0}, + 646: {cur: 0x8d, idx: 0x0}, + 647: {cur: 0xb2, idx: 0x0}, + 648: {cur: 0xc0, idx: 0x0}, + 649: {cur: 0xf6, idx: 0x0}, + 650: {cur: 0xfc, idx: 0x0}, + 651: {cur: 0x105, idx: 0x0}, + 652: {cur: 0x109, idx: 0x0}, + 653: {cur: 0x110, idx: 0x0}, + 654: {cur: 0x115, idx: 0x0}, + 655: {cur: 0x117, idx: 0x0}, + 656: {cur: 0x3b, idx: 0x32a}, + 657: {cur: 0x86, idx: 0x308}, + 658: {cur: 0x86, idx: 0x308}, + 659: {cur: 0x13, idx: 0xf8}, + 660: {cur: 0x85, idx: 0x25}, + 661: {cur: 0x9b, idx: 0x84}, + 662: {cur: 0xeb, idx: 0xbc}, + 663: {cur: 0xfc, idx: 0x4}, + 664: {cur: 0x86, idx: 0x308}, + 665: {cur: 0xf7, idx: 0x23c}, + 666: {cur: 0x86, idx: 0x308}, + 667: {cur: 0xae, idx: 0x7e}, + 668: {cur: 0xa3, idx: 0x87}, + 669: {cur: 0xb8, idx: 0x4cc}, + 670: {cur: 0x13, idx: 0x0}, + 671: {cur: 0x44, idx: 0x0}, + 672: {cur: 0x63, idx: 0x0}, + 673: {cur: 0x72, idx: 0x0}, + 674: {cur: 0x7c, idx: 0x0}, + 675: {cur: 0x7d, idx: 0x0}, + 676: {cur: 0x85, idx: 0x0}, + 677: {cur: 0x8d, idx: 0x0}, + 678: {cur: 0xa5, idx: 0x4d0}, + 679: {cur: 0xc0, idx: 0x0}, + 680: {cur: 0xf6, idx: 0x0}, + 681: {cur: 0x105, idx: 0x0}, + 682: {cur: 0x85, idx: 0x25}, + 683: {cur: 0xeb, idx: 0xbc}, + 684: {cur: 0xfc, idx: 0x4}, + 685: {cur: 0xa9, idx: 0x8c}, + 686: {cur: 0xeb, idx: 0xbc}, + 687: {cur: 0xfc, idx: 0x4}, + 688: {cur: 0xeb, idx: 0xbc}, + 689: {cur: 0xfc, idx: 0x4}, + 690: {cur: 0x3a, idx: 0x0}, + 691: {cur: 0xb2, idx: 0x0}, + 692: {cur: 0xb5, idx: 0x94}, + 693: {cur: 0xfc, idx: 0x0}, + 694: {cur: 0x26, idx: 0x4}, + 695: {cur: 0xdc, idx: 0x4}, + 696: {cur: 0x8, idx: 0x4dc}, + 697: {cur: 0x14, idx: 0x4e0}, + 698: {cur: 0x76, idx: 0x465}, + 699: {cur: 0xa8, idx: 0x8a}, + 700: {cur: 0xc2, idx: 0x387}, + 701: {cur: 0xeb, idx: 0xbc}, + 702: {cur: 0xf5, idx: 0x21b}, + 703: {cur: 0xfc, idx: 0x4}, + 704: {cur: 0xb9, idx: 0x4}, + 705: {cur: 0x13, idx: 0x0}, + 706: {cur: 0x2e, idx: 0x0}, + 707: {cur: 0x3a, idx: 0x0}, + 708: {cur: 0x44, idx: 0x0}, + 709: {cur: 0x72, idx: 0x0}, + 710: {cur: 0x7c, idx: 0x0}, + 711: {cur: 0x7d, idx: 0x0}, + 712: {cur: 0x85, idx: 0x0}, + 713: {cur: 0x8d, idx: 0x0}, + 714: {cur: 0xb2, idx: 0x0}, + 715: {cur: 0xbe, idx: 0x30}, + 716: {cur: 0xc0, idx: 0x0}, + 717: {cur: 0xf6, idx: 0x0}, + 718: {cur: 0xfc, idx: 0x0}, + 719: {cur: 0x105, idx: 0x0}, + 720: {cur: 0x109, idx: 0x0}, + 721: {cur: 0x110, idx: 0x0}, + 722: {cur: 0x117, idx: 0x0}, + 723: {cur: 0xbf, idx: 0x4e4}, + 724: {cur: 0xeb, idx: 0xbc}, + 725: {cur: 0x13, idx: 0xf8}, + 726: {cur: 0x3a, idx: 0x9b}, + 727: {cur: 0x60, idx: 0x16e}, + 728: {cur: 0xd6, idx: 0x28a}, + 729: {cur: 0xeb, idx: 0xbc}, + 730: {cur: 0x117, idx: 0x0}, + 731: {cur: 0x14, idx: 0x4f8}, + 732: {cur: 0xfc, idx: 0x4}, + 733: {cur: 0x8, idx: 0x36d}, + 734: {cur: 0xe2, idx: 0x4}, + 735: {cur: 0x8, idx: 0x36d}, + 736: {cur: 0x13, idx: 0x0}, + 737: {cur: 0x2e, idx: 0x0}, + 738: {cur: 0x3a, idx: 0x0}, + 739: {cur: 0x44, idx: 0x0}, + 740: {cur: 0x63, idx: 0x0}, + 741: {cur: 0x72, idx: 0x0}, + 742: {cur: 0x7c, idx: 0x0}, + 743: {cur: 0x7d, idx: 0x0}, + 744: {cur: 0x85, idx: 0x0}, + 745: {cur: 0x8d, idx: 0x0}, + 746: {cur: 0xb2, idx: 0x0}, + 747: {cur: 0xbe, idx: 0x30}, + 748: {cur: 0xc0, idx: 0x0}, + 749: {cur: 0xf6, idx: 0x0}, + 750: {cur: 0xfc, idx: 0x0}, + 751: {cur: 0x105, idx: 0x0}, + 752: {cur: 0x109, idx: 0x0}, + 753: {cur: 0x110, idx: 0x0}, + 754: {cur: 0x117, idx: 0x0}, + 755: {cur: 0x63, idx: 0x237}, + 756: {cur: 0xe4, idx: 0x3f}, + 757: {cur: 0xfb, idx: 0x2f4}, + 758: {cur: 0x5d, idx: 0x258}, + 759: {cur: 0x86, idx: 0x308}, + 760: {cur: 0x85, idx: 0x25}, + 761: {cur: 0xfc, idx: 0x4}, + 762: {cur: 0x65, idx: 0x42}, + 763: {cur: 0xfc, idx: 0x4}, + 764: {cur: 0x65, idx: 0x0}, + 765: {cur: 0xd2, idx: 0xb2}, + 766: {cur: 0xeb, idx: 0xbc}, + 767: {cur: 0xc8, idx: 0x4fd}, + 768: {cur: 0x13, idx: 0x0}, + 769: {cur: 0x3a, idx: 0x0}, + 770: {cur: 0x44, idx: 0x0}, + 771: {cur: 0x63, idx: 0x0}, + 772: {cur: 0x72, idx: 0x0}, + 773: {cur: 0x7c, idx: 0x0}, + 774: {cur: 0x7d, idx: 0x0}, + 775: {cur: 0x85, idx: 0x0}, + 776: {cur: 0x8d, idx: 0x0}, + 777: {cur: 0xb2, idx: 0x0}, + 778: {cur: 0xc0, idx: 0x0}, + 779: {cur: 0xc9, idx: 0xa6}, + 780: {cur: 0xf6, idx: 0x0}, + 781: {cur: 0xfc, idx: 0x0}, + 782: {cur: 0x105, idx: 0x0}, + 783: {cur: 0x4, idx: 0x396}, + 784: {cur: 0x13, idx: 0xf8}, + 785: {cur: 0xcb, idx: 0x504}, + 786: {cur: 0xeb, idx: 0xbc}, + 787: {cur: 0x9, idx: 0x1}, + 788: {cur: 0x4c, idx: 0x4ae}, + 789: {cur: 0xcb, idx: 0x509}, + 790: {cur: 0x99, idx: 0x2eb}, + 791: {cur: 0xaa, idx: 0x35f}, + 792: {cur: 0xb8, idx: 0x4cc}, + 793: {cur: 0xcb, idx: 0x4ae}, + 794: {cur: 0xe5, idx: 0xb9}, + 795: {cur: 0xc4, idx: 0x38b}, + 796: {cur: 0x27, idx: 0x10}, + 797: {cur: 0xc4, idx: 0x0}, + 798: {cur: 0xc4, idx: 0x0}, + 799: {cur: 0xfc, idx: 0x4}, + 800: {cur: 0x24, idx: 0x359}, + 801: {cur: 0x13, idx: 0x0}, + 802: {cur: 0x2e, idx: 0x0}, + 803: {cur: 0x3a, idx: 0x0}, + 804: {cur: 0x44, idx: 0x0}, + 805: {cur: 0x5e, idx: 0x0}, + 806: {cur: 0x63, idx: 0x0}, + 807: {cur: 0x72, idx: 0x0}, + 808: {cur: 0x7c, idx: 0x0}, + 809: {cur: 0x7d, idx: 0x0}, + 810: {cur: 0x85, idx: 0x0}, + 811: {cur: 0x8d, idx: 0x0}, + 812: {cur: 0xb2, idx: 0x0}, + 813: {cur: 0xc0, idx: 0x0}, + 814: {cur: 0xf6, idx: 0x0}, + 815: {cur: 0xfc, idx: 0x0}, + 816: {cur: 0x105, idx: 0x0}, + 817: {cur: 0x110, idx: 0x0}, + 818: {cur: 0xa2, idx: 0x4f}, + 819: {cur: 0xf7, idx: 0x23c}, + 820: {cur: 0x0, idx: 0x510}, + 821: {cur: 0x85, idx: 0x25}, + 822: {cur: 0xd2, idx: 0xb2}, + 823: {cur: 0xd3, idx: 0x18}, + 824: {cur: 0xeb, idx: 0xbc}, + 825: {cur: 0xef, idx: 0x519}, + 826: {cur: 0xf8, idx: 0xcb}, + 827: {cur: 0xfc, idx: 0x4}, + 828: {cur: 0x37, idx: 0x258}, + 829: {cur: 0xd3, idx: 0x0}, + 830: {cur: 0x87, idx: 0x4bf}, + 831: {cur: 0x90, idx: 0x72}, + 832: {cur: 0xa2, idx: 0x4f}, + 833: {cur: 0xd4, idx: 0xb6}, + 834: {cur: 0xf7, idx: 0x23c}, + 835: {cur: 0xd2, idx: 0xb2}, + 836: {cur: 0x86, idx: 0x308}, + 837: {cur: 0xf7, idx: 0x23c}, + 838: {cur: 0xc8, idx: 0x7e}, + 839: {cur: 0x52, idx: 0x520}, + 840: {cur: 0xbe, idx: 0x30}, + 841: {cur: 0xdb, idx: 0x524}, + 842: {cur: 0xeb, idx: 0xbc}, + 843: {cur: 0xbe, idx: 0x528}, + 844: {cur: 0xdb, idx: 0x30}, + 845: {cur: 0xb8, idx: 0x4cc}, + 846: {cur: 0x93, idx: 0x52c}, + 847: {cur: 0xeb, idx: 0xbc}, + 848: {cur: 0x115, idx: 0x534}, + 849: {cur: 0x13, idx: 0x0}, + 850: {cur: 0x2e, idx: 0x0}, + 851: {cur: 0x3a, idx: 0x0}, + 852: {cur: 0x44, idx: 0x0}, + 853: {cur: 0x63, idx: 0x0}, + 854: {cur: 0x72, idx: 0x0}, + 855: {cur: 0x7c, idx: 0x544}, + 856: {cur: 0x7d, idx: 0x0}, + 857: {cur: 0x85, idx: 0x0}, + 858: {cur: 0x8d, idx: 0x0}, + 859: {cur: 0xc0, idx: 0x0}, + 860: {cur: 0xf6, idx: 0x0}, + 861: {cur: 0xfc, idx: 0x0}, + 862: {cur: 0x105, idx: 0x0}, + 863: {cur: 0x13, idx: 0x0}, + 864: {cur: 0x2e, idx: 0x0}, + 865: {cur: 0x3a, idx: 0x0}, + 866: {cur: 0x63, idx: 0x0}, + 867: {cur: 0x85, idx: 0x25}, + 868: {cur: 0xb2, idx: 0x0}, + 869: {cur: 0xc0, idx: 0x0}, + 870: {cur: 0xf6, idx: 0x0}, + 871: {cur: 0xfc, idx: 0x4}, + 872: {cur: 0x110, idx: 0x0}, + 873: {cur: 0xe1, idx: 0x235}, + 874: {cur: 0x51, idx: 0x22d}, + 875: {cur: 0x5d, idx: 0x258}, + 876: {cur: 0x86, idx: 0x308}, + 877: {cur: 0x6, idx: 0x548}, + 878: {cur: 0xeb, idx: 0xbc}, + 879: {cur: 0xa5, idx: 0x54e}, + 880: {cur: 0x13, idx: 0x0}, + 881: {cur: 0x18, idx: 0x2cf}, + 882: {cur: 0x85, idx: 0x25}, + 883: {cur: 0x8d, idx: 0x0}, + 884: {cur: 0xc0, idx: 0x0}, + 885: {cur: 0x105, idx: 0x0}, + 886: {cur: 0x13, idx: 0x0}, + 887: {cur: 0x18, idx: 0x9}, + 888: {cur: 0x85, idx: 0x25}, + 889: {cur: 0x8d, idx: 0x0}, + 890: {cur: 0xc0, idx: 0x0}, + 891: {cur: 0x105, idx: 0x0}, + 892: {cur: 0x13, idx: 0x0}, + 893: {cur: 0x1a, idx: 0x24c}, + 894: {cur: 0x25, idx: 0x13a}, + 895: {cur: 0x2e, idx: 0x555}, + 896: {cur: 0x32, idx: 0x142}, + 897: {cur: 0x39, idx: 0x146}, + 898: {cur: 0x44, idx: 0x0}, + 899: {cur: 0x52, idx: 0x520}, + 900: {cur: 0x53, idx: 0x264}, + 901: {cur: 0x57, idx: 0x559}, + 902: {cur: 0x58, idx: 0x55d}, + 903: {cur: 0x63, idx: 0x0}, + 904: {cur: 0x72, idx: 0x0}, + 905: {cur: 0x79, idx: 0x562}, + 906: {cur: 0x7d, idx: 0x0}, + 907: {cur: 0x81, idx: 0x567}, + 908: {cur: 0x83, idx: 0x18c}, + 909: {cur: 0x85, idx: 0x0}, + 910: {cur: 0x8d, idx: 0x0}, + 911: {cur: 0xbe, idx: 0x528}, + 912: {cur: 0xc0, idx: 0x0}, + 913: {cur: 0xdb, idx: 0x30}, + 914: {cur: 0xf6, idx: 0x0}, + 915: {cur: 0x105, idx: 0x0}, + 916: {cur: 0x86, idx: 0x308}, + 917: {cur: 0xeb, idx: 0xbc}, + 918: {cur: 0xf7, idx: 0x23c}, + 919: {cur: 0x3b, idx: 0x32a}, + 920: {cur: 0xfb, idx: 0x2f4}, + 921: {cur: 0x85, idx: 0x25}, + 922: {cur: 0xeb, idx: 0xbc}, + 923: {cur: 0xfc, idx: 0x4}, + 924: {cur: 0x93, idx: 0x56b}, + 925: {cur: 0xb5, idx: 0x94}, + 926: {cur: 0xdc, idx: 0x28e}, + 927: {cur: 0xb5, idx: 0x94}, + 928: {cur: 0xdc, idx: 0x4}, + 929: {cur: 0xfc, idx: 0xcf}, + 930: {cur: 0xeb, idx: 0xbc}, + 931: {cur: 0xfc, idx: 0x4}, + 932: {cur: 0xfb, idx: 0x2f4}, + 933: {cur: 0x86, idx: 0x308}, + 934: {cur: 0xed, idx: 0x56f}, + 935: {cur: 0xfc, idx: 0x4}, + 936: {cur: 0x13, idx: 0xf8}, + 937: {cur: 0x85, idx: 0x25}, + 938: {cur: 0x5d, idx: 0x258}, + 939: {cur: 0x59, idx: 0x231}, + 940: {cur: 0x5e, idx: 0x0}, + 941: {cur: 0x63, idx: 0x0}, + 942: {cur: 0x13, idx: 0x577}, + 943: {cur: 0xc0, idx: 0x57c}, + 944: {cur: 0xf1, idx: 0xc0}, + 945: {cur: 0x13, idx: 0xf8}, + 946: {cur: 0x85, idx: 0x25}, + 947: {cur: 0xeb, idx: 0xbc}, + 948: {cur: 0xf4, idx: 0xc3}, + 949: {cur: 0xfc, idx: 0x4}, + 950: {cur: 0xd2, idx: 0xb2}, + 951: {cur: 0xfc, idx: 0x4}, + 952: {cur: 0x44, idx: 0x4a3}, + 953: {cur: 0xfc, idx: 0x4}, + 954: {cur: 0x13, idx: 0x0}, + 955: {cur: 0x2e, idx: 0x0}, + 956: {cur: 0x3a, idx: 0x0}, + 957: {cur: 0x44, idx: 0x0}, + 958: {cur: 0x5e, idx: 0x0}, + 959: {cur: 0x63, idx: 0x0}, + 960: {cur: 0x72, idx: 0x0}, + 961: {cur: 0x7c, idx: 0x0}, + 962: {cur: 0x7d, idx: 0x0}, + 963: {cur: 0x85, idx: 0x25}, + 964: {cur: 0x8d, idx: 0x0}, + 965: {cur: 0xb2, idx: 0x0}, + 966: {cur: 0xc0, idx: 0x0}, + 967: {cur: 0xf6, idx: 0x0}, + 968: {cur: 0xf8, idx: 0xcb}, + 969: {cur: 0xf9, idx: 0x581}, + 970: {cur: 0xfc, idx: 0x0}, + 971: {cur: 0x105, idx: 0x0}, + 972: {cur: 0x110, idx: 0x0}, + 973: {cur: 0xc8, idx: 0x7e}, + 974: {cur: 0xeb, idx: 0xbc}, + 975: {cur: 0xfc, idx: 0x4}, + 976: {cur: 0xc8, idx: 0x0}, + 977: {cur: 0x102, idx: 0x589}, + 978: {cur: 0x4, idx: 0x396}, + 979: {cur: 0xeb, idx: 0xbc}, + 980: {cur: 0x102, idx: 0x58f}, + 981: {cur: 0x94, idx: 0x4}, + 982: {cur: 0x94, idx: 0x4}, + 983: {cur: 0x13, idx: 0xf8}, + 984: {cur: 0xeb, idx: 0xbc}, + 985: {cur: 0xf7, idx: 0x23c}, + 986: {cur: 0x85, idx: 0x25}, + 987: {cur: 0xfc, idx: 0x4}, + 988: {cur: 0xfc, idx: 0x4}, + 989: {cur: 0xfb, idx: 0x2f4}, + 990: {cur: 0xba, idx: 0x97}, + 991: {cur: 0x13, idx: 0xf8}, + 992: {cur: 0x85, idx: 0x25}, + 993: {cur: 0x8d, idx: 0x596}, + 994: {cur: 0x13, idx: 0xf8}, + 995: {cur: 0x44, idx: 0x4a3}, + 996: {cur: 0x8d, idx: 0x596}, + 997: {cur: 0x13, idx: 0xf8}, + 998: {cur: 0x44, idx: 0x4a3}, + 999: {cur: 0x7b, idx: 0x59a}, + 1000: {cur: 0x8d, idx: 0x596}, + 1001: {cur: 0x44, idx: 0x20}, + 1002: {cur: 0x44, idx: 0x20}, + 1003: {cur: 0xaa, idx: 0x35f}, + 1004: {cur: 0x44, idx: 0x20}, + 1005: {cur: 0xdc, idx: 0x4}, + 1006: {cur: 0x13, idx: 0xf8}, + 1007: {cur: 0x85, idx: 0x25}, + 1008: {cur: 0x8d, idx: 0x596}, + 1009: {cur: 0xf6, idx: 0x4}, + 1010: {cur: 0x8d, idx: 0x6e}, + 1011: {cur: 0xf6, idx: 0xc7}, + 1012: {cur: 0xaa, idx: 0x35f}, + 1013: {cur: 0xeb, idx: 0xbc}, + 1014: {cur: 0x125, idx: 0xe9}, +} // Size: 4084 bytes + +var narrowLangIndex = []uint16{ // 776 elements + // Entry 0 - 3F + 0x0000, 0x0062, 0x0064, 0x0064, 0x0064, 0x0064, 0x0064, 0x0064, + 0x0064, 0x0065, 0x0065, 0x0081, 0x0081, 0x0082, 0x0082, 0x0082, + 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, + 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, + 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, + 0x0082, 0x0082, 0x0082, 0x0082, 0x0082, 0x008b, 0x008b, 0x008e, + 0x008e, 0x008e, 0x008e, 0x008e, 0x008e, 0x008e, 0x00a8, 0x00a8, + 0x00a8, 0x00a8, 0x00a8, 0x00a8, 0x00d8, 0x00d8, 0x00d8, 0x00d8, + // Entry 40 - 7F + 0x00d8, 0x00d9, 0x00d9, 0x00d9, 0x00d9, 0x00d9, 0x00d9, 0x00dc, + 0x00dc, 0x00dc, 0x00dc, 0x00dd, 0x00dd, 0x00dd, 0x00dd, 0x00dd, + 0x00de, 0x00de, 0x00de, 0x00de, 0x00de, 0x00df, 0x00df, 0x00df, + 0x00e0, 0x00e0, 0x00e0, 0x00e0, 0x00e0, 0x00e0, 0x00e0, 0x00e0, + 0x00e0, 0x00e2, 0x00e2, 0x00e2, 0x00e2, 0x00e8, 0x00e8, 0x00ee, + 0x00ee, 0x00ee, 0x00ee, 0x00ee, 0x00f7, 0x00f7, 0x00f7, 0x00f8, + 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, + 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, + // Entry 80 - BF + 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, + 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x00f8, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + // Entry C0 - FF + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, + 0x0100, 0x0100, 0x0103, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, + 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, + // Entry 100 - 13F + 0x0108, 0x0108, 0x0108, 0x0108, 0x010d, 0x010d, 0x010d, 0x010d, + 0x010d, 0x010d, 0x010d, 0x010d, 0x0111, 0x0111, 0x0112, 0x0113, + 0x0113, 0x0114, 0x0114, 0x0114, 0x0114, 0x0114, 0x0114, 0x0114, + 0x0114, 0x0114, 0x0114, 0x0114, 0x0114, 0x0171, 0x0171, 0x0172, + 0x0172, 0x0172, 0x0172, 0x0172, 0x017a, 0x017a, 0x017a, 0x017a, + 0x017a, 0x017a, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, + 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, + 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, + // Entry 140 - 17F + 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, + 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, + 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x017f, 0x0180, + 0x0180, 0x0182, 0x0182, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185, + 0x0185, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, + 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0188, 0x0188, + 0x018a, 0x018a, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018c, + 0x018c, 0x018d, 0x018d, 0x018e, 0x018e, 0x018e, 0x018e, 0x018e, + // Entry 180 - 1BF + 0x018e, 0x018e, 0x018e, 0x018f, 0x018f, 0x0193, 0x0193, 0x0193, + 0x0193, 0x0193, 0x0193, 0x0193, 0x0196, 0x0196, 0x0196, 0x0196, + 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0197, 0x0197, + 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, + 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0198, 0x0198, + 0x0198, 0x0198, 0x0198, 0x0198, 0x0198, 0x0198, 0x0199, 0x0199, + 0x019b, 0x019b, 0x019d, 0x019d, 0x019d, 0x019d, 0x019d, 0x019d, + 0x019d, 0x019d, 0x019d, 0x019d, 0x019d, 0x019d, 0x019d, 0x019d, + // Entry 1C0 - 1FF + 0x019d, 0x019d, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x01a9, 0x01a9, + 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, + 0x01a9, 0x01aa, 0x01aa, 0x01aa, 0x01aa, 0x01aa, 0x01b5, 0x01b5, + 0x01b5, 0x01b5, 0x01b5, 0x01b5, 0x01b5, 0x01b5, 0x01b6, 0x01b6, + 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, + 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b7, 0x01b7, 0x01b8, + 0x01b8, 0x01ba, 0x01ba, 0x01ba, 0x01bb, 0x01bb, 0x01bc, 0x01bc, + 0x01bc, 0x01bc, 0x01bc, 0x01bc, 0x01bc, 0x01bc, 0x01be, 0x01be, + // Entry 200 - 23F + 0x01be, 0x01be, 0x01be, 0x01be, 0x01be, 0x01c0, 0x01c0, 0x01c0, + 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c0, 0x01c1, 0x01c1, 0x01c1, + 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, + 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, + 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, + 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c3, + 0x01c3, 0x01c3, 0x01c3, 0x01c3, 0x01c3, 0x01c5, 0x01c5, 0x01c5, + 0x01c5, 0x01c5, 0x01c5, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, + // Entry 240 - 27F + 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, + 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, + 0x01c8, 0x01c8, 0x01c8, 0x01c8, 0x01c8, 0x01cb, 0x01cc, 0x01cc, + 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, + 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, + 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, + 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, 0x01cc, + 0x01cc, 0x01ce, 0x01ce, 0x01cf, 0x01cf, 0x01d0, 0x01d0, 0x01d0, + // Entry 280 - 2BF + 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, + 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, 0x01d0, + 0x01d2, 0x01d2, 0x01d2, 0x01d2, 0x01d2, 0x01d2, 0x01d5, 0x01d5, + 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d8, 0x01d8, + 0x01d8, 0x01d8, 0x01d9, 0x01d9, 0x01d9, 0x01d9, 0x01d9, 0x01d9, + 0x01da, 0x01da, 0x01da, 0x01da, 0x01da, 0x01db, 0x01db, 0x01db, + 0x01db, 0x01db, 0x01db, 0x01db, 0x01dc, 0x01dc, 0x01dc, 0x01dc, + 0x01dc, 0x01dc, 0x01dc, 0x01dc, 0x01dc, 0x01dc, 0x01dc, 0x01dc, + // Entry 2C0 - 2FF + 0x01de, 0x01de, 0x01de, 0x01de, 0x01de, 0x01de, 0x01de, 0x01de, + 0x01de, 0x01de, 0x01de, 0x01de, 0x01df, 0x01df, 0x01e0, 0x01e0, + 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, + 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e1, 0x01e1, + 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, + 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, + 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, + 0x01e1, 0x01e1, 0x01e2, 0x01e2, 0x01e2, 0x01e2, 0x01e2, 0x01e2, + // Entry 300 - 33F + 0x01e3, 0x01e3, 0x01e3, 0x01e3, 0x01eb, 0x01eb, 0x01eb, 0x01eb, +} // Size: 1576 bytes + +var narrowSymIndex = []curToIndex{ // 491 elements + 0: {cur: 0x9, idx: 0x1}, + 1: {cur: 0x11, idx: 0x4}, + 2: {cur: 0x13, idx: 0x4}, + 3: {cur: 0x18, idx: 0x9}, + 4: {cur: 0x1a, idx: 0x4}, + 5: {cur: 0x1b, idx: 0xc}, + 6: {cur: 0x25, idx: 0x4}, + 7: {cur: 0x26, idx: 0x4}, + 8: {cur: 0x27, idx: 0x10}, + 9: {cur: 0x2e, idx: 0x13}, + 10: {cur: 0x32, idx: 0x4}, + 11: {cur: 0x35, idx: 0x16}, + 12: {cur: 0x37, idx: 0x18}, + 13: {cur: 0x39, idx: 0x4}, + 14: {cur: 0x3a, idx: 0x4}, + 15: {cur: 0x41, idx: 0x4}, + 16: {cur: 0x44, idx: 0x25}, + 17: {cur: 0x45, idx: 0x4}, + 18: {cur: 0x47, idx: 0x28}, + 19: {cur: 0x4a, idx: 0x4}, + 20: {cur: 0x4b, idx: 0x4}, + 21: {cur: 0x4e, idx: 0x2c}, + 22: {cur: 0x52, idx: 0x30}, + 23: {cur: 0x53, idx: 0x4}, + 24: {cur: 0x58, idx: 0x33}, + 25: {cur: 0x5c, idx: 0x37}, + 26: {cur: 0x5e, idx: 0x3b}, + 27: {cur: 0x60, idx: 0x4}, + 28: {cur: 0x61, idx: 0x3f}, + 29: {cur: 0x63, idx: 0x3f}, + 30: {cur: 0x65, idx: 0x42}, + 31: {cur: 0x68, idx: 0x3f}, + 32: {cur: 0x6a, idx: 0x46}, + 33: {cur: 0x6e, idx: 0x49}, + 34: {cur: 0x71, idx: 0x4}, + 35: {cur: 0x72, idx: 0x4}, + 36: {cur: 0x73, idx: 0x4f}, + 37: {cur: 0x75, idx: 0x51}, + 38: {cur: 0x77, idx: 0x54}, + 39: {cur: 0x78, idx: 0x57}, + 40: {cur: 0x7c, idx: 0x5a}, + 41: {cur: 0x7d, idx: 0x5e}, + 42: {cur: 0x81, idx: 0x30}, + 43: {cur: 0x83, idx: 0x4}, + 44: {cur: 0x85, idx: 0x25}, + 45: {cur: 0x88, idx: 0x67}, + 46: {cur: 0x89, idx: 0x6b}, + 47: {cur: 0x8a, idx: 0x6e}, + 48: {cur: 0x8d, idx: 0x6e}, + 49: {cur: 0x8f, idx: 0x4}, + 50: {cur: 0x90, idx: 0x72}, + 51: {cur: 0x91, idx: 0x76}, + 52: {cur: 0x92, idx: 0x7a}, + 53: {cur: 0x93, idx: 0x7e}, + 54: {cur: 0x94, idx: 0x4}, + 55: {cur: 0x96, idx: 0x81}, + 56: {cur: 0x9b, idx: 0x84}, + 57: {cur: 0xa3, idx: 0x87}, + 58: {cur: 0xa8, idx: 0x8a}, + 59: {cur: 0xa9, idx: 0x8c}, + 60: {cur: 0xae, idx: 0x7e}, + 61: {cur: 0xb2, idx: 0x4}, + 62: {cur: 0xb5, idx: 0x94}, + 63: {cur: 0xb9, idx: 0x4}, + 64: {cur: 0xba, idx: 0x97}, + 65: {cur: 0xbc, idx: 0x9b}, + 66: {cur: 0xbe, idx: 0x30}, + 67: {cur: 0xbf, idx: 0x7e}, + 68: {cur: 0xc0, idx: 0x4}, + 69: {cur: 0xc7, idx: 0xa2}, + 70: {cur: 0xc8, idx: 0x7e}, + 71: {cur: 0xc9, idx: 0xa6}, + 72: {cur: 0xcc, idx: 0xaa}, + 73: {cur: 0xd0, idx: 0xae}, + 74: {cur: 0xd2, idx: 0xb2}, + 75: {cur: 0xd3, idx: 0x18}, + 76: {cur: 0xd4, idx: 0xb6}, + 77: {cur: 0xd6, idx: 0x4}, + 78: {cur: 0xdb, idx: 0x30}, + 79: {cur: 0xdc, idx: 0x4}, + 80: {cur: 0xdd, idx: 0x3f}, + 81: {cur: 0xe2, idx: 0x4}, + 82: {cur: 0xe4, idx: 0x3f}, + 83: {cur: 0xe5, idx: 0xb9}, + 84: {cur: 0xe9, idx: 0x3f}, + 85: {cur: 0xeb, idx: 0xbc}, + 86: {cur: 0xf1, idx: 0xc0}, + 87: {cur: 0xf4, idx: 0xc3}, + 88: {cur: 0xf5, idx: 0x4}, + 89: {cur: 0xf6, idx: 0x4}, + 90: {cur: 0xf8, idx: 0xcb}, + 91: {cur: 0xfc, idx: 0x4}, + 92: {cur: 0x101, idx: 0x4}, + 93: {cur: 0x104, idx: 0x10}, + 94: {cur: 0x105, idx: 0xd3}, + 95: {cur: 0x110, idx: 0x4}, + 96: {cur: 0x125, idx: 0xe9}, + 97: {cur: 0x127, idx: 0xeb}, + 98: {cur: 0xd0, idx: 0xee}, + 99: {cur: 0xf6, idx: 0xc7}, + 100: {cur: 0xf6, idx: 0xc7}, + 101: {cur: 0x11, idx: 0x128}, + 102: {cur: 0x13, idx: 0xf8}, + 103: {cur: 0x1a, idx: 0x12c}, + 104: {cur: 0x25, idx: 0x13a}, + 105: {cur: 0x26, idx: 0x13e}, + 106: {cur: 0x32, idx: 0x142}, + 107: {cur: 0x39, idx: 0x146}, + 108: {cur: 0x3a, idx: 0x1c}, + 109: {cur: 0x41, idx: 0x14a}, + 110: {cur: 0x44, idx: 0x20}, + 111: {cur: 0x45, idx: 0x14e}, + 112: {cur: 0x4b, idx: 0x152}, + 113: {cur: 0x53, idx: 0x156}, + 114: {cur: 0x60, idx: 0x16e}, + 115: {cur: 0x63, idx: 0x172}, + 116: {cur: 0x71, idx: 0x177}, + 117: {cur: 0x72, idx: 0x4b}, + 118: {cur: 0x83, idx: 0x18c}, + 119: {cur: 0x85, idx: 0x62}, + 120: {cur: 0x8f, idx: 0x1a4}, + 121: {cur: 0xb2, idx: 0x90}, + 122: {cur: 0xc0, idx: 0x9e}, + 123: {cur: 0xd6, idx: 0x1ee}, + 124: {cur: 0xe2, idx: 0x203}, + 125: {cur: 0xf5, idx: 0x21b}, + 126: {cur: 0xf6, idx: 0xc7}, + 127: {cur: 0xfc, idx: 0xcf}, + 128: {cur: 0x101, idx: 0x21f}, + 129: {cur: 0x26, idx: 0x4}, + 130: {cur: 0x37, idx: 0x0}, + 131: {cur: 0x52, idx: 0x0}, + 132: {cur: 0x75, idx: 0x0}, + 133: {cur: 0x81, idx: 0x0}, + 134: {cur: 0xbe, idx: 0x0}, + 135: {cur: 0xc9, idx: 0x0}, + 136: {cur: 0xd3, idx: 0x0}, + 137: {cur: 0xdb, idx: 0x0}, + 138: {cur: 0xf6, idx: 0xc7}, + 139: {cur: 0xd0, idx: 0x244}, + 140: {cur: 0xe9, idx: 0x248}, + 141: {cur: 0xf6, idx: 0xc7}, + 142: {cur: 0x13, idx: 0x6}, + 143: {cur: 0x1a, idx: 0x24c}, + 144: {cur: 0x25, idx: 0x251}, + 145: {cur: 0x32, idx: 0x255}, + 146: {cur: 0x37, idx: 0x258}, + 147: {cur: 0x39, idx: 0x146}, + 148: {cur: 0x3a, idx: 0x1c}, + 149: {cur: 0x4a, idx: 0x25b}, + 150: {cur: 0x4b, idx: 0x260}, + 151: {cur: 0x53, idx: 0x264}, + 152: {cur: 0x60, idx: 0x16e}, + 153: {cur: 0x61, idx: 0x268}, + 154: {cur: 0x71, idx: 0x26d}, + 155: {cur: 0x81, idx: 0x270}, + 156: {cur: 0x83, idx: 0x275}, + 157: {cur: 0x8f, idx: 0x278}, + 158: {cur: 0x94, idx: 0x27c}, + 159: {cur: 0xb2, idx: 0x90}, + 160: {cur: 0xb9, idx: 0x27f}, + 161: {cur: 0xc0, idx: 0x9e}, + 162: {cur: 0xd2, idx: 0x282}, + 163: {cur: 0xd6, idx: 0x28a}, + 164: {cur: 0xdc, idx: 0x28e}, + 165: {cur: 0xf5, idx: 0x21b}, + 166: {cur: 0x101, idx: 0x291}, + 167: {cur: 0x110, idx: 0xdc}, + 168: {cur: 0x11, idx: 0x0}, + 169: {cur: 0x13, idx: 0x0}, + 170: {cur: 0x1a, idx: 0x0}, + 171: {cur: 0x1b, idx: 0x0}, + 172: {cur: 0x25, idx: 0x0}, + 173: {cur: 0x26, idx: 0x0}, + 174: {cur: 0x2e, idx: 0x0}, + 175: {cur: 0x32, idx: 0x0}, + 176: {cur: 0x37, idx: 0x0}, + 177: {cur: 0x39, idx: 0x0}, + 178: {cur: 0x3a, idx: 0x0}, + 179: {cur: 0x41, idx: 0x0}, + 180: {cur: 0x44, idx: 0x0}, + 181: {cur: 0x45, idx: 0x0}, + 182: {cur: 0x47, idx: 0x0}, + 183: {cur: 0x4b, idx: 0x0}, + 184: {cur: 0x53, idx: 0x0}, + 185: {cur: 0x60, idx: 0x0}, + 186: {cur: 0x68, idx: 0x0}, + 187: {cur: 0x71, idx: 0x0}, + 188: {cur: 0x72, idx: 0x0}, + 189: {cur: 0x7c, idx: 0x0}, + 190: {cur: 0x7d, idx: 0x0}, + 191: {cur: 0x83, idx: 0x0}, + 192: {cur: 0x88, idx: 0x0}, + 193: {cur: 0x8d, idx: 0x0}, + 194: {cur: 0x8f, idx: 0x0}, + 195: {cur: 0x90, idx: 0x0}, + 196: {cur: 0x91, idx: 0x0}, + 197: {cur: 0x94, idx: 0x0}, + 198: {cur: 0xa9, idx: 0x0}, + 199: {cur: 0xb2, idx: 0x0}, + 200: {cur: 0xb9, idx: 0x0}, + 201: {cur: 0xba, idx: 0x0}, + 202: {cur: 0xc0, idx: 0x0}, + 203: {cur: 0xc7, idx: 0x0}, + 204: {cur: 0xcc, idx: 0x0}, + 205: {cur: 0xd0, idx: 0x0}, + 206: {cur: 0xd6, idx: 0x0}, + 207: {cur: 0xdc, idx: 0x0}, + 208: {cur: 0xe2, idx: 0x0}, + 209: {cur: 0xe4, idx: 0x0}, + 210: {cur: 0xf4, idx: 0x0}, + 211: {cur: 0xf5, idx: 0x0}, + 212: {cur: 0xf6, idx: 0x0}, + 213: {cur: 0xf8, idx: 0x0}, + 214: {cur: 0x101, idx: 0x0}, + 215: {cur: 0x105, idx: 0x0}, + 216: {cur: 0xf6, idx: 0xc7}, + 217: {cur: 0x58, idx: 0x2a8}, + 218: {cur: 0x92, idx: 0x2b8}, + 219: {cur: 0xf1, idx: 0x2c1}, + 220: {cur: 0xf6, idx: 0xc7}, + 221: {cur: 0x104, idx: 0x0}, + 222: {cur: 0xf6, idx: 0xc7}, + 223: {cur: 0xd0, idx: 0x2ed}, + 224: {cur: 0xd0, idx: 0x4f}, + 225: {cur: 0xf6, idx: 0xc7}, + 226: {cur: 0x1b, idx: 0x301}, + 227: {cur: 0x35, idx: 0x0}, + 228: {cur: 0x72, idx: 0x4b}, + 229: {cur: 0xf6, idx: 0xc7}, + 230: {cur: 0x125, idx: 0x0}, + 231: {cur: 0x127, idx: 0x0}, + 232: {cur: 0x52, idx: 0x304}, + 233: {cur: 0x81, idx: 0x304}, + 234: {cur: 0xbe, idx: 0x304}, + 235: {cur: 0xd0, idx: 0x4f}, + 236: {cur: 0xdb, idx: 0x304}, + 237: {cur: 0xf6, idx: 0xc7}, + 238: {cur: 0x4a, idx: 0x318}, + 239: {cur: 0x61, idx: 0x320}, + 240: {cur: 0x6a, idx: 0x325}, + 241: {cur: 0x89, idx: 0x32a}, + 242: {cur: 0xd0, idx: 0x4f}, + 243: {cur: 0xd4, idx: 0x32d}, + 244: {cur: 0xe9, idx: 0x0}, + 245: {cur: 0xf6, idx: 0xc7}, + 246: {cur: 0x127, idx: 0x8a}, + 247: {cur: 0x5e, idx: 0x0}, + 248: {cur: 0x1b, idx: 0x349}, + 249: {cur: 0x27, idx: 0x34c}, + 250: {cur: 0x4b, idx: 0xa2}, + 251: {cur: 0x58, idx: 0x3f}, + 252: {cur: 0x81, idx: 0x34f}, + 253: {cur: 0xcc, idx: 0x352}, + 254: {cur: 0xdb, idx: 0x34f}, + 255: {cur: 0x101, idx: 0x291}, + 256: {cur: 0x58, idx: 0x0}, + 257: {cur: 0xd0, idx: 0x4f}, + 258: {cur: 0xf6, idx: 0xc7}, + 259: {cur: 0x58, idx: 0x33}, + 260: {cur: 0x61, idx: 0x268}, + 261: {cur: 0xe4, idx: 0x37b}, + 262: {cur: 0xe9, idx: 0x248}, + 263: {cur: 0x104, idx: 0x380}, + 264: {cur: 0x37, idx: 0x384}, + 265: {cur: 0x61, idx: 0x3f}, + 266: {cur: 0xd0, idx: 0xae}, + 267: {cur: 0xe4, idx: 0x3f}, + 268: {cur: 0xe9, idx: 0x3f}, + 269: {cur: 0x61, idx: 0x3f}, + 270: {cur: 0xd0, idx: 0xae}, + 271: {cur: 0xe4, idx: 0x3f}, + 272: {cur: 0xe9, idx: 0x3f}, + 273: {cur: 0x104, idx: 0x392}, + 274: {cur: 0xf6, idx: 0xc7}, + 275: {cur: 0xf6, idx: 0xc7}, + 276: {cur: 0x9, idx: 0x0}, + 277: {cur: 0x11, idx: 0x0}, + 278: {cur: 0x13, idx: 0x0}, + 279: {cur: 0x18, idx: 0x0}, + 280: {cur: 0x1a, idx: 0x0}, + 281: {cur: 0x1b, idx: 0x0}, + 282: {cur: 0x25, idx: 0x0}, + 283: {cur: 0x26, idx: 0x0}, + 284: {cur: 0x27, idx: 0x0}, + 285: {cur: 0x2e, idx: 0x0}, + 286: {cur: 0x32, idx: 0x0}, + 287: {cur: 0x35, idx: 0x0}, + 288: {cur: 0x37, idx: 0x0}, + 289: {cur: 0x39, idx: 0x0}, + 290: {cur: 0x3a, idx: 0x0}, + 291: {cur: 0x41, idx: 0x0}, + 292: {cur: 0x44, idx: 0x0}, + 293: {cur: 0x45, idx: 0x0}, + 294: {cur: 0x47, idx: 0x0}, + 295: {cur: 0x4a, idx: 0x0}, + 296: {cur: 0x4b, idx: 0x0}, + 297: {cur: 0x4e, idx: 0x0}, + 298: {cur: 0x52, idx: 0x0}, + 299: {cur: 0x53, idx: 0x0}, + 300: {cur: 0x58, idx: 0x0}, + 301: {cur: 0x5c, idx: 0x0}, + 302: {cur: 0x60, idx: 0x0}, + 303: {cur: 0x61, idx: 0x0}, + 304: {cur: 0x65, idx: 0x0}, + 305: {cur: 0x68, idx: 0x0}, + 306: {cur: 0x6a, idx: 0x0}, + 307: {cur: 0x6e, idx: 0x0}, + 308: {cur: 0x71, idx: 0x0}, + 309: {cur: 0x72, idx: 0x0}, + 310: {cur: 0x73, idx: 0x0}, + 311: {cur: 0x75, idx: 0x0}, + 312: {cur: 0x77, idx: 0x0}, + 313: {cur: 0x78, idx: 0x0}, + 314: {cur: 0x7c, idx: 0x0}, + 315: {cur: 0x7d, idx: 0x0}, + 316: {cur: 0x81, idx: 0x0}, + 317: {cur: 0x83, idx: 0x0}, + 318: {cur: 0x88, idx: 0x0}, + 319: {cur: 0x89, idx: 0x0}, + 320: {cur: 0x8a, idx: 0x0}, + 321: {cur: 0x8d, idx: 0x0}, + 322: {cur: 0x8f, idx: 0x0}, + 323: {cur: 0x90, idx: 0x0}, + 324: {cur: 0x91, idx: 0x0}, + 325: {cur: 0x92, idx: 0x0}, + 326: {cur: 0x93, idx: 0x0}, + 327: {cur: 0x94, idx: 0x0}, + 328: {cur: 0x96, idx: 0x0}, + 329: {cur: 0x9b, idx: 0x0}, + 330: {cur: 0xa3, idx: 0x0}, + 331: {cur: 0xa8, idx: 0x0}, + 332: {cur: 0xa9, idx: 0x0}, + 333: {cur: 0xae, idx: 0x0}, + 334: {cur: 0xb2, idx: 0x0}, + 335: {cur: 0xb5, idx: 0x0}, + 336: {cur: 0xb9, idx: 0x0}, + 337: {cur: 0xba, idx: 0x0}, + 338: {cur: 0xbc, idx: 0x0}, + 339: {cur: 0xbe, idx: 0x0}, + 340: {cur: 0xbf, idx: 0x0}, + 341: {cur: 0xc0, idx: 0x0}, + 342: {cur: 0xc7, idx: 0x0}, + 343: {cur: 0xc8, idx: 0x0}, + 344: {cur: 0xc9, idx: 0x0}, + 345: {cur: 0xcc, idx: 0x0}, + 346: {cur: 0xd0, idx: 0x0}, + 347: {cur: 0xd3, idx: 0x0}, + 348: {cur: 0xd4, idx: 0x0}, + 349: {cur: 0xd6, idx: 0x0}, + 350: {cur: 0xdb, idx: 0x0}, + 351: {cur: 0xdc, idx: 0x0}, + 352: {cur: 0xdd, idx: 0x0}, + 353: {cur: 0xe2, idx: 0x0}, + 354: {cur: 0xe4, idx: 0x0}, + 355: {cur: 0xe5, idx: 0x0}, + 356: {cur: 0xe9, idx: 0x0}, + 357: {cur: 0xeb, idx: 0x0}, + 358: {cur: 0xf1, idx: 0x0}, + 359: {cur: 0xf4, idx: 0x0}, + 360: {cur: 0xf5, idx: 0x0}, + 361: {cur: 0xf6, idx: 0x0}, + 362: {cur: 0xf8, idx: 0x0}, + 363: {cur: 0x101, idx: 0x0}, + 364: {cur: 0x104, idx: 0x0}, + 365: {cur: 0x105, idx: 0x0}, + 366: {cur: 0x110, idx: 0x0}, + 367: {cur: 0x125, idx: 0x0}, + 368: {cur: 0x127, idx: 0x0}, + 369: {cur: 0xf6, idx: 0xc7}, + 370: {cur: 0x58, idx: 0x3e5}, + 371: {cur: 0x89, idx: 0x32a}, + 372: {cur: 0x92, idx: 0x2b8}, + 373: {cur: 0xbc, idx: 0x41a}, + 374: {cur: 0xd0, idx: 0x4f}, + 375: {cur: 0xd4, idx: 0x421}, + 376: {cur: 0xf6, idx: 0xc7}, + 377: {cur: 0x127, idx: 0x441}, + 378: {cur: 0x37, idx: 0x258}, + 379: {cur: 0x65, idx: 0x0}, + 380: {cur: 0x89, idx: 0x6b}, + 381: {cur: 0xbc, idx: 0x9b}, + 382: {cur: 0x127, idx: 0xeb}, + 383: {cur: 0xf6, idx: 0xc7}, + 384: {cur: 0xd0, idx: 0xee}, + 385: {cur: 0xf6, idx: 0xc7}, + 386: {cur: 0x89, idx: 0x32a}, + 387: {cur: 0xd2, idx: 0x46d}, + 388: {cur: 0xf6, idx: 0xc7}, + 389: {cur: 0xae, idx: 0x474}, + 390: {cur: 0xf6, idx: 0xc7}, + 391: {cur: 0xf6, idx: 0xc7}, + 392: {cur: 0xd0, idx: 0x48e}, + 393: {cur: 0xf6, idx: 0xc7}, + 394: {cur: 0xf6, idx: 0xc7}, + 395: {cur: 0xf6, idx: 0xc7}, + 396: {cur: 0xf6, idx: 0xc7}, + 397: {cur: 0xf6, idx: 0xc7}, + 398: {cur: 0xf6, idx: 0xc7}, + 399: {cur: 0x37, idx: 0x258}, + 400: {cur: 0x58, idx: 0x3e5}, + 401: {cur: 0xbe, idx: 0x49b}, + 402: {cur: 0xf6, idx: 0xc7}, + 403: {cur: 0x44, idx: 0x4a3}, + 404: {cur: 0x85, idx: 0x4a3}, + 405: {cur: 0xd0, idx: 0x4a7}, + 406: {cur: 0xf6, idx: 0xc7}, + 407: {cur: 0xf6, idx: 0xc7}, + 408: {cur: 0xf6, idx: 0xc7}, + 409: {cur: 0xd0, idx: 0x4b2}, + 410: {cur: 0xf6, idx: 0xc7}, + 411: {cur: 0xd0, idx: 0x4f}, + 412: {cur: 0xf6, idx: 0xc7}, + 413: {cur: 0x25, idx: 0x251}, + 414: {cur: 0x32, idx: 0x255}, + 415: {cur: 0x39, idx: 0x146}, + 416: {cur: 0x3a, idx: 0x9b}, + 417: {cur: 0x53, idx: 0x264}, + 418: {cur: 0x58, idx: 0x4b9}, + 419: {cur: 0x72, idx: 0x4b}, + 420: {cur: 0x75, idx: 0x4bc}, + 421: {cur: 0x83, idx: 0x275}, + 422: {cur: 0xf5, idx: 0x21b}, + 423: {cur: 0xf6, idx: 0xc7}, + 424: {cur: 0xf6, idx: 0xc7}, + 425: {cur: 0xf6, idx: 0xc7}, + 426: {cur: 0x1b, idx: 0x0}, + 427: {cur: 0x37, idx: 0x258}, + 428: {cur: 0x7c, idx: 0x0}, + 429: {cur: 0x7d, idx: 0x0}, + 430: {cur: 0x88, idx: 0x0}, + 431: {cur: 0x91, idx: 0x0}, + 432: {cur: 0xa9, idx: 0x0}, + 433: {cur: 0xc9, idx: 0x4c6}, + 434: {cur: 0xcc, idx: 0x352}, + 435: {cur: 0xd2, idx: 0x4c9}, + 436: {cur: 0x105, idx: 0x0}, + 437: {cur: 0xf6, idx: 0xc7}, + 438: {cur: 0xf6, idx: 0xc7}, + 439: {cur: 0xf6, idx: 0xc7}, + 440: {cur: 0xdb, idx: 0x4d7}, + 441: {cur: 0xf6, idx: 0xc7}, + 442: {cur: 0xf6, idx: 0xc7}, + 443: {cur: 0xf6, idx: 0xc7}, + 444: {cur: 0x1a, idx: 0x24c}, + 445: {cur: 0x32, idx: 0x255}, + 446: {cur: 0xd0, idx: 0x4f}, + 447: {cur: 0xf6, idx: 0xc7}, + 448: {cur: 0xbf, idx: 0x4f1}, + 449: {cur: 0xf6, idx: 0xc7}, + 450: {cur: 0xf6, idx: 0xc7}, + 451: {cur: 0xd0, idx: 0x500}, + 452: {cur: 0xf6, idx: 0xc7}, + 453: {cur: 0xd0, idx: 0x4f}, + 454: {cur: 0xf6, idx: 0xc7}, + 455: {cur: 0xf6, idx: 0xc7}, + 456: {cur: 0x65, idx: 0x515}, + 457: {cur: 0xd0, idx: 0x4f}, + 458: {cur: 0xf6, idx: 0xc7}, + 459: {cur: 0x37, idx: 0x258}, + 460: {cur: 0x93, idx: 0x52c}, + 461: {cur: 0xf6, idx: 0xc7}, + 462: {cur: 0xf6, idx: 0xc7}, + 463: {cur: 0xf6, idx: 0xc7}, + 464: {cur: 0x65, idx: 0x515}, + 465: {cur: 0xf6, idx: 0xc7}, + 466: {cur: 0x37, idx: 0x552}, + 467: {cur: 0x65, idx: 0x515}, + 468: {cur: 0xf6, idx: 0xc7}, + 469: {cur: 0x5c, idx: 0x0}, + 470: {cur: 0xd0, idx: 0x4f}, + 471: {cur: 0xf6, idx: 0xc7}, + 472: {cur: 0xf6, idx: 0xc7}, + 473: {cur: 0xf6, idx: 0xc7}, + 474: {cur: 0xf6, idx: 0xc7}, + 475: {cur: 0xf6, idx: 0xc7}, + 476: {cur: 0xd0, idx: 0x4f}, + 477: {cur: 0xf6, idx: 0xc7}, + 478: {cur: 0xf6, idx: 0xc7}, + 479: {cur: 0xf6, idx: 0xc7}, + 480: {cur: 0xf6, idx: 0xc7}, + 481: {cur: 0xf6, idx: 0xc7}, + 482: {cur: 0xd0, idx: 0x4f}, + 483: {cur: 0x37, idx: 0x59e}, + 484: {cur: 0x52, idx: 0x34f}, + 485: {cur: 0x75, idx: 0x4bc}, + 486: {cur: 0x81, idx: 0x34f}, + 487: {cur: 0xbe, idx: 0x34f}, + 488: {cur: 0xc9, idx: 0x5a1}, + 489: {cur: 0xdb, idx: 0x34f}, + 490: {cur: 0xf6, idx: 0xc7}, +} // Size: 1988 bytes + +// Total table size 18885 bytes (18KiB); checksum: BE08FD0B diff --git a/vendor/golang.org/x/text/internal/format/format.go b/vendor/golang.org/x/text/internal/format/format.go new file mode 100644 index 00000000000..ee1c57a3c58 --- /dev/null +++ b/vendor/golang.org/x/text/internal/format/format.go @@ -0,0 +1,41 @@ +// 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 format contains types for defining language-specific formatting of +// values. +// +// This package is internal now, but will eventually be exposed after the API +// settles. +package format // import "golang.org/x/text/internal/format" + +import ( + "fmt" + + "golang.org/x/text/language" +) + +// State represents the printer state passed to custom formatters. It provides +// access to the fmt.State interface and the sentence and language-related +// context. +type State interface { + fmt.State + + // Language reports the requested language in which to render a message. + Language() language.Tag + + // TODO: consider this and removing rune from the Format method in the + // Formatter interface. + // + // Verb returns the format variant to render, analogous to the types used + // in fmt. Use 'v' for the default or only variant. + // Verb() rune + + // TODO: more info: + // - sentence context such as linguistic features passed by the translator. +} + +// Formatter is analogous to fmt.Formatter. +type Formatter interface { + Format(state State, verb rune) +} diff --git a/vendor/golang.org/x/text/internal/format/parser.go b/vendor/golang.org/x/text/internal/format/parser.go new file mode 100644 index 00000000000..855aed71dbb --- /dev/null +++ b/vendor/golang.org/x/text/internal/format/parser.go @@ -0,0 +1,358 @@ +// Copyright 2017 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 format + +import ( + "reflect" + "unicode/utf8" +) + +// A Parser parses a format string. The result from the parse are set in the +// struct fields. +type Parser struct { + Verb rune + + WidthPresent bool + PrecPresent bool + Minus bool + Plus bool + Sharp bool + Space bool + Zero bool + + // For the formats %+v %#v, we set the plusV/sharpV flags + // and clear the plus/sharp flags since %+v and %#v are in effect + // different, flagless formats set at the top level. + PlusV bool + SharpV bool + + HasIndex bool + + Width int + Prec int // precision + + // retain arguments across calls. + Args []interface{} + // retain current argument number across calls + ArgNum int + + // reordered records whether the format string used argument reordering. + Reordered bool + // goodArgNum records whether the most recent reordering directive was valid. + goodArgNum bool + + // position info + format string + startPos int + endPos int + Status Status +} + +// Reset initializes a parser to scan format strings for the given args. +func (p *Parser) Reset(args []interface{}) { + p.Args = args + p.ArgNum = 0 + p.startPos = 0 + p.Reordered = false +} + +// Text returns the part of the format string that was parsed by the last call +// to Scan. It returns the original substitution clause if the current scan +// parsed a substitution. +func (p *Parser) Text() string { return p.format[p.startPos:p.endPos] } + +// SetFormat sets a new format string to parse. It does not reset the argument +// count. +func (p *Parser) SetFormat(format string) { + p.format = format + p.startPos = 0 + p.endPos = 0 +} + +// Status indicates the result type of a call to Scan. +type Status int + +const ( + StatusText Status = iota + StatusSubstitution + StatusBadWidthSubstitution + StatusBadPrecSubstitution + StatusNoVerb + StatusBadArgNum + StatusMissingArg +) + +// ClearFlags reset the parser to default behavior. +func (p *Parser) ClearFlags() { + p.WidthPresent = false + p.PrecPresent = false + p.Minus = false + p.Plus = false + p.Sharp = false + p.Space = false + p.Zero = false + + p.PlusV = false + p.SharpV = false + + p.HasIndex = false +} + +// Scan scans the next part of the format string and sets the status to +// indicate whether it scanned a string literal, substitution or error. +func (p *Parser) Scan() bool { + p.Status = StatusText + format := p.format + end := len(format) + if p.endPos >= end { + return false + } + afterIndex := false // previous item in format was an index like [3]. + + p.startPos = p.endPos + p.goodArgNum = true + i := p.startPos + for i < end && format[i] != '%' { + i++ + } + if i > p.startPos { + p.endPos = i + return true + } + // Process one verb + i++ + + p.Status = StatusSubstitution + + // Do we have flags? + p.ClearFlags() + +simpleFormat: + for ; i < end; i++ { + c := p.format[i] + switch c { + case '#': + p.Sharp = true + case '0': + p.Zero = !p.Minus // Only allow zero padding to the left. + case '+': + p.Plus = true + case '-': + p.Minus = true + p.Zero = false // Do not pad with zeros to the right. + case ' ': + p.Space = true + default: + // Fast path for common case of ascii lower case simple verbs + // without precision or width or argument indices. + if 'a' <= c && c <= 'z' && p.ArgNum < len(p.Args) { + if c == 'v' { + // Go syntax + p.SharpV = p.Sharp + p.Sharp = false + // Struct-field syntax + p.PlusV = p.Plus + p.Plus = false + } + p.Verb = rune(c) + p.ArgNum++ + p.endPos = i + 1 + return true + } + // Format is more complex than simple flags and a verb or is malformed. + break simpleFormat + } + } + + // Do we have an explicit argument index? + i, afterIndex = p.updateArgNumber(format, i) + + // Do we have width? + if i < end && format[i] == '*' { + i++ + p.Width, p.WidthPresent = p.intFromArg() + + if !p.WidthPresent { + p.Status = StatusBadWidthSubstitution + } + + // We have a negative width, so take its value and ensure + // that the minus flag is set + if p.Width < 0 { + p.Width = -p.Width + p.Minus = true + p.Zero = false // Do not pad with zeros to the right. + } + afterIndex = false + } else { + p.Width, p.WidthPresent, i = parsenum(format, i, end) + if afterIndex && p.WidthPresent { // "%[3]2d" + p.goodArgNum = false + } + } + + // Do we have precision? + if i+1 < end && format[i] == '.' { + i++ + if afterIndex { // "%[3].2d" + p.goodArgNum = false + } + i, afterIndex = p.updateArgNumber(format, i) + if i < end && format[i] == '*' { + i++ + p.Prec, p.PrecPresent = p.intFromArg() + // Negative precision arguments don't make sense + if p.Prec < 0 { + p.Prec = 0 + p.PrecPresent = false + } + if !p.PrecPresent { + p.Status = StatusBadPrecSubstitution + } + afterIndex = false + } else { + p.Prec, p.PrecPresent, i = parsenum(format, i, end) + if !p.PrecPresent { + p.Prec = 0 + p.PrecPresent = true + } + } + } + + if !afterIndex { + i, afterIndex = p.updateArgNumber(format, i) + } + p.HasIndex = afterIndex + + if i >= end { + p.endPos = i + p.Status = StatusNoVerb + return true + } + + verb, w := utf8.DecodeRuneInString(format[i:]) + p.endPos = i + w + p.Verb = verb + + switch { + case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec. + p.startPos = p.endPos - 1 + p.Status = StatusText + case !p.goodArgNum: + p.Status = StatusBadArgNum + case p.ArgNum >= len(p.Args): // No argument left over to print for the current verb. + p.Status = StatusMissingArg + p.ArgNum++ + case verb == 'v': + // Go syntax + p.SharpV = p.Sharp + p.Sharp = false + // Struct-field syntax + p.PlusV = p.Plus + p.Plus = false + fallthrough + default: + p.ArgNum++ + } + return true +} + +// intFromArg gets the ArgNumth element of Args. On return, isInt reports +// whether the argument has integer type. +func (p *Parser) intFromArg() (num int, isInt bool) { + if p.ArgNum < len(p.Args) { + arg := p.Args[p.ArgNum] + num, isInt = arg.(int) // Almost always OK. + if !isInt { + // Work harder. + switch v := reflect.ValueOf(arg); v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n := v.Int() + if int64(int(n)) == n { + num = int(n) + isInt = true + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n := v.Uint() + if int64(n) >= 0 && uint64(int(n)) == n { + num = int(n) + isInt = true + } + default: + // Already 0, false. + } + } + p.ArgNum++ + if tooLarge(num) { + num = 0 + isInt = false + } + } + return +} + +// parseArgNumber returns the value of the bracketed number, minus 1 +// (explicit argument numbers are one-indexed but we want zero-indexed). +// The opening bracket is known to be present at format[0]. +// The returned values are the index, the number of bytes to consume +// up to the closing paren, if present, and whether the number parsed +// ok. The bytes to consume will be 1 if no closing paren is present. +func parseArgNumber(format string) (index int, wid int, ok bool) { + // There must be at least 3 bytes: [n]. + if len(format) < 3 { + return 0, 1, false + } + + // Find closing bracket. + for i := 1; i < len(format); i++ { + if format[i] == ']' { + width, ok, newi := parsenum(format, 1, i) + if !ok || newi != i { + return 0, i + 1, false + } + return width - 1, i + 1, true // arg numbers are one-indexed and skip paren. + } + } + return 0, 1, false +} + +// updateArgNumber returns the next argument to evaluate, which is either the value of the passed-in +// argNum or the value of the bracketed integer that begins format[i:]. It also returns +// the new value of i, that is, the index of the next byte of the format to process. +func (p *Parser) updateArgNumber(format string, i int) (newi int, found bool) { + if len(format) <= i || format[i] != '[' { + return i, false + } + p.Reordered = true + index, wid, ok := parseArgNumber(format[i:]) + if ok && 0 <= index && index < len(p.Args) { + p.ArgNum = index + return i + wid, true + } + p.goodArgNum = false + return i + wid, ok +} + +// tooLarge reports whether the magnitude of the integer is +// too large to be used as a formatting width or precision. +func tooLarge(x int) bool { + const max int = 1e6 + return x > max || x < -max +} + +// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present. +func parsenum(s string, start, end int) (num int, isnum bool, newi int) { + if start >= end { + return 0, false, end + } + for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ { + if tooLarge(num) { + return 0, false, end // Overflow; crazy long number most likely. + } + num = num*10 + int(s[newi]-'0') + isnum = true + } + return +} diff --git a/vendor/golang.org/x/text/internal/number/common.go b/vendor/golang.org/x/text/internal/number/common.go new file mode 100644 index 00000000000..a6e9c8e0d54 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/common.go @@ -0,0 +1,55 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package number + +import ( + "unicode/utf8" + + "golang.org/x/text/internal/language/compact" +) + +// A system identifies a CLDR numbering system. +type system byte + +type systemData struct { + id system + digitSize byte // number of UTF-8 bytes per digit + zero [utf8.UTFMax]byte // UTF-8 sequence of zero digit. +} + +// A SymbolType identifies a symbol of a specific kind. +type SymbolType int + +const ( + SymDecimal SymbolType = iota + SymGroup + SymList + SymPercentSign + SymPlusSign + SymMinusSign + SymExponential + SymSuperscriptingExponent + SymPerMille + SymInfinity + SymNan + SymTimeSeparator + + NumSymbolTypes +) + +const hasNonLatnMask = 0x8000 + +// symOffset is an offset into altSymData if the bit indicated by hasNonLatnMask +// is not 0 (with this bit masked out), and an offset into symIndex otherwise. +// +// TODO: this type can be a byte again if we use an indirection into altsymData +// and introduce an alt -> offset slice (the length of this will be number of +// alternatives plus 1). This also allows getting rid of the compactTag field +// in altSymData. In total this will save about 1K. +type symOffset uint16 + +type altSymData struct { + compactTag compact.ID + symIndex symOffset + system system +} diff --git a/vendor/golang.org/x/text/internal/number/decimal.go b/vendor/golang.org/x/text/internal/number/decimal.go new file mode 100644 index 00000000000..e128cf34377 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/decimal.go @@ -0,0 +1,500 @@ +// Copyright 2017 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 stringer -type RoundingMode + +package number + +import ( + "math" + "strconv" +) + +// RoundingMode determines how a number is rounded to the desired precision. +type RoundingMode byte + +const ( + ToNearestEven RoundingMode = iota // towards the nearest integer, or towards an even number if equidistant. + ToNearestZero // towards the nearest integer, or towards zero if equidistant. + ToNearestAway // towards the nearest integer, or away from zero if equidistant. + ToPositiveInf // towards infinity + ToNegativeInf // towards negative infinity + ToZero // towards zero + AwayFromZero // away from zero + numModes +) + +const maxIntDigits = 20 + +// A Decimal represents a floating point number in decimal format. +// Digits represents a number [0, 1.0), and the absolute value represented by +// Decimal is Digits * 10^Exp. Leading and trailing zeros may be omitted and Exp +// may point outside a valid position in Digits. +// +// Examples: +// +// Number Decimal +// 12345 Digits: [1, 2, 3, 4, 5], Exp: 5 +// 12.345 Digits: [1, 2, 3, 4, 5], Exp: 2 +// 12000 Digits: [1, 2], Exp: 5 +// 12000.00 Digits: [1, 2], Exp: 5 +// 0.00123 Digits: [1, 2, 3], Exp: -2 +// 0 Digits: [], Exp: 0 +type Decimal struct { + digits + + buf [maxIntDigits]byte +} + +type digits struct { + Digits []byte // mantissa digits, big-endian + Exp int32 // exponent + Neg bool + Inf bool // Takes precedence over Digits and Exp. + NaN bool // Takes precedence over Inf. +} + +// Digits represents a floating point number represented in digits of the +// base in which a number is to be displayed. It is similar to Decimal, but +// keeps track of trailing fraction zeros and the comma placement for +// engineering notation. Digits must have at least one digit. +// +// Examples: +// +// Number Decimal +// decimal +// 12345 Digits: [1, 2, 3, 4, 5], Exp: 5 End: 5 +// 12.345 Digits: [1, 2, 3, 4, 5], Exp: 2 End: 5 +// 12000 Digits: [1, 2], Exp: 5 End: 5 +// 12000.00 Digits: [1, 2], Exp: 5 End: 7 +// 0.00123 Digits: [1, 2, 3], Exp: -2 End: 3 +// 0 Digits: [], Exp: 0 End: 1 +// scientific (actual exp is Exp - Comma) +// 0e0 Digits: [0], Exp: 1, End: 1, Comma: 1 +// .0e0 Digits: [0], Exp: 0, End: 1, Comma: 0 +// 0.0e0 Digits: [0], Exp: 1, End: 2, Comma: 1 +// 1.23e4 Digits: [1, 2, 3], Exp: 5, End: 3, Comma: 1 +// .123e5 Digits: [1, 2, 3], Exp: 5, End: 3, Comma: 0 +// engineering +// 12.3e3 Digits: [1, 2, 3], Exp: 5, End: 3, Comma: 2 +type Digits struct { + digits + // End indicates the end position of the number. + End int32 // For decimals Exp <= End. For scientific len(Digits) <= End. + // Comma is used for the comma position for scientific (always 0 or 1) and + // engineering notation (always 0, 1, 2, or 3). + Comma uint8 + // IsScientific indicates whether this number is to be rendered as a + // scientific number. + IsScientific bool +} + +func (d *Digits) NumFracDigits() int { + if d.Exp >= d.End { + return 0 + } + return int(d.End - d.Exp) +} + +// normalize returns a new Decimal with leading and trailing zeros removed. +func (d *Decimal) normalize() (n Decimal) { + n = *d + b := n.Digits + // Strip leading zeros. Resulting number of digits is significant digits. + for len(b) > 0 && b[0] == 0 { + b = b[1:] + n.Exp-- + } + // Strip trailing zeros + for len(b) > 0 && b[len(b)-1] == 0 { + b = b[:len(b)-1] + } + if len(b) == 0 { + n.Exp = 0 + } + n.Digits = b + return n +} + +func (d *Decimal) clear() { + b := d.Digits + if b == nil { + b = d.buf[:0] + } + *d = Decimal{} + d.Digits = b[:0] +} + +func (x *Decimal) String() string { + if x.NaN { + return "NaN" + } + var buf []byte + if x.Neg { + buf = append(buf, '-') + } + if x.Inf { + buf = append(buf, "Inf"...) + return string(buf) + } + switch { + case len(x.Digits) == 0: + buf = append(buf, '0') + case x.Exp <= 0: + // 0.00ddd + buf = append(buf, "0."...) + buf = appendZeros(buf, -int(x.Exp)) + buf = appendDigits(buf, x.Digits) + + case /* 0 < */ int(x.Exp) < len(x.Digits): + // dd.ddd + buf = appendDigits(buf, x.Digits[:x.Exp]) + buf = append(buf, '.') + buf = appendDigits(buf, x.Digits[x.Exp:]) + + default: // len(x.Digits) <= x.Exp + // ddd00 + buf = appendDigits(buf, x.Digits) + buf = appendZeros(buf, int(x.Exp)-len(x.Digits)) + } + return string(buf) +} + +func appendDigits(buf []byte, digits []byte) []byte { + for _, c := range digits { + buf = append(buf, c+'0') + } + return buf +} + +// appendZeros appends n 0 digits to buf and returns buf. +func appendZeros(buf []byte, n int) []byte { + for ; n > 0; n-- { + buf = append(buf, '0') + } + return buf +} + +func (d *digits) round(mode RoundingMode, n int) { + if n >= len(d.Digits) { + return + } + // Make rounding decision: The result mantissa is truncated ("rounded down") + // by default. Decide if we need to increment, or "round up", the (unsigned) + // mantissa. + inc := false + switch mode { + case ToNegativeInf: + inc = d.Neg + case ToPositiveInf: + inc = !d.Neg + case ToZero: + // nothing to do + case AwayFromZero: + inc = true + case ToNearestEven: + inc = d.Digits[n] > 5 || d.Digits[n] == 5 && + (len(d.Digits) > n+1 || n == 0 || d.Digits[n-1]&1 != 0) + case ToNearestAway: + inc = d.Digits[n] >= 5 + case ToNearestZero: + inc = d.Digits[n] > 5 || d.Digits[n] == 5 && len(d.Digits) > n+1 + default: + panic("unreachable") + } + if inc { + d.roundUp(n) + } else { + d.roundDown(n) + } +} + +// roundFloat rounds a floating point number. +func (r RoundingMode) roundFloat(x float64) float64 { + // Make rounding decision: The result mantissa is truncated ("rounded down") + // by default. Decide if we need to increment, or "round up", the (unsigned) + // mantissa. + abs := x + if x < 0 { + abs = -x + } + i, f := math.Modf(abs) + if f == 0.0 { + return x + } + inc := false + switch r { + case ToNegativeInf: + inc = x < 0 + case ToPositiveInf: + inc = x >= 0 + case ToZero: + // nothing to do + case AwayFromZero: + inc = true + case ToNearestEven: + // TODO: check overflow + inc = f > 0.5 || f == 0.5 && int64(i)&1 != 0 + case ToNearestAway: + inc = f >= 0.5 + case ToNearestZero: + inc = f > 0.5 + default: + panic("unreachable") + } + if inc { + i += 1 + } + if abs != x { + i = -i + } + return i +} + +func (x *digits) roundUp(n int) { + if n < 0 || n >= len(x.Digits) { + return // nothing to do + } + // find first digit < 9 + for n > 0 && x.Digits[n-1] >= 9 { + n-- + } + + if n == 0 { + // all digits are 9s => round up to 1 and update exponent + x.Digits[0] = 1 // ok since len(x.Digits) > n + x.Digits = x.Digits[:1] + x.Exp++ + return + } + x.Digits[n-1]++ + x.Digits = x.Digits[:n] + // x already trimmed +} + +func (x *digits) roundDown(n int) { + if n < 0 || n >= len(x.Digits) { + return // nothing to do + } + x.Digits = x.Digits[:n] + trim(x) +} + +// trim cuts off any trailing zeros from x's mantissa; +// they are meaningless for the value of x. +func trim(x *digits) { + i := len(x.Digits) + for i > 0 && x.Digits[i-1] == 0 { + i-- + } + x.Digits = x.Digits[:i] + if i == 0 { + x.Exp = 0 + } +} + +// A Converter converts a number into decimals according to the given rounding +// criteria. +type Converter interface { + Convert(d *Decimal, r RoundingContext) +} + +const ( + signed = true + unsigned = false +) + +// Convert converts the given number to the decimal representation using the +// supplied RoundingContext. +func (d *Decimal) Convert(r RoundingContext, number interface{}) { + switch f := number.(type) { + case Converter: + d.clear() + f.Convert(d, r) + case float32: + d.ConvertFloat(r, float64(f), 32) + case float64: + d.ConvertFloat(r, f, 64) + case int: + d.ConvertInt(r, signed, uint64(f)) + case int8: + d.ConvertInt(r, signed, uint64(f)) + case int16: + d.ConvertInt(r, signed, uint64(f)) + case int32: + d.ConvertInt(r, signed, uint64(f)) + case int64: + d.ConvertInt(r, signed, uint64(f)) + case uint: + d.ConvertInt(r, unsigned, uint64(f)) + case uint8: + d.ConvertInt(r, unsigned, uint64(f)) + case uint16: + d.ConvertInt(r, unsigned, uint64(f)) + case uint32: + d.ConvertInt(r, unsigned, uint64(f)) + case uint64: + d.ConvertInt(r, unsigned, f) + + default: + d.NaN = true + // TODO: + // case string: if produced by strconv, allows for easy arbitrary pos. + // case reflect.Value: + // case big.Float + // case big.Int + // case big.Rat? + // catch underlyings using reflect or will this already be done by the + // message package? + } +} + +// ConvertInt converts an integer to decimals. +func (d *Decimal) ConvertInt(r RoundingContext, signed bool, x uint64) { + if r.Increment > 0 { + // TODO: if uint64 is too large, fall back to float64 + if signed { + d.ConvertFloat(r, float64(int64(x)), 64) + } else { + d.ConvertFloat(r, float64(x), 64) + } + return + } + d.clear() + if signed && int64(x) < 0 { + x = uint64(-int64(x)) + d.Neg = true + } + d.fillIntDigits(x) + d.Exp = int32(len(d.Digits)) +} + +// ConvertFloat converts a floating point number to decimals. +func (d *Decimal) ConvertFloat(r RoundingContext, x float64, size int) { + d.clear() + if math.IsNaN(x) { + d.NaN = true + return + } + // Simple case: decimal notation + if r.Increment > 0 { + scale := int(r.IncrementScale) + mult := 1.0 + if scale >= len(scales) { + mult = math.Pow(10, float64(scale)) + } else { + mult = scales[scale] + } + // We multiply x instead of dividing inc as it gives less rounding + // issues. + x *= mult + x /= float64(r.Increment) + x = r.Mode.roundFloat(x) + x *= float64(r.Increment) + x /= mult + } + + abs := x + if x < 0 { + d.Neg = true + abs = -x + } + if math.IsInf(abs, 1) { + d.Inf = true + return + } + + // By default we get the exact decimal representation. + verb := byte('g') + prec := -1 + // As the strconv API does not return the rounding accuracy, we can only + // round using ToNearestEven. + if r.Mode == ToNearestEven { + if n := r.RoundSignificantDigits(); n >= 0 { + prec = n + } else if n = r.RoundFractionDigits(); n >= 0 { + prec = n + verb = 'f' + } + } else { + // TODO: At this point strconv's rounding is imprecise to the point that + // it is not usable for this purpose. + // See https://github.com/golang/go/issues/21714 + // If rounding is requested, we ask for a large number of digits and + // round from there to simulate rounding only once. + // Ideally we would have strconv export an AppendDigits that would take + // a rounding mode and/or return an accuracy. Something like this would + // work: + // AppendDigits(dst []byte, x float64, base, size, prec int) (digits []byte, exp, accuracy int) + hasPrec := r.RoundSignificantDigits() >= 0 + hasScale := r.RoundFractionDigits() >= 0 + if hasPrec || hasScale { + // prec is the number of mantissa bits plus some extra for safety. + // We need at least the number of mantissa bits as decimals to + // accurately represent the floating point without rounding, as each + // bit requires one more decimal to represent: 0.5, 0.25, 0.125, ... + prec = 60 + } + } + + b := strconv.AppendFloat(d.Digits[:0], abs, verb, prec, size) + i := 0 + k := 0 + beforeDot := 1 + for i < len(b) { + if c := b[i]; '0' <= c && c <= '9' { + b[k] = c - '0' + k++ + d.Exp += int32(beforeDot) + } else if c == '.' { + beforeDot = 0 + d.Exp = int32(k) + } else { + break + } + i++ + } + d.Digits = b[:k] + if i != len(b) { + i += len("e") + pSign := i + exp := 0 + for i++; i < len(b); i++ { + exp *= 10 + exp += int(b[i] - '0') + } + if b[pSign] == '-' { + exp = -exp + } + d.Exp = int32(exp) + 1 + } +} + +func (d *Decimal) fillIntDigits(x uint64) { + if cap(d.Digits) < maxIntDigits { + d.Digits = d.buf[:] + } else { + d.Digits = d.buf[:maxIntDigits] + } + i := 0 + for ; x > 0; x /= 10 { + d.Digits[i] = byte(x % 10) + i++ + } + d.Digits = d.Digits[:i] + for p := 0; p < i; p++ { + i-- + d.Digits[p], d.Digits[i] = d.Digits[i], d.Digits[p] + } +} + +var scales [70]float64 + +func init() { + x := 1.0 + for i := range scales { + scales[i] = x + x *= 10 + } +} diff --git a/vendor/golang.org/x/text/internal/number/format.go b/vendor/golang.org/x/text/internal/number/format.go new file mode 100644 index 00000000000..1aadcf40777 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/format.go @@ -0,0 +1,533 @@ +// Copyright 2017 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 number + +import ( + "strconv" + "unicode/utf8" + + "golang.org/x/text/language" +) + +// TODO: +// - grouping of fractions +// - allow user-defined superscript notation (such as 4) +// - same for non-breaking spaces, like   + +// A VisibleDigits computes digits, comma placement and trailing zeros as they +// will be shown to the user. +type VisibleDigits interface { + Digits(buf []byte, t language.Tag, scale int) Digits + // TODO: Do we also need to add the verb or pass a format.State? +} + +// Formatting proceeds along the following lines: +// 0) Compose rounding information from format and context. +// 1) Convert a number into a Decimal. +// 2) Sanitize Decimal by adding trailing zeros, removing leading digits, and +// (non-increment) rounding. The Decimal that results from this is suitable +// for determining the plural form. +// 3) Render the Decimal in the localized form. + +// Formatter contains all the information needed to render a number. +type Formatter struct { + Pattern + Info +} + +func (f *Formatter) init(t language.Tag, index []uint8) { + f.Info = InfoFromTag(t) + f.Pattern = formats[index[tagToID(t)]] +} + +// InitPattern initializes a Formatter for the given Pattern. +func (f *Formatter) InitPattern(t language.Tag, pat *Pattern) { + f.Info = InfoFromTag(t) + f.Pattern = *pat +} + +// InitDecimal initializes a Formatter using the default Pattern for the given +// language. +func (f *Formatter) InitDecimal(t language.Tag) { + f.init(t, tagToDecimal) +} + +// InitScientific initializes a Formatter using the default Pattern for the +// given language. +func (f *Formatter) InitScientific(t language.Tag) { + f.init(t, tagToScientific) + f.Pattern.MinFractionDigits = 0 + f.Pattern.MaxFractionDigits = -1 +} + +// InitEngineering initializes a Formatter using the default Pattern for the +// given language. +func (f *Formatter) InitEngineering(t language.Tag) { + f.init(t, tagToScientific) + f.Pattern.MinFractionDigits = 0 + f.Pattern.MaxFractionDigits = -1 + f.Pattern.MaxIntegerDigits = 3 + f.Pattern.MinIntegerDigits = 1 +} + +// InitPercent initializes a Formatter using the default Pattern for the given +// language. +func (f *Formatter) InitPercent(t language.Tag) { + f.init(t, tagToPercent) +} + +// InitPerMille initializes a Formatter using the default Pattern for the given +// language. +func (f *Formatter) InitPerMille(t language.Tag) { + f.init(t, tagToPercent) + f.Pattern.DigitShift = 3 +} + +func (f *Formatter) Append(dst []byte, x interface{}) []byte { + var d Decimal + r := f.RoundingContext + d.Convert(r, x) + return f.Render(dst, FormatDigits(&d, r)) +} + +func FormatDigits(d *Decimal, r RoundingContext) Digits { + if r.isScientific() { + return scientificVisibleDigits(r, d) + } + return decimalVisibleDigits(r, d) +} + +func (f *Formatter) Format(dst []byte, d *Decimal) []byte { + return f.Render(dst, FormatDigits(d, f.RoundingContext)) +} + +func (f *Formatter) Render(dst []byte, d Digits) []byte { + var result []byte + var postPrefix, preSuffix int + if d.IsScientific { + result, postPrefix, preSuffix = appendScientific(dst, f, &d) + } else { + result, postPrefix, preSuffix = appendDecimal(dst, f, &d) + } + if f.PadRune == 0 { + return result + } + width := int(f.FormatWidth) + if count := utf8.RuneCount(result); count < width { + insertPos := 0 + switch f.Flags & PadMask { + case PadAfterPrefix: + insertPos = postPrefix + case PadBeforeSuffix: + insertPos = preSuffix + case PadAfterSuffix: + insertPos = len(result) + } + num := width - count + pad := [utf8.UTFMax]byte{' '} + sz := 1 + if r := f.PadRune; r != 0 { + sz = utf8.EncodeRune(pad[:], r) + } + extra := sz * num + if n := len(result) + extra; n < cap(result) { + result = result[:n] + copy(result[insertPos+extra:], result[insertPos:]) + } else { + buf := make([]byte, n) + copy(buf, result[:insertPos]) + copy(buf[insertPos+extra:], result[insertPos:]) + result = buf + } + for ; num > 0; num-- { + insertPos += copy(result[insertPos:], pad[:sz]) + } + } + return result +} + +// decimalVisibleDigits converts d according to the RoundingContext. Note that +// the exponent may change as a result of this operation. +func decimalVisibleDigits(r RoundingContext, d *Decimal) Digits { + if d.NaN || d.Inf { + return Digits{digits: digits{Neg: d.Neg, NaN: d.NaN, Inf: d.Inf}} + } + n := Digits{digits: d.normalize().digits} + + exp := n.Exp + exp += int32(r.DigitShift) + + // Cap integer digits. Remove *most-significant* digits. + if r.MaxIntegerDigits > 0 { + if p := int(exp) - int(r.MaxIntegerDigits); p > 0 { + if p > len(n.Digits) { + p = len(n.Digits) + } + if n.Digits = n.Digits[p:]; len(n.Digits) == 0 { + exp = 0 + } else { + exp -= int32(p) + } + // Strip leading zeros. + for len(n.Digits) > 0 && n.Digits[0] == 0 { + n.Digits = n.Digits[1:] + exp-- + } + } + } + + // Rounding if not already done by Convert. + p := len(n.Digits) + if maxSig := int(r.MaxSignificantDigits); maxSig > 0 { + p = maxSig + } + if maxFrac := int(r.MaxFractionDigits); maxFrac >= 0 { + if cap := int(exp) + maxFrac; cap < p { + p = int(exp) + maxFrac + } + if p < 0 { + p = 0 + } + } + n.round(r.Mode, p) + + // set End (trailing zeros) + n.End = int32(len(n.Digits)) + if n.End == 0 { + exp = 0 + if r.MinFractionDigits > 0 { + n.End = int32(r.MinFractionDigits) + } + if p := int32(r.MinSignificantDigits) - 1; p > n.End { + n.End = p + } + } else { + if end := exp + int32(r.MinFractionDigits); end > n.End { + n.End = end + } + if n.End < int32(r.MinSignificantDigits) { + n.End = int32(r.MinSignificantDigits) + } + } + n.Exp = exp + return n +} + +// appendDecimal appends a formatted number to dst. It returns two possible +// insertion points for padding. +func appendDecimal(dst []byte, f *Formatter, n *Digits) (b []byte, postPre, preSuf int) { + if dst, ok := f.renderSpecial(dst, n); ok { + return dst, 0, len(dst) + } + digits := n.Digits + exp := n.Exp + + // Split in integer and fraction part. + var intDigits, fracDigits []byte + numInt := 0 + numFrac := int(n.End - n.Exp) + if exp > 0 { + numInt = int(exp) + if int(exp) >= len(digits) { // ddddd | ddddd00 + intDigits = digits + } else { // ddd.dd + intDigits = digits[:exp] + fracDigits = digits[exp:] + } + } else { + fracDigits = digits + } + + neg := n.Neg + affix, suffix := f.getAffixes(neg) + dst = appendAffix(dst, f, affix, neg) + savedLen := len(dst) + + minInt := int(f.MinIntegerDigits) + if minInt == 0 && f.MinSignificantDigits > 0 { + minInt = 1 + } + // add leading zeros + for i := minInt; i > numInt; i-- { + dst = f.AppendDigit(dst, 0) + if f.needsSep(i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + i := 0 + for ; i < len(intDigits); i++ { + dst = f.AppendDigit(dst, intDigits[i]) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + for ; i < numInt; i++ { + dst = f.AppendDigit(dst, 0) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + + if numFrac > 0 || f.Flags&AlwaysDecimalSeparator != 0 { + dst = append(dst, f.Symbol(SymDecimal)...) + } + // Add trailing zeros + i = 0 + for n := -int(n.Exp); i < n; i++ { + dst = f.AppendDigit(dst, 0) + } + for _, d := range fracDigits { + i++ + dst = f.AppendDigit(dst, d) + } + for ; i < numFrac; i++ { + dst = f.AppendDigit(dst, 0) + } + return appendAffix(dst, f, suffix, neg), savedLen, len(dst) +} + +func scientificVisibleDigits(r RoundingContext, d *Decimal) Digits { + if d.NaN || d.Inf { + return Digits{digits: digits{Neg: d.Neg, NaN: d.NaN, Inf: d.Inf}} + } + n := Digits{digits: d.normalize().digits, IsScientific: true} + + // Normalize to have at least one digit. This simplifies engineering + // notation. + if len(n.Digits) == 0 { + n.Digits = append(n.Digits, 0) + n.Exp = 1 + } + + // Significant digits are transformed by the parser for scientific notation + // and do not need to be handled here. + maxInt, numInt := int(r.MaxIntegerDigits), int(r.MinIntegerDigits) + if numInt == 0 { + numInt = 1 + } + + // If a maximum number of integers is specified, the minimum must be 1 + // and the exponent is grouped by this number (e.g. for engineering) + if maxInt > numInt { + // Correct the exponent to reflect a single integer digit. + numInt = 1 + // engineering + // 0.01234 ([12345]e-1) -> 1.2345e-2 12.345e-3 + // 12345 ([12345]e+5) -> 1.2345e4 12.345e3 + d := int(n.Exp-1) % maxInt + if d < 0 { + d += maxInt + } + numInt += d + } + + p := len(n.Digits) + if maxSig := int(r.MaxSignificantDigits); maxSig > 0 { + p = maxSig + } + if maxFrac := int(r.MaxFractionDigits); maxFrac >= 0 && numInt+maxFrac < p { + p = numInt + maxFrac + } + n.round(r.Mode, p) + + n.Comma = uint8(numInt) + n.End = int32(len(n.Digits)) + if minSig := int32(r.MinFractionDigits) + int32(numInt); n.End < minSig { + n.End = minSig + } + return n +} + +// appendScientific appends a formatted number to dst. It returns two possible +// insertion points for padding. +func appendScientific(dst []byte, f *Formatter, n *Digits) (b []byte, postPre, preSuf int) { + if dst, ok := f.renderSpecial(dst, n); ok { + return dst, 0, 0 + } + digits := n.Digits + numInt := int(n.Comma) + numFrac := int(n.End) - int(n.Comma) + + var intDigits, fracDigits []byte + if numInt <= len(digits) { + intDigits = digits[:numInt] + fracDigits = digits[numInt:] + } else { + intDigits = digits + } + neg := n.Neg + affix, suffix := f.getAffixes(neg) + dst = appendAffix(dst, f, affix, neg) + savedLen := len(dst) + + i := 0 + for ; i < len(intDigits); i++ { + dst = f.AppendDigit(dst, intDigits[i]) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + for ; i < numInt; i++ { + dst = f.AppendDigit(dst, 0) + if f.needsSep(numInt - i) { + dst = append(dst, f.Symbol(SymGroup)...) + } + } + + if numFrac > 0 || f.Flags&AlwaysDecimalSeparator != 0 { + dst = append(dst, f.Symbol(SymDecimal)...) + } + i = 0 + for ; i < len(fracDigits); i++ { + dst = f.AppendDigit(dst, fracDigits[i]) + } + for ; i < numFrac; i++ { + dst = f.AppendDigit(dst, 0) + } + + // exp + buf := [12]byte{} + // TODO: use exponential if superscripting is not available (no Latin + // numbers or no tags) and use exponential in all other cases. + exp := n.Exp - int32(n.Comma) + exponential := f.Symbol(SymExponential) + if exponential == "E" { + dst = append(dst, f.Symbol(SymSuperscriptingExponent)...) + dst = f.AppendDigit(dst, 1) + dst = f.AppendDigit(dst, 0) + switch { + case exp < 0: + dst = append(dst, superMinus...) + exp = -exp + case f.Flags&AlwaysExpSign != 0: + dst = append(dst, superPlus...) + } + b = strconv.AppendUint(buf[:0], uint64(exp), 10) + for i := len(b); i < int(f.MinExponentDigits); i++ { + dst = append(dst, superDigits[0]...) + } + for _, c := range b { + dst = append(dst, superDigits[c-'0']...) + } + } else { + dst = append(dst, exponential...) + switch { + case exp < 0: + dst = append(dst, f.Symbol(SymMinusSign)...) + exp = -exp + case f.Flags&AlwaysExpSign != 0: + dst = append(dst, f.Symbol(SymPlusSign)...) + } + b = strconv.AppendUint(buf[:0], uint64(exp), 10) + for i := len(b); i < int(f.MinExponentDigits); i++ { + dst = f.AppendDigit(dst, 0) + } + for _, c := range b { + dst = f.AppendDigit(dst, c-'0') + } + } + return appendAffix(dst, f, suffix, neg), savedLen, len(dst) +} + +const ( + superMinus = "\u207B" // SUPERSCRIPT HYPHEN-MINUS + superPlus = "\u207A" // SUPERSCRIPT PLUS SIGN +) + +var ( + // Note: the digits are not sequential!!! + superDigits = []string{ + "\u2070", // SUPERSCRIPT DIGIT ZERO + "\u00B9", // SUPERSCRIPT DIGIT ONE + "\u00B2", // SUPERSCRIPT DIGIT TWO + "\u00B3", // SUPERSCRIPT DIGIT THREE + "\u2074", // SUPERSCRIPT DIGIT FOUR + "\u2075", // SUPERSCRIPT DIGIT FIVE + "\u2076", // SUPERSCRIPT DIGIT SIX + "\u2077", // SUPERSCRIPT DIGIT SEVEN + "\u2078", // SUPERSCRIPT DIGIT EIGHT + "\u2079", // SUPERSCRIPT DIGIT NINE + } +) + +func (f *Formatter) getAffixes(neg bool) (affix, suffix string) { + str := f.Affix + if str != "" { + if f.NegOffset > 0 { + if neg { + str = str[f.NegOffset:] + } else { + str = str[:f.NegOffset] + } + } + sufStart := 1 + str[0] + affix = str[1:sufStart] + suffix = str[sufStart+1:] + } + // TODO: introduce a NeedNeg sign to indicate if the left pattern already + // has a sign marked? + if f.NegOffset == 0 && (neg || f.Flags&AlwaysSign != 0) { + affix = "-" + affix + } + return affix, suffix +} + +func (f *Formatter) renderSpecial(dst []byte, d *Digits) (b []byte, ok bool) { + if d.NaN { + return fmtNaN(dst, f), true + } + if d.Inf { + return fmtInfinite(dst, f, d), true + } + return dst, false +} + +func fmtNaN(dst []byte, f *Formatter) []byte { + return append(dst, f.Symbol(SymNan)...) +} + +func fmtInfinite(dst []byte, f *Formatter, d *Digits) []byte { + affix, suffix := f.getAffixes(d.Neg) + dst = appendAffix(dst, f, affix, d.Neg) + dst = append(dst, f.Symbol(SymInfinity)...) + dst = appendAffix(dst, f, suffix, d.Neg) + return dst +} + +func appendAffix(dst []byte, f *Formatter, affix string, neg bool) []byte { + quoting := false + escaping := false + for _, r := range affix { + switch { + case escaping: + // escaping occurs both inside and outside of quotes + dst = append(dst, string(r)...) + escaping = false + case r == '\\': + escaping = true + case r == '\'': + quoting = !quoting + case quoting: + dst = append(dst, string(r)...) + case r == '%': + if f.DigitShift == 3 { + dst = append(dst, f.Symbol(SymPerMille)...) + } else { + dst = append(dst, f.Symbol(SymPercentSign)...) + } + case r == '-' || r == '+': + if neg { + dst = append(dst, f.Symbol(SymMinusSign)...) + } else if f.Flags&ElideSign == 0 { + dst = append(dst, f.Symbol(SymPlusSign)...) + } else { + dst = append(dst, ' ') + } + default: + dst = append(dst, string(r)...) + } + } + return dst +} diff --git a/vendor/golang.org/x/text/internal/number/number.go b/vendor/golang.org/x/text/internal/number/number.go new file mode 100644 index 00000000000..e1d933c3f7e --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/number.go @@ -0,0 +1,152 @@ +// Copyright 2016 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 gen_common.go + +// Package number contains tools and data for formatting numbers. +package number + +import ( + "unicode/utf8" + + "golang.org/x/text/internal/language/compact" + "golang.org/x/text/language" +) + +// Info holds number formatting configuration data. +type Info struct { + system systemData // numbering system information + symIndex symOffset // index to symbols +} + +// InfoFromLangID returns a Info for the given compact language identifier and +// numbering system identifier. If system is the empty string, the default +// numbering system will be taken for that language. +func InfoFromLangID(compactIndex compact.ID, numberSystem string) Info { + p := langToDefaults[compactIndex] + // Lookup the entry for the language. + pSymIndex := symOffset(0) // Default: Latin, default symbols + system, ok := systemMap[numberSystem] + if !ok { + // Take the value for the default numbering system. This is by far the + // most common case as an alternative numbering system is hardly used. + if p&hasNonLatnMask == 0 { // Latn digits. + pSymIndex = p + } else { // Non-Latn or multiple numbering systems. + // Take the first entry from the alternatives list. + data := langToAlt[p&^hasNonLatnMask] + pSymIndex = data.symIndex + system = data.system + } + } else { + langIndex := compactIndex + ns := system + outerLoop: + for ; ; p = langToDefaults[langIndex] { + if p&hasNonLatnMask == 0 { + if ns == 0 { + // The index directly points to the symbol data. + pSymIndex = p + break + } + // Move to the parent and retry. + langIndex = langIndex.Parent() + } else { + // The index points to a list of symbol data indexes. + for _, e := range langToAlt[p&^hasNonLatnMask:] { + if e.compactTag != langIndex { + if langIndex == 0 { + // The CLDR root defines full symbol information for + // all numbering systems (even though mostly by + // means of aliases). Fall back to the default entry + // for Latn if there is no data for the numbering + // system of this language. + if ns == 0 { + break + } + // Fall back to Latin and start from the original + // language. See + // https://unicode.org/reports/tr35/#Locale_Inheritance. + ns = numLatn + langIndex = compactIndex + continue outerLoop + } + // Fall back to parent. + langIndex = langIndex.Parent() + } else if e.system == ns { + pSymIndex = e.symIndex + break outerLoop + } + } + } + } + } + if int(system) >= len(numSysData) { // algorithmic + // Will generate ASCII digits in case the user inadvertently calls + // WriteDigit or Digit on it. + d := numSysData[0] + d.id = system + return Info{ + system: d, + symIndex: pSymIndex, + } + } + return Info{ + system: numSysData[system], + symIndex: pSymIndex, + } +} + +// InfoFromTag returns a Info for the given language tag. +func InfoFromTag(t language.Tag) Info { + return InfoFromLangID(tagToID(t), t.TypeForKey("nu")) +} + +// IsDecimal reports if the numbering system can convert decimal to native +// symbols one-to-one. +func (n Info) IsDecimal() bool { + return int(n.system.id) < len(numSysData) +} + +// WriteDigit writes the UTF-8 sequence for n corresponding to the given ASCII +// digit to dst and reports the number of bytes written. dst must be large +// enough to hold the rune (can be up to utf8.UTFMax bytes). +func (n Info) WriteDigit(dst []byte, asciiDigit rune) int { + copy(dst, n.system.zero[:n.system.digitSize]) + dst[n.system.digitSize-1] += byte(asciiDigit - '0') + return int(n.system.digitSize) +} + +// AppendDigit appends the UTF-8 sequence for n corresponding to the given digit +// to dst and reports the number of bytes written. dst must be large enough to +// hold the rune (can be up to utf8.UTFMax bytes). +func (n Info) AppendDigit(dst []byte, digit byte) []byte { + dst = append(dst, n.system.zero[:n.system.digitSize]...) + dst[len(dst)-1] += digit + return dst +} + +// Digit returns the digit for the numbering system for the corresponding ASCII +// value. For example, ni.Digit('3') could return '三'. Note that the argument +// is the rune constant '3', which equals 51, not the integer constant 3. +func (n Info) Digit(asciiDigit rune) rune { + var x [utf8.UTFMax]byte + n.WriteDigit(x[:], asciiDigit) + r, _ := utf8.DecodeRune(x[:]) + return r +} + +// Symbol returns the string for the given symbol type. +func (n Info) Symbol(t SymbolType) string { + return symData.Elem(int(symIndex[n.symIndex][t])) +} + +func formatForLang(t language.Tag, index []byte) *Pattern { + return &formats[index[tagToID(t)]] +} + +func tagToID(t language.Tag) compact.ID { + id, _ := compact.RegionalID(compact.Tag(t)) + return id +} diff --git a/vendor/golang.org/x/text/internal/number/pattern.go b/vendor/golang.org/x/text/internal/number/pattern.go new file mode 100644 index 00000000000..06e59559a96 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/pattern.go @@ -0,0 +1,485 @@ +// 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 number + +import ( + "errors" + "unicode/utf8" +) + +// This file contains a parser for the CLDR number patterns as described in +// https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns. +// +// The following BNF is derived from this standard. +// +// pattern := subpattern (';' subpattern)? +// subpattern := affix? number exponent? affix? +// number := decimal | sigDigits +// decimal := '#'* '0'* ('.' fraction)? | '#' | '0' +// fraction := '0'* '#'* +// sigDigits := '#'* '@' '@'* '#'* +// exponent := 'E' '+'? '0'* '0' +// padSpec := '*' \L +// +// Notes: +// - An affix pattern may contain any runes, but runes with special meaning +// should be escaped. +// - Sequences of digits, '#', and '@' in decimal and sigDigits may have +// interstitial commas. + +// TODO: replace special characters in affixes (-, +, ¤) with control codes. + +// Pattern holds information for formatting numbers. It is designed to hold +// information from CLDR number patterns. +// +// This pattern is precompiled for all patterns for all languages. Even though +// the number of patterns is not very large, we want to keep this small. +// +// This type is only intended for internal use. +type Pattern struct { + RoundingContext + + Affix string // includes prefix and suffix. First byte is prefix length. + Offset uint16 // Offset into Affix for prefix and suffix + NegOffset uint16 // Offset into Affix for negative prefix and suffix or 0. + PadRune rune + FormatWidth uint16 + + GroupingSize [2]uint8 + Flags PatternFlag +} + +// A RoundingContext indicates how a number should be converted to digits. +// It contains all information needed to determine the "visible digits" as +// required by the pluralization rules. +type RoundingContext struct { + // TODO: unify these two fields so that there is a more unambiguous meaning + // of how precision is handled. + MaxSignificantDigits int16 // -1 is unlimited + MaxFractionDigits int16 // -1 is unlimited + + Increment uint32 + IncrementScale uint8 // May differ from printed scale. + + Mode RoundingMode + + DigitShift uint8 // Number of decimals to shift. Used for % and ‰. + + // Number of digits. + MinIntegerDigits uint8 + + MaxIntegerDigits uint8 + MinFractionDigits uint8 + MinSignificantDigits uint8 + + MinExponentDigits uint8 +} + +// RoundSignificantDigits returns the number of significant digits an +// implementation of Convert may round to or n < 0 if there is no maximum or +// a maximum is not recommended. +func (r *RoundingContext) RoundSignificantDigits() (n int) { + if r.MaxFractionDigits == 0 && r.MaxSignificantDigits > 0 { + return int(r.MaxSignificantDigits) + } else if r.isScientific() && r.MaxIntegerDigits == 1 { + if r.MaxSignificantDigits == 0 || + int(r.MaxFractionDigits+1) == int(r.MaxSignificantDigits) { + // Note: don't add DigitShift: it is only used for decimals. + return int(r.MaxFractionDigits) + 1 + } + } + return -1 +} + +// RoundFractionDigits returns the number of fraction digits an implementation +// of Convert may round to or n < 0 if there is no maximum or a maximum is not +// recommended. +func (r *RoundingContext) RoundFractionDigits() (n int) { + if r.MinExponentDigits == 0 && + r.MaxSignificantDigits == 0 && + r.MaxFractionDigits >= 0 { + return int(r.MaxFractionDigits) + int(r.DigitShift) + } + return -1 +} + +// SetScale fixes the RoundingContext to a fixed number of fraction digits. +func (r *RoundingContext) SetScale(scale int) { + r.MinFractionDigits = uint8(scale) + r.MaxFractionDigits = int16(scale) +} + +func (r *RoundingContext) SetPrecision(prec int) { + r.MaxSignificantDigits = int16(prec) +} + +func (r *RoundingContext) isScientific() bool { + return r.MinExponentDigits > 0 +} + +func (f *Pattern) needsSep(pos int) bool { + p := pos - 1 + size := int(f.GroupingSize[0]) + if size == 0 || p == 0 { + return false + } + if p == size { + return true + } + if p -= size; p < 0 { + return false + } + // TODO: make second groupingsize the same as first if 0 so that we can + // avoid this check. + if x := int(f.GroupingSize[1]); x != 0 { + size = x + } + return p%size == 0 +} + +// A PatternFlag is a bit mask for the flag field of a Pattern. +type PatternFlag uint8 + +const ( + AlwaysSign PatternFlag = 1 << iota + ElideSign // Use space instead of plus sign. AlwaysSign must be true. + AlwaysExpSign + AlwaysDecimalSeparator + ParenthesisForNegative // Common pattern. Saves space. + + PadAfterNumber + PadAfterAffix + + PadBeforePrefix = 0 // Default + PadAfterPrefix = PadAfterAffix + PadBeforeSuffix = PadAfterNumber + PadAfterSuffix = PadAfterNumber | PadAfterAffix + PadMask = PadAfterNumber | PadAfterAffix +) + +type parser struct { + *Pattern + + leadingSharps int + + pos int + err error + doNotTerminate bool + groupingCount uint + hasGroup bool + buf []byte +} + +func (p *parser) setError(err error) { + if p.err == nil { + p.err = err + } +} + +func (p *parser) updateGrouping() { + if p.hasGroup && + 0 < p.groupingCount && p.groupingCount < 255 { + p.GroupingSize[1] = p.GroupingSize[0] + p.GroupingSize[0] = uint8(p.groupingCount) + } + p.groupingCount = 0 + p.hasGroup = true +} + +var ( + // TODO: more sensible and localizeable error messages. + errMultiplePadSpecifiers = errors.New("format: pattern has multiple pad specifiers") + errInvalidPadSpecifier = errors.New("format: invalid pad specifier") + errInvalidQuote = errors.New("format: invalid quote") + errAffixTooLarge = errors.New("format: prefix or suffix exceeds maximum UTF-8 length of 256 bytes") + errDuplicatePercentSign = errors.New("format: duplicate percent sign") + errDuplicatePermilleSign = errors.New("format: duplicate permille sign") + errUnexpectedEnd = errors.New("format: unexpected end of pattern") +) + +// ParsePattern extracts formatting information from a CLDR number pattern. +// +// See https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns. +func ParsePattern(s string) (f *Pattern, err error) { + p := parser{Pattern: &Pattern{}} + + s = p.parseSubPattern(s) + + if s != "" { + // Parse negative sub pattern. + if s[0] != ';' { + p.setError(errors.New("format: error parsing first sub pattern")) + return nil, p.err + } + neg := parser{Pattern: &Pattern{}} // just for extracting the affixes. + s = neg.parseSubPattern(s[len(";"):]) + p.NegOffset = uint16(len(p.buf)) + p.buf = append(p.buf, neg.buf...) + } + if s != "" { + p.setError(errors.New("format: spurious characters at end of pattern")) + } + if p.err != nil { + return nil, p.err + } + if affix := string(p.buf); affix == "\x00\x00" || affix == "\x00\x00\x00\x00" { + // No prefix or suffixes. + p.NegOffset = 0 + } else { + p.Affix = affix + } + if p.Increment == 0 { + p.IncrementScale = 0 + } + return p.Pattern, nil +} + +func (p *parser) parseSubPattern(s string) string { + s = p.parsePad(s, PadBeforePrefix) + s = p.parseAffix(s) + s = p.parsePad(s, PadAfterPrefix) + + s = p.parse(p.number, s) + p.updateGrouping() + + s = p.parsePad(s, PadBeforeSuffix) + s = p.parseAffix(s) + s = p.parsePad(s, PadAfterSuffix) + return s +} + +func (p *parser) parsePad(s string, f PatternFlag) (tail string) { + if len(s) >= 2 && s[0] == '*' { + r, sz := utf8.DecodeRuneInString(s[1:]) + if p.PadRune != 0 { + p.err = errMultiplePadSpecifiers + } else { + p.Flags |= f + p.PadRune = r + } + return s[1+sz:] + } + return s +} + +func (p *parser) parseAffix(s string) string { + x := len(p.buf) + p.buf = append(p.buf, 0) // placeholder for affix length + + s = p.parse(p.affix, s) + + n := len(p.buf) - x - 1 + if n > 0xFF { + p.setError(errAffixTooLarge) + } + p.buf[x] = uint8(n) + return s +} + +// state implements a state transition. It returns the new state. A state +// function may set an error on the parser or may simply return on an incorrect +// token and let the next phase fail. +type state func(r rune) state + +// parse repeatedly applies a state function on the given string until a +// termination condition is reached. +func (p *parser) parse(fn state, s string) (tail string) { + for i, r := range s { + p.doNotTerminate = false + if fn = fn(r); fn == nil || p.err != nil { + return s[i:] + } + p.FormatWidth++ + } + if p.doNotTerminate { + p.setError(errUnexpectedEnd) + } + return "" +} + +func (p *parser) affix(r rune) state { + switch r { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '#', '@', '.', '*', ',', ';': + return nil + case '\'': + p.FormatWidth-- + return p.escapeFirst + case '%': + if p.DigitShift != 0 { + p.setError(errDuplicatePercentSign) + } + p.DigitShift = 2 + case '\u2030': // ‰ Per mille + if p.DigitShift != 0 { + p.setError(errDuplicatePermilleSign) + } + p.DigitShift = 3 + // TODO: handle currency somehow: ¤, ¤¤, ¤¤¤, ¤¤¤¤ + } + p.buf = append(p.buf, string(r)...) + return p.affix +} + +func (p *parser) escapeFirst(r rune) state { + switch r { + case '\'': + p.buf = append(p.buf, "\\'"...) + return p.affix + default: + p.buf = append(p.buf, '\'') + p.buf = append(p.buf, string(r)...) + } + return p.escape +} + +func (p *parser) escape(r rune) state { + switch r { + case '\'': + p.FormatWidth-- + p.buf = append(p.buf, '\'') + return p.affix + default: + p.buf = append(p.buf, string(r)...) + } + return p.escape +} + +// number parses a number. The BNF says the integer part should always have +// a '0', but that does not appear to be the case according to the rest of the +// documentation. We will allow having only '#' numbers. +func (p *parser) number(r rune) state { + switch r { + case '#': + p.groupingCount++ + p.leadingSharps++ + case '@': + p.groupingCount++ + p.leadingSharps = 0 + p.MaxFractionDigits = -1 + return p.sigDigits(r) + case ',': + if p.leadingSharps == 0 { // no leading commas + return nil + } + p.updateGrouping() + case 'E': + p.MaxIntegerDigits = uint8(p.leadingSharps) + return p.exponent + case '.': // allow ".##" etc. + p.updateGrouping() + return p.fraction + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return p.integer(r) + default: + return nil + } + return p.number +} + +func (p *parser) integer(r rune) state { + if !('0' <= r && r <= '9') { + var next state + switch r { + case 'E': + if p.leadingSharps > 0 { + p.MaxIntegerDigits = uint8(p.leadingSharps) + p.MinIntegerDigits + } + next = p.exponent + case '.': + next = p.fraction + case ',': + next = p.integer + } + p.updateGrouping() + return next + } + p.Increment = p.Increment*10 + uint32(r-'0') + p.groupingCount++ + p.MinIntegerDigits++ + return p.integer +} + +func (p *parser) sigDigits(r rune) state { + switch r { + case '@': + p.groupingCount++ + p.MaxSignificantDigits++ + p.MinSignificantDigits++ + case '#': + return p.sigDigitsFinal(r) + case 'E': + p.updateGrouping() + return p.normalizeSigDigitsWithExponent() + default: + p.updateGrouping() + return nil + } + return p.sigDigits +} + +func (p *parser) sigDigitsFinal(r rune) state { + switch r { + case '#': + p.groupingCount++ + p.MaxSignificantDigits++ + case 'E': + p.updateGrouping() + return p.normalizeSigDigitsWithExponent() + default: + p.updateGrouping() + return nil + } + return p.sigDigitsFinal +} + +func (p *parser) normalizeSigDigitsWithExponent() state { + p.MinIntegerDigits, p.MaxIntegerDigits = 1, 1 + p.MinFractionDigits = p.MinSignificantDigits - 1 + p.MaxFractionDigits = p.MaxSignificantDigits - 1 + p.MinSignificantDigits, p.MaxSignificantDigits = 0, 0 + return p.exponent +} + +func (p *parser) fraction(r rune) state { + switch r { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + p.Increment = p.Increment*10 + uint32(r-'0') + p.IncrementScale++ + p.MinFractionDigits++ + p.MaxFractionDigits++ + case '#': + p.MaxFractionDigits++ + case 'E': + if p.leadingSharps > 0 { + p.MaxIntegerDigits = uint8(p.leadingSharps) + p.MinIntegerDigits + } + return p.exponent + default: + return nil + } + return p.fraction +} + +func (p *parser) exponent(r rune) state { + switch r { + case '+': + // Set mode and check it wasn't already set. + if p.Flags&AlwaysExpSign != 0 || p.MinExponentDigits > 0 { + break + } + p.Flags |= AlwaysExpSign + p.doNotTerminate = true + return p.exponent + case '0': + p.MinExponentDigits++ + return p.exponent + } + // termination condition + if p.MinExponentDigits == 0 { + p.setError(errors.New("format: need at least one digit")) + } + return nil +} diff --git a/vendor/golang.org/x/text/internal/number/roundingmode_string.go b/vendor/golang.org/x/text/internal/number/roundingmode_string.go new file mode 100644 index 00000000000..bcc22471db8 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/roundingmode_string.go @@ -0,0 +1,30 @@ +// Code generated by "stringer -type RoundingMode"; DO NOT EDIT. + +package number + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ToNearestEven-0] + _ = x[ToNearestZero-1] + _ = x[ToNearestAway-2] + _ = x[ToPositiveInf-3] + _ = x[ToNegativeInf-4] + _ = x[ToZero-5] + _ = x[AwayFromZero-6] + _ = x[numModes-7] +} + +const _RoundingMode_name = "ToNearestEvenToNearestZeroToNearestAwayToPositiveInfToNegativeInfToZeroAwayFromZeronumModes" + +var _RoundingMode_index = [...]uint8{0, 13, 26, 39, 52, 65, 71, 83, 91} + +func (i RoundingMode) String() string { + if i >= RoundingMode(len(_RoundingMode_index)-1) { + return "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]] +} diff --git a/vendor/golang.org/x/text/internal/number/tables.go b/vendor/golang.org/x/text/internal/number/tables.go new file mode 100644 index 00000000000..8efce81b562 --- /dev/null +++ b/vendor/golang.org/x/text/internal/number/tables.go @@ -0,0 +1,1219 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package number + +import "golang.org/x/text/internal/stringset" + +// CLDRVersion is the CLDR version from which the tables in this package are derived. +const CLDRVersion = "32" + +var numSysData = []systemData{ // 59 elements + 0: {id: 0x0, digitSize: 0x1, zero: [4]uint8{0x30, 0x0, 0x0, 0x0}}, + 1: {id: 0x1, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9e, 0xa5, 0x90}}, + 2: {id: 0x2, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x9c, 0xb0}}, + 3: {id: 0x3, digitSize: 0x2, zero: [4]uint8{0xd9, 0xa0, 0x0, 0x0}}, + 4: {id: 0x4, digitSize: 0x2, zero: [4]uint8{0xdb, 0xb0, 0x0, 0x0}}, + 5: {id: 0x5, digitSize: 0x3, zero: [4]uint8{0xe1, 0xad, 0x90, 0x0}}, + 6: {id: 0x6, digitSize: 0x3, zero: [4]uint8{0xe0, 0xa7, 0xa6, 0x0}}, + 7: {id: 0x7, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0xb1, 0x90}}, + 8: {id: 0x8, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x81, 0xa6}}, + 9: {id: 0x9, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x84, 0xb6}}, + 10: {id: 0xa, digitSize: 0x3, zero: [4]uint8{0xea, 0xa9, 0x90, 0x0}}, + 11: {id: 0xb, digitSize: 0x3, zero: [4]uint8{0xe0, 0xa5, 0xa6, 0x0}}, + 12: {id: 0xc, digitSize: 0x3, zero: [4]uint8{0xef, 0xbc, 0x90, 0x0}}, + 13: {id: 0xd, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0xb5, 0x90}}, + 14: {id: 0xe, digitSize: 0x3, zero: [4]uint8{0xe0, 0xab, 0xa6, 0x0}}, + 15: {id: 0xf, digitSize: 0x3, zero: [4]uint8{0xe0, 0xa9, 0xa6, 0x0}}, + 16: {id: 0x10, digitSize: 0x4, zero: [4]uint8{0xf0, 0x96, 0xad, 0x90}}, + 17: {id: 0x11, digitSize: 0x3, zero: [4]uint8{0xea, 0xa7, 0x90, 0x0}}, + 18: {id: 0x12, digitSize: 0x3, zero: [4]uint8{0xea, 0xa4, 0x80, 0x0}}, + 19: {id: 0x13, digitSize: 0x3, zero: [4]uint8{0xe1, 0x9f, 0xa0, 0x0}}, + 20: {id: 0x14, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb3, 0xa6, 0x0}}, + 21: {id: 0x15, digitSize: 0x3, zero: [4]uint8{0xe1, 0xaa, 0x80, 0x0}}, + 22: {id: 0x16, digitSize: 0x3, zero: [4]uint8{0xe1, 0xaa, 0x90, 0x0}}, + 23: {id: 0x17, digitSize: 0x3, zero: [4]uint8{0xe0, 0xbb, 0x90, 0x0}}, + 24: {id: 0x18, digitSize: 0x3, zero: [4]uint8{0xe1, 0xb1, 0x80, 0x0}}, + 25: {id: 0x19, digitSize: 0x3, zero: [4]uint8{0xe1, 0xa5, 0x86, 0x0}}, + 26: {id: 0x1a, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0x8e}}, + 27: {id: 0x1b, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0x98}}, + 28: {id: 0x1c, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0xb6}}, + 29: {id: 0x1d, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0xac}}, + 30: {id: 0x1e, digitSize: 0x4, zero: [4]uint8{0xf0, 0x9d, 0x9f, 0xa2}}, + 31: {id: 0x1f, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb5, 0xa6, 0x0}}, + 32: {id: 0x20, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x99, 0x90}}, + 33: {id: 0x21, digitSize: 0x3, zero: [4]uint8{0xe1, 0xa0, 0x90, 0x0}}, + 34: {id: 0x22, digitSize: 0x4, zero: [4]uint8{0xf0, 0x96, 0xa9, 0xa0}}, + 35: {id: 0x23, digitSize: 0x3, zero: [4]uint8{0xea, 0xaf, 0xb0, 0x0}}, + 36: {id: 0x24, digitSize: 0x3, zero: [4]uint8{0xe1, 0x81, 0x80, 0x0}}, + 37: {id: 0x25, digitSize: 0x3, zero: [4]uint8{0xe1, 0x82, 0x90, 0x0}}, + 38: {id: 0x26, digitSize: 0x3, zero: [4]uint8{0xea, 0xa7, 0xb0, 0x0}}, + 39: {id: 0x27, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x91, 0x90}}, + 40: {id: 0x28, digitSize: 0x2, zero: [4]uint8{0xdf, 0x80, 0x0, 0x0}}, + 41: {id: 0x29, digitSize: 0x3, zero: [4]uint8{0xe1, 0xb1, 0x90, 0x0}}, + 42: {id: 0x2a, digitSize: 0x3, zero: [4]uint8{0xe0, 0xad, 0xa6, 0x0}}, + 43: {id: 0x2b, digitSize: 0x4, zero: [4]uint8{0xf0, 0x90, 0x92, 0xa0}}, + 44: {id: 0x2c, digitSize: 0x3, zero: [4]uint8{0xea, 0xa3, 0x90, 0x0}}, + 45: {id: 0x2d, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x87, 0x90}}, + 46: {id: 0x2e, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x8b, 0xb0}}, + 47: {id: 0x2f, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb7, 0xa6, 0x0}}, + 48: {id: 0x30, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x83, 0xb0}}, + 49: {id: 0x31, digitSize: 0x3, zero: [4]uint8{0xe1, 0xae, 0xb0, 0x0}}, + 50: {id: 0x32, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x9b, 0x80}}, + 51: {id: 0x33, digitSize: 0x3, zero: [4]uint8{0xe1, 0xa7, 0x90, 0x0}}, + 52: {id: 0x34, digitSize: 0x3, zero: [4]uint8{0xe0, 0xaf, 0xa6, 0x0}}, + 53: {id: 0x35, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb1, 0xa6, 0x0}}, + 54: {id: 0x36, digitSize: 0x3, zero: [4]uint8{0xe0, 0xb9, 0x90, 0x0}}, + 55: {id: 0x37, digitSize: 0x3, zero: [4]uint8{0xe0, 0xbc, 0xa0, 0x0}}, + 56: {id: 0x38, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0x93, 0x90}}, + 57: {id: 0x39, digitSize: 0x3, zero: [4]uint8{0xea, 0x98, 0xa0, 0x0}}, + 58: {id: 0x3a, digitSize: 0x4, zero: [4]uint8{0xf0, 0x91, 0xa3, 0xa0}}, +} // Size: 378 bytes + +const ( + numAdlm = 0x1 + numAhom = 0x2 + numArab = 0x3 + numArabext = 0x4 + numArmn = 0x3b + numArmnlow = 0x3c + numBali = 0x5 + numBeng = 0x6 + numBhks = 0x7 + numBrah = 0x8 + numCakm = 0x9 + numCham = 0xa + numCyrl = 0x3d + numDeva = 0xb + numEthi = 0x3e + numFullwide = 0xc + numGeor = 0x3f + numGonm = 0xd + numGrek = 0x40 + numGreklow = 0x41 + numGujr = 0xe + numGuru = 0xf + numHanidays = 0x42 + numHanidec = 0x43 + numHans = 0x44 + numHansfin = 0x45 + numHant = 0x46 + numHantfin = 0x47 + numHebr = 0x48 + numHmng = 0x10 + numJava = 0x11 + numJpan = 0x49 + numJpanfin = 0x4a + numKali = 0x12 + numKhmr = 0x13 + numKnda = 0x14 + numLana = 0x15 + numLanatham = 0x16 + numLaoo = 0x17 + numLatn = 0x0 + numLepc = 0x18 + numLimb = 0x19 + numMathbold = 0x1a + numMathdbl = 0x1b + numMathmono = 0x1c + numMathsanb = 0x1d + numMathsans = 0x1e + numMlym = 0x1f + numModi = 0x20 + numMong = 0x21 + numMroo = 0x22 + numMtei = 0x23 + numMymr = 0x24 + numMymrshan = 0x25 + numMymrtlng = 0x26 + numNewa = 0x27 + numNkoo = 0x28 + numOlck = 0x29 + numOrya = 0x2a + numOsma = 0x2b + numRoman = 0x4b + numRomanlow = 0x4c + numSaur = 0x2c + numShrd = 0x2d + numSind = 0x2e + numSinh = 0x2f + numSora = 0x30 + numSund = 0x31 + numTakr = 0x32 + numTalu = 0x33 + numTaml = 0x4d + numTamldec = 0x34 + numTelu = 0x35 + numThai = 0x36 + numTibt = 0x37 + numTirh = 0x38 + numVaii = 0x39 + numWara = 0x3a + numNumberSystems +) + +var systemMap = map[string]system{ + "adlm": numAdlm, + "ahom": numAhom, + "arab": numArab, + "arabext": numArabext, + "armn": numArmn, + "armnlow": numArmnlow, + "bali": numBali, + "beng": numBeng, + "bhks": numBhks, + "brah": numBrah, + "cakm": numCakm, + "cham": numCham, + "cyrl": numCyrl, + "deva": numDeva, + "ethi": numEthi, + "fullwide": numFullwide, + "geor": numGeor, + "gonm": numGonm, + "grek": numGrek, + "greklow": numGreklow, + "gujr": numGujr, + "guru": numGuru, + "hanidays": numHanidays, + "hanidec": numHanidec, + "hans": numHans, + "hansfin": numHansfin, + "hant": numHant, + "hantfin": numHantfin, + "hebr": numHebr, + "hmng": numHmng, + "java": numJava, + "jpan": numJpan, + "jpanfin": numJpanfin, + "kali": numKali, + "khmr": numKhmr, + "knda": numKnda, + "lana": numLana, + "lanatham": numLanatham, + "laoo": numLaoo, + "latn": numLatn, + "lepc": numLepc, + "limb": numLimb, + "mathbold": numMathbold, + "mathdbl": numMathdbl, + "mathmono": numMathmono, + "mathsanb": numMathsanb, + "mathsans": numMathsans, + "mlym": numMlym, + "modi": numModi, + "mong": numMong, + "mroo": numMroo, + "mtei": numMtei, + "mymr": numMymr, + "mymrshan": numMymrshan, + "mymrtlng": numMymrtlng, + "newa": numNewa, + "nkoo": numNkoo, + "olck": numOlck, + "orya": numOrya, + "osma": numOsma, + "roman": numRoman, + "romanlow": numRomanlow, + "saur": numSaur, + "shrd": numShrd, + "sind": numSind, + "sinh": numSinh, + "sora": numSora, + "sund": numSund, + "takr": numTakr, + "talu": numTalu, + "taml": numTaml, + "tamldec": numTamldec, + "telu": numTelu, + "thai": numThai, + "tibt": numTibt, + "tirh": numTirh, + "vaii": numVaii, + "wara": numWara, +} + +var symIndex = [][12]uint8{ // 81 elements + 0: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 1: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 2: [12]uint8{0x0, 0x1, 0x2, 0xd, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0x10, 0xb}, + 3: [12]uint8{0x1, 0x0, 0x2, 0xd, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0x10, 0xb}, + 4: [12]uint8{0x0, 0x1, 0x2, 0x11, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0x10, 0xb}, + 5: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x12, 0xb}, + 6: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 7: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x13, 0xb}, + 8: [12]uint8{0x0, 0x1, 0x2, 0x3, 0xe, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 9: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x0}, + 10: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x14, 0x8, 0x9, 0xa, 0xb}, + 11: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x14, 0x8, 0x9, 0xa, 0xb}, + 12: [12]uint8{0x0, 0x15, 0x2, 0x3, 0x4, 0x5, 0x6, 0x14, 0x8, 0x9, 0xa, 0xb}, + 13: [12]uint8{0x0, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 14: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x16, 0xb}, + 15: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 16: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0x0}, + 17: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 18: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x0}, + 19: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x18, 0x7, 0x8, 0x9, 0xa, 0xb}, + 20: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x19, 0x1a, 0xa, 0xb}, + 21: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 22: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x18, 0x7, 0x8, 0x9, 0xa, 0xb}, + 23: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 24: [12]uint8{0x0, 0x1, 0x2, 0x3, 0xe, 0x1c, 0x6, 0x7, 0x8, 0x9, 0x1d, 0xb}, + 25: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0x1e, 0x0}, + 26: [12]uint8{0x0, 0x15, 0x2, 0x3, 0x4, 0x1b, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 27: [12]uint8{0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 28: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x1f, 0xb}, + 29: [12]uint8{0x0, 0x15, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 30: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x20, 0xb}, + 31: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x21, 0x7, 0x8, 0x9, 0x22, 0xb}, + 32: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x23, 0xb}, + 33: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x1b, 0x18, 0x14, 0x8, 0x9, 0x24, 0xb}, + 34: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x18, 0x7, 0x8, 0x9, 0x24, 0xb}, + 35: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x25, 0xb}, + 36: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x26, 0xb}, + 37: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x27, 0xb}, + 38: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x28, 0xb}, + 39: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x29, 0xb}, + 40: [12]uint8{0x1, 0x0, 0x2, 0x3, 0xe, 0x1c, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 41: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2a, 0xb}, + 42: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2b, 0xb}, + 43: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x1b, 0x2c, 0x14, 0x8, 0x9, 0x24, 0xb}, + 44: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x0}, + 45: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 46: [12]uint8{0x1, 0x0, 0x2, 0x3, 0x4, 0x1b, 0x17, 0x7, 0x8, 0x9, 0xa, 0xb}, + 47: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2d, 0x0}, + 48: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2e, 0xb}, + 49: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x2f, 0xb}, + 50: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x30, 0x7, 0x8, 0x9, 0xa, 0xb}, + 51: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x31, 0xb}, + 52: [12]uint8{0x1, 0xc, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x32, 0xb}, + 53: [12]uint8{0x1, 0x15, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}, + 54: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x33, 0xb}, + 55: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x34, 0xb}, + 56: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 57: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x7, 0x3c, 0x9, 0x3d, 0xb}, + 58: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x3e, 0x3f, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 59: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x39, 0x3a, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 60: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x39, 0x40, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 61: [12]uint8{0x35, 0x36, 0x37, 0x41, 0x3e, 0x3f, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 62: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x3e, 0x3f, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0xb}, + 63: [12]uint8{0x35, 0xc, 0x37, 0x38, 0x39, 0x42, 0x3b, 0x7, 0x3c, 0x9, 0xa, 0x0}, + 64: [12]uint8{0x35, 0xc, 0x37, 0x38, 0x39, 0x42, 0x43, 0x7, 0x44, 0x9, 0x24, 0xb}, + 65: [12]uint8{0x35, 0x36, 0x37, 0x38, 0x39, 0x5, 0x3b, 0x7, 0x3c, 0x9, 0x33, 0xb}, + 66: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x45, 0x46, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 67: [12]uint8{0x35, 0x36, 0x37, 0x11, 0xe, 0x1c, 0x43, 0x7, 0x3c, 0x9, 0x1d, 0xb}, + 68: [12]uint8{0x35, 0x36, 0x37, 0x11, 0xe, 0x1c, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 69: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x45, 0x5, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 70: [12]uint8{0x1, 0xc, 0x37, 0x11, 0x45, 0x47, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x0}, + 71: [12]uint8{0x35, 0x1, 0x37, 0x11, 0x4, 0x5, 0x43, 0x7, 0x3c, 0x9, 0xa, 0x35}, + 72: [12]uint8{0x1, 0xc, 0x37, 0x11, 0x45, 0x47, 0x43, 0x7, 0x3c, 0x9, 0x24, 0xb}, + 73: [12]uint8{0x35, 0x36, 0x2, 0x3, 0x45, 0x46, 0x43, 0x7, 0x8, 0x9, 0xa, 0x35}, + 74: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x4, 0x5, 0x43, 0x7, 0x3c, 0x9, 0x31, 0x35}, + 75: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x4, 0x5, 0x43, 0x7, 0x3c, 0x9, 0x32, 0x35}, + 76: [12]uint8{0x35, 0x36, 0x37, 0x11, 0x48, 0x46, 0x43, 0x7, 0x3c, 0x9, 0x33, 0x35}, + 77: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x49}, + 78: [12]uint8{0x0, 0x1, 0x4a, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x28, 0xb}, + 79: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x4b, 0xb}, + 80: [12]uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x4c, 0x4d, 0xb}, +} // Size: 996 bytes + +var symData = stringset.Set{ + Data: "" + // Size: 599 bytes + ".,;%+-E׉∞NaN:\u00a0\u200e%\u200e\u200e+\u200e-ليس\u00a0رقمًا٪NDТерхьаш" + + "\u00a0дац·’mnne×10^0/00INF−\u200e−ناعددepälukuՈչԹარ\u00a0არის\u00a0რიცხვ" + + "იZMdMсан\u00a0емес¤¤¤сан\u00a0эмесບໍ່\u200bແມ່ນ\u200bໂຕ\u200bເລກNSဂဏန်" + + "းမဟုတ်သောННне\u00a0числочыыһыла\u00a0буотах·10^epilohosan\u00a0dälTFЕs" + + "on\u00a0emasҳақиқий\u00a0сон\u00a0эмас非數值非数值٫٬؛٪\u061c\u061c+\u061c-اس؉ل" + + "يس\u00a0رقم\u200f+\u200f-\u200f−٪\u200f\u061c−×۱۰^؉\u200f\u200e+\u200e" + + "\u200e-\u200e\u200e−\u200e+\u200e:၊ཨང་མེན་གྲངས་མེདཨང་མད", + Index: []uint16{ // 79 elements + // Entry 0 - 3F + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0009, 0x000c, 0x000f, 0x0012, 0x0013, 0x0015, 0x001c, 0x0020, + 0x0024, 0x0036, 0x0038, 0x003a, 0x0050, 0x0052, 0x0055, 0x0058, + 0x0059, 0x005e, 0x0062, 0x0065, 0x0068, 0x006e, 0x0078, 0x0080, + 0x0086, 0x00ae, 0x00af, 0x00b2, 0x00c2, 0x00c8, 0x00d8, 0x0105, + 0x0107, 0x012e, 0x0132, 0x0142, 0x015e, 0x0163, 0x016a, 0x0173, + 0x0175, 0x0177, 0x0180, 0x01a0, 0x01a9, 0x01b2, 0x01b4, 0x01b6, + 0x01b8, 0x01bc, 0x01bf, 0x01c2, 0x01c6, 0x01c8, 0x01d6, 0x01da, + // Entry 40 - 7F + 0x01de, 0x01e4, 0x01e9, 0x01ee, 0x01f5, 0x01fa, 0x0201, 0x0208, + 0x0211, 0x0215, 0x0218, 0x021b, 0x0230, 0x0248, 0x0257, + }, +} // Size: 797 bytes + +// langToDefaults maps a compact language index to the default numbering system +// and default symbol set +var langToDefaults = [775]symOffset{ + // Entry 0 - 3F + 0x8000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8003, 0x0002, 0x0002, 0x0002, 0x0002, 0x0003, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0003, 0x0003, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, 0x0004, + 0x0002, 0x0004, 0x0002, 0x0002, 0x0002, 0x0003, 0x0002, 0x0000, + 0x8005, 0x0000, 0x0000, 0x0000, 0x8006, 0x0005, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + // Entry 40 - 7F + 0x8009, 0x0000, 0x0000, 0x800a, 0x0000, 0x0000, 0x800c, 0x0001, + 0x0000, 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x800e, 0x0000, 0x0000, 0x0007, + 0x0007, 0x0000, 0x0000, 0x0000, 0x0000, 0x800f, 0x0008, 0x0008, + 0x8011, 0x0001, 0x0001, 0x0001, 0x803c, 0x0000, 0x0009, 0x0009, + 0x0009, 0x0000, 0x0000, 0x000a, 0x000b, 0x000a, 0x000c, 0x000a, + 0x000a, 0x000c, 0x000a, 0x000d, 0x000d, 0x000a, 0x000a, 0x0001, + 0x0001, 0x0000, 0x0001, 0x0001, 0x803f, 0x0000, 0x0000, 0x0000, + // Entry 80 - BF + 0x000e, 0x000e, 0x000e, 0x000f, 0x000f, 0x000f, 0x0000, 0x0000, + 0x0006, 0x0000, 0x0000, 0x0000, 0x000a, 0x0010, 0x0000, 0x0006, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0011, 0x0000, 0x000a, + 0x0000, 0x0000, 0x0000, 0x0000, 0x000a, 0x0000, 0x0009, 0x0000, + 0x0000, 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + // Entry C0 - FF + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0013, 0x0000, + 0x0000, 0x000f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0015, + 0x0015, 0x0006, 0x0000, 0x0006, 0x0006, 0x0000, 0x0000, 0x0006, + 0x0006, 0x0001, 0x0000, 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, + // Entry 100 - 13F + 0x0000, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, + 0x0000, 0x0006, 0x0000, 0x0000, 0x0006, 0x0006, 0x0016, 0x0016, + 0x0017, 0x0017, 0x0001, 0x0001, 0x8041, 0x0018, 0x0018, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0019, 0x0019, 0x0000, 0x0000, + 0x0017, 0x0017, 0x0017, 0x8044, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, + // Entry 140 - 17F + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0006, 0x0006, 0x0006, 0x0006, 0x0000, 0x0000, + 0x8047, 0x0000, 0x0006, 0x0006, 0x001a, 0x001a, 0x001a, 0x001a, + 0x804a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x804c, 0x001b, 0x0000, + 0x0000, 0x0006, 0x0006, 0x0006, 0x000a, 0x000a, 0x0001, 0x0001, + 0x001c, 0x001c, 0x0009, 0x0009, 0x804f, 0x0000, 0x0000, 0x0000, + // Entry 180 - 1BF + 0x0000, 0x0000, 0x8052, 0x0006, 0x0006, 0x001d, 0x0006, 0x0006, + 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x001e, 0x001e, 0x001f, + 0x001f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0001, 0x000d, 0x000d, 0x0000, 0x0000, 0x0020, 0x0020, 0x0006, + 0x0006, 0x0021, 0x0021, 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, + 0x0000, 0x8054, 0x0000, 0x0000, 0x0000, 0x0000, 0x8056, 0x001b, + 0x0000, 0x0000, 0x0001, 0x0001, 0x0022, 0x0022, 0x0000, 0x0000, + // Entry 1C0 - 1FF + 0x0000, 0x0023, 0x0023, 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0024, 0x0024, 0x8058, 0x0000, 0x0000, 0x0016, 0x0016, 0x0006, + 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0025, 0x0025, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x000d, 0x000d, 0x0000, 0x0000, + 0x0006, 0x0006, 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x805a, 0x0000, 0x0000, 0x0006, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x805b, 0x0026, 0x805d, + // Entry 200 - 23F + 0x0000, 0x0000, 0x0000, 0x0000, 0x805e, 0x0015, 0x0015, 0x0000, + 0x0000, 0x0006, 0x0006, 0x0006, 0x8061, 0x0000, 0x0000, 0x8062, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0001, + 0x0001, 0x0015, 0x0015, 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0027, 0x0027, 0x0027, 0x8065, 0x8067, + 0x001b, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, + 0x8069, 0x0028, 0x0006, 0x0001, 0x0006, 0x0001, 0x0001, 0x0001, + // Entry 240 - 27F + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, + 0x0006, 0x0000, 0x0000, 0x001a, 0x001a, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0000, 0x0000, 0x0029, 0x0029, 0x0029, 0x0029, + 0x0029, 0x0029, 0x0029, 0x0006, 0x0006, 0x0000, 0x0000, 0x002a, + 0x002a, 0x0000, 0x0000, 0x0000, 0x0000, 0x806b, 0x0000, 0x0000, + 0x002b, 0x002b, 0x002b, 0x002b, 0x0006, 0x0006, 0x000d, 0x000d, + 0x0006, 0x0006, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x002c, 0x002c, 0x002d, 0x002d, 0x002e, 0x002e, 0x0000, 0x0000, + // Entry 280 - 2BF + 0x0000, 0x002f, 0x002f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0006, + 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, + 0x0006, 0x0006, 0x0000, 0x0000, 0x0000, 0x806d, 0x0022, 0x0022, + 0x0022, 0x0000, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0030, 0x0030, 0x0000, 0x0000, 0x8071, 0x0031, 0x0006, + // Entry 2C0 - 2FF + 0x0006, 0x0006, 0x0000, 0x0001, 0x0001, 0x000d, 0x000d, 0x0001, + 0x0001, 0x0000, 0x0000, 0x0032, 0x0032, 0x8074, 0x8076, 0x001b, + 0x8077, 0x8079, 0x0028, 0x807b, 0x0034, 0x0033, 0x0033, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0006, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0035, 0x0035, 0x0006, 0x0006, + 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0036, 0x0037, 0x0037, 0x0036, 0x0036, 0x0001, + 0x0001, 0x807d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, + // Entry 300 - 33F + 0x0036, 0x0036, 0x0036, 0x0000, 0x0000, 0x0006, 0x0014, +} // Size: 1550 bytes + +// langToAlt is a list of numbering system and symbol set pairs, sorted and +// marked by compact language index. +var langToAlt = []altSymData{ // 131 elements + 1: {compactTag: 0x0, symIndex: 0x38, system: 0x3}, + 2: {compactTag: 0x0, symIndex: 0x42, system: 0x4}, + 3: {compactTag: 0xa, symIndex: 0x39, system: 0x3}, + 4: {compactTag: 0xa, symIndex: 0x2, system: 0x0}, + 5: {compactTag: 0x28, symIndex: 0x0, system: 0x6}, + 6: {compactTag: 0x2c, symIndex: 0x5, system: 0x0}, + 7: {compactTag: 0x2c, symIndex: 0x3a, system: 0x3}, + 8: {compactTag: 0x2c, symIndex: 0x42, system: 0x4}, + 9: {compactTag: 0x40, symIndex: 0x0, system: 0x6}, + 10: {compactTag: 0x43, symIndex: 0x0, system: 0x0}, + 11: {compactTag: 0x43, symIndex: 0x4f, system: 0x37}, + 12: {compactTag: 0x46, symIndex: 0x1, system: 0x0}, + 13: {compactTag: 0x46, symIndex: 0x38, system: 0x3}, + 14: {compactTag: 0x54, symIndex: 0x0, system: 0x9}, + 15: {compactTag: 0x5d, symIndex: 0x3a, system: 0x3}, + 16: {compactTag: 0x5d, symIndex: 0x8, system: 0x0}, + 17: {compactTag: 0x60, symIndex: 0x1, system: 0x0}, + 18: {compactTag: 0x60, symIndex: 0x38, system: 0x3}, + 19: {compactTag: 0x60, symIndex: 0x42, system: 0x4}, + 20: {compactTag: 0x60, symIndex: 0x0, system: 0x5}, + 21: {compactTag: 0x60, symIndex: 0x0, system: 0x6}, + 22: {compactTag: 0x60, symIndex: 0x0, system: 0x8}, + 23: {compactTag: 0x60, symIndex: 0x0, system: 0x9}, + 24: {compactTag: 0x60, symIndex: 0x0, system: 0xa}, + 25: {compactTag: 0x60, symIndex: 0x0, system: 0xb}, + 26: {compactTag: 0x60, symIndex: 0x0, system: 0xc}, + 27: {compactTag: 0x60, symIndex: 0x0, system: 0xd}, + 28: {compactTag: 0x60, symIndex: 0x0, system: 0xe}, + 29: {compactTag: 0x60, symIndex: 0x0, system: 0xf}, + 30: {compactTag: 0x60, symIndex: 0x0, system: 0x11}, + 31: {compactTag: 0x60, symIndex: 0x0, system: 0x12}, + 32: {compactTag: 0x60, symIndex: 0x0, system: 0x13}, + 33: {compactTag: 0x60, symIndex: 0x0, system: 0x14}, + 34: {compactTag: 0x60, symIndex: 0x0, system: 0x15}, + 35: {compactTag: 0x60, symIndex: 0x0, system: 0x16}, + 36: {compactTag: 0x60, symIndex: 0x0, system: 0x17}, + 37: {compactTag: 0x60, symIndex: 0x0, system: 0x18}, + 38: {compactTag: 0x60, symIndex: 0x0, system: 0x19}, + 39: {compactTag: 0x60, symIndex: 0x0, system: 0x1f}, + 40: {compactTag: 0x60, symIndex: 0x0, system: 0x21}, + 41: {compactTag: 0x60, symIndex: 0x0, system: 0x23}, + 42: {compactTag: 0x60, symIndex: 0x0, system: 0x24}, + 43: {compactTag: 0x60, symIndex: 0x0, system: 0x25}, + 44: {compactTag: 0x60, symIndex: 0x0, system: 0x28}, + 45: {compactTag: 0x60, symIndex: 0x0, system: 0x29}, + 46: {compactTag: 0x60, symIndex: 0x0, system: 0x2a}, + 47: {compactTag: 0x60, symIndex: 0x0, system: 0x2b}, + 48: {compactTag: 0x60, symIndex: 0x0, system: 0x2c}, + 49: {compactTag: 0x60, symIndex: 0x0, system: 0x2d}, + 50: {compactTag: 0x60, symIndex: 0x0, system: 0x30}, + 51: {compactTag: 0x60, symIndex: 0x0, system: 0x31}, + 52: {compactTag: 0x60, symIndex: 0x0, system: 0x32}, + 53: {compactTag: 0x60, symIndex: 0x0, system: 0x33}, + 54: {compactTag: 0x60, symIndex: 0x0, system: 0x34}, + 55: {compactTag: 0x60, symIndex: 0x0, system: 0x35}, + 56: {compactTag: 0x60, symIndex: 0x0, system: 0x36}, + 57: {compactTag: 0x60, symIndex: 0x0, system: 0x37}, + 58: {compactTag: 0x60, symIndex: 0x0, system: 0x39}, + 59: {compactTag: 0x60, symIndex: 0x0, system: 0x43}, + 60: {compactTag: 0x64, symIndex: 0x0, system: 0x0}, + 61: {compactTag: 0x64, symIndex: 0x38, system: 0x3}, + 62: {compactTag: 0x64, symIndex: 0x42, system: 0x4}, + 63: {compactTag: 0x7c, symIndex: 0x50, system: 0x37}, + 64: {compactTag: 0x7c, symIndex: 0x0, system: 0x0}, + 65: {compactTag: 0x114, symIndex: 0x43, system: 0x4}, + 66: {compactTag: 0x114, symIndex: 0x18, system: 0x0}, + 67: {compactTag: 0x114, symIndex: 0x3b, system: 0x3}, + 68: {compactTag: 0x123, symIndex: 0x1, system: 0x0}, + 69: {compactTag: 0x123, symIndex: 0x3c, system: 0x3}, + 70: {compactTag: 0x123, symIndex: 0x44, system: 0x4}, + 71: {compactTag: 0x158, symIndex: 0x0, system: 0x0}, + 72: {compactTag: 0x158, symIndex: 0x3b, system: 0x3}, + 73: {compactTag: 0x158, symIndex: 0x45, system: 0x4}, + 74: {compactTag: 0x160, symIndex: 0x0, system: 0x0}, + 75: {compactTag: 0x160, symIndex: 0x38, system: 0x3}, + 76: {compactTag: 0x16d, symIndex: 0x1b, system: 0x0}, + 77: {compactTag: 0x16d, symIndex: 0x0, system: 0x9}, + 78: {compactTag: 0x16d, symIndex: 0x0, system: 0xa}, + 79: {compactTag: 0x17c, symIndex: 0x0, system: 0x0}, + 80: {compactTag: 0x17c, symIndex: 0x3d, system: 0x3}, + 81: {compactTag: 0x17c, symIndex: 0x42, system: 0x4}, + 82: {compactTag: 0x182, symIndex: 0x6, system: 0x0}, + 83: {compactTag: 0x182, symIndex: 0x38, system: 0x3}, + 84: {compactTag: 0x1b1, symIndex: 0x0, system: 0x0}, + 85: {compactTag: 0x1b1, symIndex: 0x3e, system: 0x3}, + 86: {compactTag: 0x1b6, symIndex: 0x42, system: 0x4}, + 87: {compactTag: 0x1b6, symIndex: 0x1b, system: 0x0}, + 88: {compactTag: 0x1d2, symIndex: 0x42, system: 0x4}, + 89: {compactTag: 0x1d2, symIndex: 0x0, system: 0x0}, + 90: {compactTag: 0x1f3, symIndex: 0x0, system: 0xb}, + 91: {compactTag: 0x1fd, symIndex: 0x4e, system: 0x24}, + 92: {compactTag: 0x1fd, symIndex: 0x26, system: 0x0}, + 93: {compactTag: 0x1ff, symIndex: 0x42, system: 0x4}, + 94: {compactTag: 0x204, symIndex: 0x15, system: 0x0}, + 95: {compactTag: 0x204, symIndex: 0x3f, system: 0x3}, + 96: {compactTag: 0x204, symIndex: 0x46, system: 0x4}, + 97: {compactTag: 0x20c, symIndex: 0x0, system: 0xb}, + 98: {compactTag: 0x20f, symIndex: 0x6, system: 0x0}, + 99: {compactTag: 0x20f, symIndex: 0x38, system: 0x3}, + 100: {compactTag: 0x20f, symIndex: 0x42, system: 0x4}, + 101: {compactTag: 0x22e, symIndex: 0x0, system: 0x0}, + 102: {compactTag: 0x22e, symIndex: 0x47, system: 0x4}, + 103: {compactTag: 0x22f, symIndex: 0x42, system: 0x4}, + 104: {compactTag: 0x22f, symIndex: 0x1b, system: 0x0}, + 105: {compactTag: 0x238, symIndex: 0x42, system: 0x4}, + 106: {compactTag: 0x238, symIndex: 0x28, system: 0x0}, + 107: {compactTag: 0x265, symIndex: 0x38, system: 0x3}, + 108: {compactTag: 0x265, symIndex: 0x0, system: 0x0}, + 109: {compactTag: 0x29d, symIndex: 0x22, system: 0x0}, + 110: {compactTag: 0x29d, symIndex: 0x40, system: 0x3}, + 111: {compactTag: 0x29d, symIndex: 0x48, system: 0x4}, + 112: {compactTag: 0x29d, symIndex: 0x4d, system: 0xc}, + 113: {compactTag: 0x2bd, symIndex: 0x31, system: 0x0}, + 114: {compactTag: 0x2bd, symIndex: 0x3e, system: 0x3}, + 115: {compactTag: 0x2bd, symIndex: 0x42, system: 0x4}, + 116: {compactTag: 0x2cd, symIndex: 0x1b, system: 0x0}, + 117: {compactTag: 0x2cd, symIndex: 0x49, system: 0x4}, + 118: {compactTag: 0x2ce, symIndex: 0x49, system: 0x4}, + 119: {compactTag: 0x2d0, symIndex: 0x33, system: 0x0}, + 120: {compactTag: 0x2d0, symIndex: 0x4a, system: 0x4}, + 121: {compactTag: 0x2d1, symIndex: 0x42, system: 0x4}, + 122: {compactTag: 0x2d1, symIndex: 0x28, system: 0x0}, + 123: {compactTag: 0x2d3, symIndex: 0x34, system: 0x0}, + 124: {compactTag: 0x2d3, symIndex: 0x4b, system: 0x4}, + 125: {compactTag: 0x2f9, symIndex: 0x0, system: 0x0}, + 126: {compactTag: 0x2f9, symIndex: 0x38, system: 0x3}, + 127: {compactTag: 0x2f9, symIndex: 0x42, system: 0x4}, + 128: {compactTag: 0x2ff, symIndex: 0x36, system: 0x0}, + 129: {compactTag: 0x2ff, symIndex: 0x41, system: 0x3}, + 130: {compactTag: 0x2ff, symIndex: 0x4c, system: 0x4}, +} // Size: 810 bytes + +var tagToDecimal = []uint8{ // 775 elements + // Entry 0 - 3F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 40 - 7F + 0x05, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, 0x05, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, 0x01, 0x01, + // Entry 80 - BF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry C0 - FF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 100 - 13F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 140 - 17F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 180 - 1BF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, 0x05, 0x05, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 1C0 - 1FF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x05, + 0x01, 0x01, 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 200 - 23F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 240 - 27F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 280 - 2BF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, + 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 2C0 - 2FF + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + // Entry 300 - 33F + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, +} // Size: 799 bytes + +var tagToScientific = []uint8{ // 775 elements + // Entry 0 - 3F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 40 - 7F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 80 - BF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry C0 - FF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 100 - 13F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 140 - 17F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0c, + 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 180 - 1BF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 1C0 - 1FF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0d, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 200 - 23F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0c, 0x02, + 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 240 - 27F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0d, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 280 - 2BF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 2C0 - 2FF + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + // Entry 300 - 33F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x09, +} // Size: 799 bytes + +var tagToPercent = []uint8{ // 775 elements + // Entry 0 - 3F + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 40 - 7F + 0x06, 0x06, 0x06, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x06, 0x06, 0x03, 0x04, 0x04, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x03, + 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x07, 0x07, 0x04, 0x04, + // Entry 80 - BF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, 0x03, 0x04, + 0x04, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry C0 - FF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + // Entry 100 - 13F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x0b, 0x0b, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + // Entry 140 - 17F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, + 0x06, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 180 - 1BF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, + 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, 0x04, + // Entry 1C0 - 1FF + 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 200 - 23F + 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x06, 0x06, 0x04, 0x04, 0x04, 0x06, 0x04, + 0x04, 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 240 - 27F + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, + // Entry 280 - 2BF + 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, + 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x0e, + // Entry 2C0 - 2FF + 0x0e, 0x0e, 0x04, 0x03, 0x03, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + // Entry 300 - 33F + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0a, +} // Size: 799 bytes + +var formats = []Pattern{Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x0, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 3, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x9, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x1, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x1}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x3, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x03\u00a0%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x7, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x01%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x6, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 3, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0xc, + GroupingSize: [2]uint8{0x3, + 0x2}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x01%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x9, + GroupingSize: [2]uint8{0x3, + 0x2}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x03\u00a0%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0xa, + GroupingSize: [2]uint8{0x3, + 0x2}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 6, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x8, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 6, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x6, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x3}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0xd, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x4}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x00\x01%", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x2, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x03%\u00a0\x00", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x7, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x1, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x1}, + Affix: "\x01[\x01]", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x5, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x0, + MinIntegerDigits: 0x0, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x1, + GroupingSize: [2]uint8{0x0, + 0x0}, + Flags: 0x0}, + Pattern{RoundingContext: RoundingContext{MaxSignificantDigits: 0, + MaxFractionDigits: 0, + Increment: 0x0, + IncrementScale: 0x0, + Mode: 0x0, + DigitShift: 0x2, + MinIntegerDigits: 0x1, + MaxIntegerDigits: 0x0, + MinFractionDigits: 0x0, + MinSignificantDigits: 0x0, + MinExponentDigits: 0x0}, + Affix: "\x01%\x00", + Offset: 0x0, + NegOffset: 0x0, + PadRune: 0, + FormatWidth: 0x6, + GroupingSize: [2]uint8{0x3, + 0x0}, + Flags: 0x0}} + +// Total table size 8634 bytes (8KiB); checksum: 8F23386D diff --git a/vendor/golang.org/x/text/internal/stringset/set.go b/vendor/golang.org/x/text/internal/stringset/set.go new file mode 100644 index 00000000000..bb2fffbc75b --- /dev/null +++ b/vendor/golang.org/x/text/internal/stringset/set.go @@ -0,0 +1,86 @@ +// Copyright 2016 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 stringset provides a way to represent a collection of strings +// compactly. +package stringset + +import "sort" + +// A Set holds a collection of strings that can be looked up by an index number. +type Set struct { + // These fields are exported to allow for code generation. + + Data string + Index []uint16 +} + +// Elem returns the string with index i. It panics if i is out of range. +func (s *Set) Elem(i int) string { + return s.Data[s.Index[i]:s.Index[i+1]] +} + +// Len returns the number of strings in the set. +func (s *Set) Len() int { + return len(s.Index) - 1 +} + +// Search returns the index of the given string or -1 if it is not in the set. +// The Set must have been created with strings in sorted order. +func Search(s *Set, str string) int { + // TODO: optimize this if it gets used a lot. + n := len(s.Index) - 1 + p := sort.Search(n, func(i int) bool { + return s.Elem(i) >= str + }) + if p == n || str != s.Elem(p) { + return -1 + } + return p +} + +// A Builder constructs Sets. +type Builder struct { + set Set + index map[string]int +} + +// NewBuilder returns a new and initialized Builder. +func NewBuilder() *Builder { + return &Builder{ + set: Set{ + Index: []uint16{0}, + }, + index: map[string]int{}, + } +} + +// Set creates the set created so far. +func (b *Builder) Set() Set { + return b.set +} + +// Index returns the index for the given string, which must have been added +// before. +func (b *Builder) Index(s string) int { + return b.index[s] +} + +// Add adds a string to the index. Strings that are added by a single Add will +// be stored together, unless they match an existing string. +func (b *Builder) Add(ss ...string) { + // First check if the string already exists. + for _, s := range ss { + if _, ok := b.index[s]; ok { + continue + } + b.index[s] = len(b.set.Index) - 1 + b.set.Data += s + x := len(b.set.Data) + if x > 0xFFFF { + panic("Index too > 0xFFFF") + } + b.set.Index = append(b.set.Index, uint16(x)) + } +} 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 0d6d0bced0f..9c7401c9ba5 100644 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -30,6 +30,7 @@ import ( "slices" "strconv" "strings" + "sync" "golang.org/x/tools/internal/typesinternal" ) @@ -126,7 +127,8 @@ 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 { - pkgIndex map[*types.Package]*pkgIndex + pkgIndexMu sync.Mutex + pkgIndex map[*types.Package]*pkgIndex } // A traversal encapsulates the state of a single traversal of the object/type graph. @@ -191,6 +193,8 @@ type pkgIndex struct { // For returns the path to an object relative to its package, // or an error if the object is not accessible from the package's Scope. // +// For is safe for concurrent use. +// // The For function guarantees to return a path only for the following objects: // - package-level types // - exported package-level non-types @@ -320,6 +324,9 @@ func (enc *Encoder) For(obj types.Object) (Path, error) { panic(obj) } + enc.pkgIndexMu.Lock() + defer enc.pkgIndexMu.Unlock() + // 4. Search the object/type graph for the path to // the var (field/param/result) or method. ix, ok := enc.pkgIndex[pkg] diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go index 0f73c719cd1..b049e5f9775 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/deps.go +++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go @@ -12,386 +12,387 @@ type pkginfo struct { } var deps = [...]pkginfo{ - {"archive/tar", "\x03{\x03F>\x01\n\x01&\x01\x01\x02\x05\b\x02\x01\x02\x02\r"}, - {"archive/zip", "\x02\x04j\x0e\x03\x12\x022>\x01-\x05\x01\x0f\x03\x02\x0f\x04"}, - {"bufio", "\x03{\x87\x01F\x15"}, - {"bytes", "~*]\x03\fJ\x02\x02"}, + {"archive/tar", "\x03|\x03F>\x01\n\x01&\x01\x01\x02\x05\b\x02\x01\x02\x02\r"}, + {"archive/zip", "\x02\x04k\x0e\x03\x12\x022>\x01-\x05\x01\x0f\x03\x02\x0f\x04"}, + {"bufio", "\x03|\x87\x01F\x15"}, + {"bytes", "\x7f*]\x03\fJ\x02\x02"}, {"cmp", ""}, - {"compress/bzip2", "\x02\x02\x81\x02C"}, - {"compress/flate", "\x02|\x03\x84\x01\f\x034\x02\x03"}, - {"compress/gzip", "\x02\x04j\x0e\x03\x14pW"}, - {"compress/lzw", "\x02|\x03\x84\x01"}, - {"compress/zlib", "\x02\x04j\x0e\x03\x12\x01q"}, - {"container/heap", "\xc9\x02"}, + {"compress/bzip2", "\x02\x02\x82\x02C"}, + {"compress/flate", "\x02}\x03\x84\x01\f\x034\x02\x03"}, + {"compress/gzip", "\x02\x04k\x0e\x03\x14pW"}, + {"compress/lzw", "\x02}\x03\x84\x01"}, + {"compress/zlib", "\x02\x04k\x0e\x03\x12\x01q"}, + {"container/heap", "\xca\x02"}, {"container/list", ""}, {"container/ring", ""}, - {"context", "~]r\x01\x0e"}, - {"crypto", "\x93\x01rE"}, - {"crypto/aes", "\x10\v\n\xa5\x02"}, - {"crypto/cipher", "\x03\"\x01\x01 \x13$+\\"}, - {"crypto/des", "\x10\x17 7+\xa1\x01\x03"}, - {"crypto/dsa", "G\x034\x87\x01\r"}, - {"crypto/ecdh", "\x03\v\r\x11\x04\x17\x03\x10$\x87\x01"}, - {"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x11\b\v\x06\x01\x03\x0f\x01$\x87\x01\r\x05O\x01"}, - {"crypto/ed25519", "\x0e \x12\a\x03\t\a$I>E"}, - {"crypto/elliptic", "5I\x87\x01\r;"}, - {"crypto/fips140", "$\x05\x9e\x01\x9b\x01"}, - {"crypto/hkdf", "1\x15\x017\x15"}, - {"crypto/hmac", "\x1b\x17\x14\x01\x139"}, - {"crypto/hpke", "\x03\v\x02\x03\x04\x01\r\x01\x05\x1f\x06\a\x01\x01%\x03\x12\x16\x9f\x01\x1d"}, - {"crypto/internal/boring", "\x0e\x02\x0eu"}, - {"crypto/internal/boring/bbig", "\x1b\xf7\x01P"}, - {"crypto/internal/boring/bcache", "\xce\x02\x14"}, + {"context", "\x7f]r\x01\x0e"}, + {"crypto", "\x94\x01rE"}, + {"crypto/aes", "\x10\v\v\xa5\x02"}, + {"crypto/cipher", "\x03#\x01\x01 \x13$+\\"}, + {"crypto/des", "\x10\x18 7+\xa1\x01\x03"}, + {"crypto/dsa", "H\x034\x87\x01\r"}, + {"crypto/ecdh", "\x03\v\r\x12\x04\x17\x03\x10$\x87\x01"}, + {"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x12\b\v\x06\x01\x03\x0f\x01$\x87\x01\r\x05O\x01"}, + {"crypto/ed25519", "\x0e!\x12\a\x03\t\a$I>E"}, + {"crypto/elliptic", "6I\x87\x01\r;"}, + {"crypto/fips140", "%\x05\x9e\x01\x9b\x01"}, + {"crypto/hkdf", "2\x15\x017\x15"}, + {"crypto/hmac", "\x1b\x18\x14\x01\x139"}, + {"crypto/hpke", "\x03\v\x02\x03\x04\x01\x0e\x01\x05\x1f\x06\a\x01\x01%\x03\x12\x16\x9f\x01\x1d"}, + {"crypto/internal/boring", "\x0e\x02\x0ev"}, + {"crypto/internal/boring/bbig", "\x1b\xf8\x01P"}, + {"crypto/internal/boring/bcache", "\xcf\x02\x14"}, {"crypto/internal/boring/sig", ""}, {"crypto/internal/constanttime", ""}, - {"crypto/internal/cryptotest", "\x03\r\v\t%\x11\x1a\r\x12\x12!\x04\x06\n\x19\x01\x11\x11\x1d\x01\a\x03\x02\b\x02\x01\x05\f"}, - {"crypto/internal/cryptotest/wycheproof", "\x0e\x12S\x01\f\x01r@\x05\x03\x15\x10"}, - {"crypto/internal/entropy", "L"}, - {"crypto/internal/entropy/v1.0.0", "E9\x96\x01:\x14"}, - {"crypto/internal/fips140", "D:\xc2\x01\v\x17"}, - {"crypto/internal/fips140/aes", "\x03!\x03\x02\x14\x05\x01\x01\x055\x96\x016"}, - {"crypto/internal/fips140/aes/gcm", "$\x01\x02\x02\x02\x12\x05\x01\x065\x93\x01"}, - {"crypto/internal/fips140/alias", "\xe2\x02"}, - {"crypto/internal/fips140/bigmod", ")\x19\x01\x065\x96\x01"}, - {"crypto/internal/fips140/check", "$\x0e\a\t\x02\xc1\x01]"}, - {"crypto/internal/fips140/check/checktest", ")\x97\x02\""}, - {"crypto/internal/fips140/drbg", "\x03 \x01\x01\x04\x14\x05\n2\x87\x01\x0f9\x01"}, - {"crypto/internal/fips140/ecdh", "\x03!\x05\x02\n\r<\x87\x01\x0f9"}, - {"crypto/internal/fips140/ecdsa", "\x03!\x04\x01\x02\a\x03\x06C\x15r\x0f9"}, - {"crypto/internal/fips140/ed25519", "\x03!\x05\x02\x04\fC\xcc\x01\x03"}, - {"crypto/internal/fips140/edwards25519", "\x1f\n\a\x12<\x96\x019"}, - {"crypto/internal/fips140/edwards25519/field", ")\x14\x05<\x96\x01"}, - {"crypto/internal/fips140/hkdf", "\x03!\x05\t\aE\x15"}, - {"crypto/internal/fips140/hmac", "\x03!\x15\x01\x01C\x15"}, - {"crypto/internal/fips140/mldsa", "\x03\x1c\x05\x05\x02\x0e\x01\x03\x05<\x96\x019"}, - {"crypto/internal/fips140/mlkem", "\x03!\x05\x02\x0f\x03\x05<\xcf\x01"}, - {"crypto/internal/fips140/nistec", "\x1f\n\r\f<\x96\x01,\r\x15"}, - {"crypto/internal/fips140/nistec/fiat", ")\x14A\x96\x01"}, - {"crypto/internal/fips140/pbkdf2", "\x03!\x05\t\aE\x15"}, - {"crypto/internal/fips140/rsa", "\x03\x1c\x05\x04\x01\x02\x0e\x01\x01\x02A\x15rH"}, - {"crypto/internal/fips140/sha256", "\x03!\x1e\x01\x065\x15\x81\x01"}, - {"crypto/internal/fips140/sha3", "\x03!\x19\x05\x01;\x96\x01N"}, - {"crypto/internal/fips140/sha512", "\x03!\x1e\x01\x065\x15\x81\x01"}, - {"crypto/internal/fips140/ssh", ")j"}, - {"crypto/internal/fips140/subtle", "\x1f\b\x1b\xd2\x01"}, - {"crypto/internal/fips140/tls12", "\x03!\x05\t\a\x02C\x15"}, - {"crypto/internal/fips140/tls13", "\x03!\x05\b\b\t<\x15"}, - {"crypto/internal/fips140cache", "\xc0\x02\r."}, + {"crypto/internal/cryptotest", "\x03\r\v\n%\x11\x1a\r\x12\x12!\x04\x06\n\x19\x01\x11\x11\x1d\x01\a\x03\x02\b\x02\x01\x05\f"}, + {"crypto/internal/cryptotest/wycheproof", "\x0e\x12T\x01\f\x01r@\x05\x03\x15\x10"}, + {"crypto/internal/cryptotest/x509limbo", "u\n\x03\xba\x01\x03\x1e"}, + {"crypto/internal/entropy", "M"}, + {"crypto/internal/entropy/v1.0.0", "F9\x96\x01:\x14"}, + {"crypto/internal/fips140", "E:\xc2\x01\v\x17"}, + {"crypto/internal/fips140/aes", "\x03\"\x03\x02\x14\x05\x01\x01\x055\x96\x016"}, + {"crypto/internal/fips140/aes/gcm", "%\x01\x02\x02\x02\x12\x05\x01\x065\x93\x01"}, + {"crypto/internal/fips140/alias", "\xe3\x02"}, + {"crypto/internal/fips140/bigmod", "*\x19\x01\x065\x96\x01"}, + {"crypto/internal/fips140/check", "%\x0e\a\t\x02\xc1\x01]"}, + {"crypto/internal/fips140/check/checktest", "*\x97\x02\""}, + {"crypto/internal/fips140/drbg", "\x03!\x01\x01\x04\x14\x05\n2\x87\x01\x0f9\x01"}, + {"crypto/internal/fips140/ecdh", "\x03\"\x05\x02\n\r<\x87\x01\x0f9"}, + {"crypto/internal/fips140/ecdsa", "\x03\"\x04\x01\x02\a\x03\x06C\x15r\x0f9"}, + {"crypto/internal/fips140/ed25519", "\x03\"\x05\x02\x04\fC\xcc\x01\x03"}, + {"crypto/internal/fips140/edwards25519", "\x1f\v\a\x12<\x96\x019"}, + {"crypto/internal/fips140/edwards25519/field", "*\x14\x05<\x96\x01"}, + {"crypto/internal/fips140/hkdf", "\x03\"\x05\t\aE\x15"}, + {"crypto/internal/fips140/hmac", "\x03\"\x15\x01\x01C\x15"}, + {"crypto/internal/fips140/mldsa", "\x03\x1c\x06\x05\x02\x0e\x01\x03\x05<\x96\x019"}, + {"crypto/internal/fips140/mlkem", "\x03\"\x05\x02\x0f\x03\x05<\xcf\x01"}, + {"crypto/internal/fips140/nistec", "\x1f\v\r\f<\x96\x01,\r\x15"}, + {"crypto/internal/fips140/nistec/fiat", "*\x14A\x96\x01"}, + {"crypto/internal/fips140/pbkdf2", "\x03\"\x05\t\aE\x15"}, + {"crypto/internal/fips140/rsa", "\x03\x1c\x06\x04\x01\x02\x0e\x01\x01\x02A\x15rH"}, + {"crypto/internal/fips140/sha256", "\x03\"\x1e\x01\x065\x15\x81\x01"}, + {"crypto/internal/fips140/sha3", "\x03\"\x19\x05\x01;\x96\x01N"}, + {"crypto/internal/fips140/sha512", "\x03\"\x1e\x01\x065\x15\x81\x01"}, + {"crypto/internal/fips140/ssh", "*j"}, + {"crypto/internal/fips140/subtle", "\x1f\t\x1b\xd2\x01"}, + {"crypto/internal/fips140/tls12", "\x03\"\x05\t\a\x02C\x15"}, + {"crypto/internal/fips140/tls13", "\x03\"\x05\b\b\t<\x15"}, + {"crypto/internal/fips140cache", "\xc1\x02\r."}, {"crypto/internal/fips140deps", ""}, - {"crypto/internal/fips140deps/byteorder", "\xa9\x01"}, - {"crypto/internal/fips140deps/cpu", "\xbe\x01\b"}, - {"crypto/internal/fips140deps/godebug", "\xc7\x01"}, - {"crypto/internal/fips140deps/time", "\xe2\x02"}, - {"crypto/internal/fips140hash", ":\x1e;\xcf\x01"}, - {"crypto/internal/fips140only", "\x17\x14\x0e\x01\x01Xr"}, + {"crypto/internal/fips140deps/byteorder", "\xaa\x01"}, + {"crypto/internal/fips140deps/cpu", "\xbf\x01\b"}, + {"crypto/internal/fips140deps/godebug", "\xc8\x01"}, + {"crypto/internal/fips140deps/time", "\xe3\x02"}, + {"crypto/internal/fips140hash", ";\x1e;\xcf\x01"}, + {"crypto/internal/fips140only", "\x17\x15\x0e\x01\x01Xr"}, {"crypto/internal/fips140test", ""}, - {"crypto/internal/impl", "\xcb\x02"}, - {"crypto/internal/rand", "\x1b\x10 |>]"}, - {"crypto/internal/randutil", "\x85\x02\x12"}, - {"crypto/internal/sysrand", "~r!\"\r\r\x01\x01\r\x06"}, - {"crypto/internal/sysrand/internal/seccomp", "~"}, - {"crypto/md5", "\x0e97\x15\x16k"}, - {"crypto/mldsa", "\x0e%K\x87\x01"}, - {"crypto/mlkem", "\x0e&"}, - {"crypto/mlkem/mlkemtest", "4\x13\t."}, - {"crypto/pbkdf2", "7\x0f\x017\x15"}, - {"crypto/rand", "\x1b\x10\x1c\x034\x87\x01\rP"}, - {"crypto/rc4", "' 7\xcc\x01"}, - {"crypto/rsa", "\x0e\r\x01\f\x10\x0e\x01\x03\t\a$\x03\x124>\f\x01"}, - {"crypto/sha1", "\x0e\r,\x025\x15\x16\x15V"}, - {"crypto/sha256", "\x0e\r\x1eZ"}, - {"crypto/sha3", "\x0e,Y\xcf\x01"}, - {"crypto/sha512", "\x0e\r X"}, - {"crypto/subtle", "\x1f\x1e\xa9\x01|"}, - {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\n\x01\x18\x01\x0f\x01\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x1f\x02\x03\x12\x16\x15\t>\x16\x18\r\b\x01\x01\x01\x02\x01\x0e\x06\x03\x01\x15"}, - {"crypto/tls/internal/fips140tls", "\x17\xb7\x02"}, - {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x01\x017\x01\x06\x01\x01\x02\x05\x0f\x06\t\x02\x03F\x03;\x01\x02\b\x01\x01\x02\a\x12\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x04\x01"}, - {"crypto/x509/pkix", "m\x06\x0e\x91\x019\x11"}, - {"database/sql", "\x03\nS\x01\x1d\x03\x84\x01\v\a$\x05\b\x02\x03\x01\x0e\x02\x02\x02\x01"}, - {"database/sql/driver", "\rT\x1d\x03\xba\x01\x0f\x12\a"}, + {"crypto/internal/impl", "\xcc\x02"}, + {"crypto/internal/rand", "\x1b\x11 |>]"}, + {"crypto/internal/randutil", "\x86\x02\x12"}, + {"crypto/internal/sysrand", "\x7fr!\"\r\r\x01\x01\r\x06"}, + {"crypto/internal/sysrand/internal/seccomp", "\x7f"}, + {"crypto/md5", "\x0e:7\x15\x16k"}, + {"crypto/mldsa", "\x0e&K\x87\x01"}, + {"crypto/mlkem", "\x0e'"}, + {"crypto/mlkem/mlkemtest", "5\x13\t."}, + {"crypto/pbkdf2", "8\x0f\x017\x15"}, + {"crypto/rand", "\x1b\x11\x1c\x034\x87\x01\rP"}, + {"crypto/rc4", "( 7\xcc\x01"}, + {"crypto/rsa", "\x0e\r\x01\r\x10\x0e\x01\x03\t\a$\x03\x124>\f\x01"}, + {"crypto/sha1", "\x0e\r-\x025\x15\x16\x15V"}, + {"crypto/sha256", "\x0e\r\x1fZ"}, + {"crypto/sha3", "\x0e-Y\xcf\x01"}, + {"crypto/sha512", "\x0e\r!X"}, + {"crypto/subtle", "\x1f\x1f\xa9\x01|"}, + {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\v\x01\x18\x01\x0f\x01\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x1f\x02\x03\x12\x16\x15\t>\x16\x18\r\b\x01\x01\x01\x02\x01\x0e\x06\x03\x01\x15"}, + {"crypto/tls/internal/fips140tls", "\x17\xb8\x02"}, + {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x01\x018\x01\x06\x01\x01\x02\x05\x0f\x06\t\x02\x03F\x03;\x01\x02\b\x01\x01\x02\a\x12\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x04\x01"}, + {"crypto/x509/pkix", "n\x06\x0e\x91\x019\x11"}, + {"database/sql", "\x03\nT\x01\x1d\x03\x84\x01\v\a$\x05\b\x02\x03\x01\x0e\x02\x02\x02\x01"}, + {"database/sql/driver", "\rU\x1d\x03\xba\x01\x0f\x12\a"}, {"database/sql/internal", ""}, - {"debug/buildinfo", "\x03a\x02\x01\x01\b\x0e\x03h\x1a\x02\x01-\x0f "}, - {"debug/dwarf", "\x03m\x0e\x03\x84\x013\x11\x01\x01"}, - {"debug/elf", "\x03\x06Z\r\x0e\x03h\x1b\x01\f\"\x17\x01\x17"}, - {"debug/gosym", "\x03m\x11#\xa5\x01\x01\x01\x02"}, - {"debug/macho", "\x03\x06Z\r\x11h\x1c.\x17\x01"}, - {"debug/pe", "\x03\x06Z\r\x0e\x03h\x1c.\x17\x01\x17"}, - {"debug/plan9obj", "p\x0e\x03h\x1c."}, - {"embed", "~*D\x19\x01V"}, + {"debug/buildinfo", "\x03b\x02\x01\x01\b\x0e\x03h\x1a\x02\x01-\x0f "}, + {"debug/dwarf", "\x03n\x0e\x03\x84\x013\x11\x01\x01"}, + {"debug/elf", "\x03\x06[\r\x0e\x03h\x1b\x01\f\"\x17\x01\x17"}, + {"debug/gosym", "\x03n\x11#\xa5\x01\x01\x01\x02"}, + {"debug/macho", "\x03\x06[\r\x11h\x1c.\x17\x01"}, + {"debug/pe", "\x03\x06[\r\x0e\x03h\x1c.\x17\x01\x17"}, + {"debug/plan9obj", "q\x0e\x03h\x1c."}, + {"embed", "\x7f*D\x19\x01V"}, {"embed/internal/embedtest", ""}, {"encoding", ""}, - {"encoding/ascii85", "\x85\x02E"}, - {"encoding/asn1", "\x03{\x03h(\x01)\r\x02\x01\x11\x03\x01"}, - {"encoding/base32", "\x85\x02C\x02"}, - {"encoding/base64", "\xa9\x01\\C\x02"}, - {"encoding/binary", "~\x87\x01\f*\r\x05"}, - {"encoding/csv", "\x02\x01{\x03\x84\x01F\x13\x02"}, - {"encoding/gob", "\x02i\x05\x0e\x03h\x1c\v\x01\x03\x1f\b\x12\x01\x10\x02"}, - {"encoding/hex", "~\x03\x84\x01C\x03"}, - {"encoding/json", "\x03\x01g\n\x01\x01\x02\x01\x01\x03\x03\x84\x016\x0f\x01"}, - {"encoding/json/internal", "~"}, - {"encoding/json/internal/jsonflags", "u"}, - {"encoding/json/internal/jsonopts", "u\x01"}, - {"encoding/json/internal/jsontest", "\x03f\x15\x03\x83\x01\x01\x012\b\b\x03\x02\x0f"}, - {"encoding/json/internal/jsonwire", "\x04r\b\x87\x01\f7\x02\x01\x13\x01\x01"}, - {"encoding/json/jsontext", "\x03r\x01\x01\x02\x05\x87\x01\x03\t\x034\x02\x01\x02\x13"}, - {"encoding/json/v2", "\x03\x01g\x03\x01\x01\x03\x02\x01\x01\x02\x01\x04\x03\x84\x01\f\x03'\r\x02\x01\x02\x0f\x02\x02"}, - {"encoding/pem", "\x03l\x0f\x87\x01C\x03"}, - {"encoding/xml", "\x02\x01h\x13\x03\x84\x016\x05\n\x01\x02\x11\x02"}, - {"errors", "\xdb\x01\x87\x01"}, - {"expvar", "tSB\b\v\x17\r\b\x02\x03\x01\x12"}, - {"flag", "k\x13\x03\x84\x01.\b\x05\b\x02\x01\x11"}, - {"fmt", "~E)\x19\f\"\b\r\x02\x03\x13"}, - {"go/ast", "\x03\x01}\x0e\x01u\x03+\b\r\x02\x01\x13\x02"}, - {"go/build", "\x02\x01{\x03\x01\x02\x02\a\x02\x01\x17 \x04\x02\t\x1c\x13\x01-\x01\x04\x01\a\b\x02\x01\x13\x02\x02"}, - {"go/build/constraint", "~\xcc\x01\x01\x13\x02"}, - {"go/constant", "\x81\x01\x0f\x81\x01\x01\x026\x01\x02\x13"}, - {"go/doc", "\x04}\x01\x05\t>73\x10\x02\x01\x13\x02"}, - {"go/doc/comment", "\x03~\xc7\x01\x01\x01\x01\x13\x02"}, - {"go/format", "\x03~\x01\v\x01\x02uF"}, - {"go/importer", "\x83\x01\a\x01\x01\x04\x01t;"}, - {"go/internal/gccgoimporter", "\x02\x01a\x1a\x03\x04\v\x01r\x02.\x01\x05\x11\x01\r\b"}, - {"go/internal/gcimporter", "\x02\x7f\x0f\x010\x140.\x15\x03\x02"}, - {"go/internal/srcimporter", "\x81\x01\x01\x01\n\x03\x01t.\x01\x05\x12\x02\x15"}, - {"go/parser", "\x03{\x03\x01\x02\v\x01u\x01-\x06\x12"}, - {"go/printer", "\x81\x01\x01\x02\x03\tu\f\"\x15\x02\x01\x02\f\x05\x02"}, - {"go/scanner", "\x03~\x0fu4\x10\x01\x14\x02"}, - {"go/token", "\x04}\x87\x01@\x02\x03\x01\x10\x02"}, - {"go/types", "\x03\x01\x06t\x03\x01\x03\b\x03\x02\x0654\x04\x03\t\"\x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"}, - {"go/version", "\xcc\x01\x7f"}, - {"hash", "\x85\x02"}, - {"hash/adler32", "~\x15\x16"}, - {"hash/crc32", "~\x15\x16\x15\x8f\x01\x01\x14"}, - {"hash/crc64", "~\x15\x16\xa4\x01"}, - {"hash/fnv", "~\x15\x16k"}, - {"hash/maphash", "\x93\x01\x11>\x80\x01"}, - {"html", "\xcb\x02\x02\x13"}, - {"html/template", "\x03q\r\x18.>\x01\n#\x05\x01\x02\x03\n\x02\x01\x02\r\x01\x03\x02"}, - {"image", "\x02|\x1ei\x0f6\x03\x01"}, + {"encoding/ascii85", "\x86\x02E"}, + {"encoding/asn1", "\x03|\x03h(\x01)\r\x02\x01\x11\x03\x01"}, + {"encoding/base32", "\x86\x02C\x02"}, + {"encoding/base64", "\xaa\x01\\C\x02"}, + {"encoding/binary", "\x7f\x87\x01\f*\r\x05"}, + {"encoding/csv", "\x02\x01|\x03\x84\x01F\x13\x02"}, + {"encoding/gob", "\x02j\x05\x0e\x03h\x1c\v\x01\x03\x1f\b\x12\x01\x10\x02"}, + {"encoding/hex", "\x7f\x03\x84\x01C\x03"}, + {"encoding/json", "\x03\x01h\n\x01\x01\x02\x01\x01\x03\x03\x84\x016\x0f\x01"}, + {"encoding/json/internal", "\x7f"}, + {"encoding/json/internal/jsonflags", "v"}, + {"encoding/json/internal/jsonopts", "v\x01"}, + {"encoding/json/internal/jsontest", "\x03g\x15\x03\x83\x01\x01\x012\b\b\x03\x02\x0f"}, + {"encoding/json/internal/jsonwire", "\x04s\b\x87\x01\f7\x02\x01\x13\x01\x01"}, + {"encoding/json/jsontext", "\x03s\x01\x01\x02\x05\x87\x01\x03\t\x034\x02\x01\x02\x13"}, + {"encoding/json/v2", "\x03\x01h\x03\x01\x01\x03\x02\x01\x01\x02\x01\x04\x03\x84\x01\f\x03'\r\x02\x01\x02\x0f\x02\x02"}, + {"encoding/pem", "\x03m\x0f\x87\x01C\x03"}, + {"encoding/xml", "\x02\x01i\x13\x03\x84\x016\x05\n\x01\x02\x11\x02"}, + {"errors", "\xdc\x01\x87\x01"}, + {"expvar", "uSB\b\v\x17\r\b\x02\x03\x01\x12"}, + {"flag", "l\x13\x03\x84\x01.\b\x05\b\x02\x01\x11"}, + {"fmt", "\x7fE)\x19\f\"\b\r\x02\x03\x13"}, + {"go/ast", "\x03\x01~\x0e\x01u\x03+\b\r\x02\x01\x13\x02"}, + {"go/build", "\x02\x01|\x03\x01\x02\x02\a\x02\x01\x17 \x04\x02\t\x1c\x13\x01-\x01\x04\x01\a\b\x02\x01\x13\x02\x02"}, + {"go/build/constraint", "\x7f\xcc\x01\x01\x13\x02"}, + {"go/constant", "\x82\x01\x0f\x81\x01\x01\x026\x01\x02\x13"}, + {"go/doc", "\x04~\x01\x05\t>73\x10\x02\x01\x13\x02"}, + {"go/doc/comment", "\x03\x7f\xc7\x01\x01\x01\x01\x13\x02"}, + {"go/format", "\x03\x7f\x01\v\x01\x02uF"}, + {"go/importer", "\x84\x01\a\x01\x01\x04\x01t;"}, + {"go/internal/gccgoimporter", "\x02\x01b\x1a\x03\x04\v\x01r\x02.\x01\x05\x11\x01\r\b"}, + {"go/internal/gcimporter", "\x02\x80\x01\x0f\x010\x140.\x15\x03\x02"}, + {"go/internal/srcimporter", "\x82\x01\x01\x01\n\x03\x01t.\x01\x05\x12\x02\x15"}, + {"go/parser", "\x03|\x03\x01\x02\v\x01u\x01-\x06\x12"}, + {"go/printer", "\x82\x01\x01\x02\x03\tu\f\"\x15\x02\x01\x02\f\x05\x02"}, + {"go/scanner", "\x03\x7f\x0fu4\x10\x01\x14\x02"}, + {"go/token", "\x04~\x87\x01@\x02\x03\x01\x10\x02"}, + {"go/types", "\x03\x01\x06u\x03\x01\x03\b\x03\x02\x0654\x04\x03\t\"\x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"}, + {"go/version", "\xcd\x01\x7f"}, + {"hash", "\x86\x02"}, + {"hash/adler32", "\x7f\x15\x16"}, + {"hash/crc32", "\x7f\x15\x16\x15\x8f\x01\x01\x14"}, + {"hash/crc64", "\x7f\x15\x16\xa4\x01"}, + {"hash/fnv", "\x7f\x15\x16k"}, + {"hash/maphash", "\x94\x01\x11>\x80\x01"}, + {"html", "\xcc\x02\x02\x13"}, + {"html/template", "\x03r\r\x18.>\x01\n#\x05\x01\x02\x03\n\x02\x01\x02\r\x01\x03\x02"}, + {"image", "\x02}\x1ei\x0f6\x03\x01"}, {"image/color", ""}, - {"image/color/palette", "\x9c\x01"}, - {"image/draw", "\x9b\x01\x01\x04"}, - {"image/gif", "\x02\x01\x05v\x03\x1a\x01\x01\x01\v\\\x0f"}, - {"image/internal/imageutil", "\x9b\x01"}, - {"image/jpeg", "\x02|\x1d\x01\x04e"}, - {"image/png", "\x02\ag\x11\x12\x02\x06\x01iE"}, - {"index/suffixarray", "\x03m\x0e\x87\x01\f-\n\x01"}, - {"internal/abi", "\xc6\x01\x9c\x01"}, - {"internal/asan", "\xe2\x02"}, - {"internal/bisect", "\xc0\x02\r\x01"}, - {"internal/buildcfg", "\x81\x01Hj\x06\x02\x05\n\x01"}, - {"internal/bytealg", "\xbe\x01\xa4\x01"}, + {"image/color/palette", "\x9d\x01"}, + {"image/draw", "\x9c\x01\x01\x04"}, + {"image/gif", "\x02\x01\x05w\x03\x1a\x01\x01\x01\v\\\x0f"}, + {"image/internal/imageutil", "\x9c\x01"}, + {"image/jpeg", "\x02}\x1d\x01\x04e"}, + {"image/png", "\x02\ah\x11\x12\x02\x06\x01iE"}, + {"index/suffixarray", "\x03n\x0e\x87\x01\f-\n\x01"}, + {"internal/abi", "\xc7\x01\x9c\x01"}, + {"internal/asan", "\xe3\x02"}, + {"internal/bisect", "\xc1\x02\r\x01"}, + {"internal/buildcfg", "\x82\x01Hj\x06\x02\x05\n\x01"}, + {"internal/bytealg", "\xbf\x01\xa4\x01"}, {"internal/byteorder", ""}, {"internal/cfg", ""}, - {"internal/cgrouptest", "\x81\x01\\V\x06\x0f\x02\x01\x04\x01"}, - {"internal/chacha8rand", "\xa9\x01\x15\b\x9c\x01"}, + {"internal/cgrouptest", "\x82\x01\\V\x06\x0f\x02\x01\x04\x01"}, + {"internal/chacha8rand", "\xaa\x01\x15\b\x9c\x01"}, {"internal/copyright", ""}, {"internal/coverage", ""}, {"internal/coverage/calloc", ""}, - {"internal/coverage/cfile", "t\r\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01$\x02'.\x06\a\n\x01\x03\x0e\x06"}, - {"internal/coverage/cformat", "\x04}-\x04S\v8\x01\x02\x0e"}, - {"internal/coverage/cmerge", "\x81\x01-c"}, - {"internal/coverage/decodecounter", "p\x11-\v\x02J.\x17\x18"}, - {"internal/coverage/decodemeta", "\x02n\x11\x16\x17\v\x02J."}, - {"internal/coverage/encodecounter", "\x02n\x11-\f\x01\x02H\v#\x15"}, - {"internal/coverage/encodemeta", "\x02\x01m\x11\x12\x04\x17\r\x02H./"}, - {"internal/coverage/pods", "\x04}-\x85\x01\x06\x05\n\x02\x01"}, - {"internal/coverage/rtcov", "\xe2\x02"}, - {"internal/coverage/slicereader", "p\x11\x84\x01]"}, - {"internal/coverage/slicewriter", "\x81\x01\x84\x01"}, - {"internal/coverage/stringtab", "\x81\x018\x04H"}, + {"internal/coverage/cfile", "u\r\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01$\x02'.\x06\a\n\x01\x03\x0e\x06"}, + {"internal/coverage/cformat", "\x04~-\x04S\v8\x01\x02\x0e"}, + {"internal/coverage/cmerge", "\x82\x01-c"}, + {"internal/coverage/decodecounter", "q\x11-\v\x02J.\x17\x18"}, + {"internal/coverage/decodemeta", "\x02o\x11\x16\x17\v\x02J."}, + {"internal/coverage/encodecounter", "\x02o\x11-\f\x01\x02H\v#\x15"}, + {"internal/coverage/encodemeta", "\x02\x01n\x11\x12\x04\x17\r\x02H./"}, + {"internal/coverage/pods", "\x04~-\x85\x01\x06\x05\n\x02\x01"}, + {"internal/coverage/rtcov", "\xe3\x02"}, + {"internal/coverage/slicereader", "q\x11\x84\x01]"}, + {"internal/coverage/slicewriter", "\x82\x01\x84\x01"}, + {"internal/coverage/stringtab", "\x82\x018\x04H"}, {"internal/coverage/test", ""}, {"internal/coverage/uleb128", ""}, - {"internal/cpu", "\xe2\x02"}, - {"internal/dag", "\x04}\xc7\x01\x03"}, - {"internal/diff", "\x03~\xc8\x01\x02"}, - {"internal/exportdata", "\x02\x01{\x03\x02f\x1c.\x01\x05\x11\x01\x02"}, - {"internal/filepathlite", "~*D\x1aB"}, - {"internal/fmtsort", "\x04\xb7\x02\r"}, - {"internal/fuzz", "\x03\nJ\x19\x04\n\x03\x01\v\x037>\f\x03\x1f\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"}, + {"internal/cpu", "\xe3\x02"}, + {"internal/dag", "\x04~\xc7\x01\x03"}, + {"internal/diff", "\x03\x7f\xc8\x01\x02"}, + {"internal/exportdata", "\x02\x01|\x03\x02f\x1c.\x01\x05\x11\x01\x02"}, + {"internal/filepathlite", "\x7f*D\x1aB"}, + {"internal/fmtsort", "\x04\xb8\x02\r"}, + {"internal/fuzz", "\x03\nK\x19\x04\n\x03\x01\v\x037>\f\x03\x1f\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"}, {"internal/gate", "\r"}, {"internal/goarch", ""}, - {"internal/godebug", "\xa6\x01\"\x85\x01\x01\x14"}, + {"internal/godebug", "\xa7\x01\"\x85\x01\x01\x14"}, {"internal/godebugs", ""}, {"internal/goexperiment", ""}, {"internal/goos", ""}, - {"internal/goroot", "\xb3\x02\x01\x05\x12\x02"}, + {"internal/goroot", "\xb4\x02\x01\x05\x12\x02"}, {"internal/gover", "\x04"}, {"internal/goversion", ""}, - {"internal/lazyregexp", "\xb3\x02\v\r\x02"}, - {"internal/lazytemplate", "\x85\x02.\x18\x02\r"}, - {"internal/msan", "\xe2\x02"}, - {"internal/nettest", "\x03\nqG@\f\n\x12\x06\x15\x05\x0f"}, + {"internal/lazyregexp", "\xb4\x02\v\r\x02"}, + {"internal/lazytemplate", "\x86\x02.\x18\x02\r"}, + {"internal/msan", "\xe3\x02"}, + {"internal/nettest", "\x03\nrG@\f\n\x12\x06\x15\x05\x0f"}, {"internal/nettrace", ""}, - {"internal/obscuretestdata", "o\x96\x01."}, - {"internal/oserror", "~"}, - {"internal/pkgbits", "\x03T\x19\x0e\x03\x04\vu\r!\r\n\x01"}, + {"internal/obscuretestdata", "p\x96\x01."}, + {"internal/oserror", "\x7f"}, + {"internal/pkgbits", "\x03U\x19\x0e\x03\x04\vu\r!\r\n\x01"}, {"internal/platform", ""}, - {"internal/poll", "~m\x05\x15;\r\x01\x01\r\x06"}, - {"internal/profile", "\x03\x04w\x03\x84\x019\n\x01\x01\x01\x11"}, + {"internal/poll", "\x7fm\x05\x15;\r\x01\x01\r\x06"}, + {"internal/profile", "\x03\x04x\x03\x84\x019\n\x01\x01\x01\x11"}, {"internal/profilerecord", ""}, - {"internal/race", "\xa4\x01\xbe\x01"}, - {"internal/reflectlite", "\xa4\x01\"<>\""}, - {"internal/runtime/atomic", "\xc6\x01\x9c\x01"}, - {"internal/runtime/cgroup", "\xa8\x01?\x04w"}, - {"internal/runtime/exithook", "\xdc\x01\x86\x01"}, - {"internal/runtime/gc", "\xc6\x01"}, - {"internal/runtime/gc/internal/gen", "\nf\x11\x17m\x04\v\x1f\b\x10\x02"}, - {"internal/runtime/gc/scan", "\xbe\x01\b\x19\a|"}, - {"internal/runtime/maps", "\xa4\x01\x01\x04\x15\b\x03\a\n\t\x03.N"}, - {"internal/runtime/math", "\xc6\x01"}, + {"internal/race", "\xa5\x01\xbe\x01"}, + {"internal/reflectlite", "\xa5\x01\"<>\""}, + {"internal/runtime/atomic", "\xc7\x01\x9c\x01"}, + {"internal/runtime/cgroup", "\xa9\x01?\x04w"}, + {"internal/runtime/exithook", "\xdd\x01\x86\x01"}, + {"internal/runtime/gc", "\xc7\x01"}, + {"internal/runtime/gc/internal/gen", "\ng\x11\x17m\x04\v\x1f\b\x10\x02"}, + {"internal/runtime/gc/scan", "\xbf\x01\b\x19\a|"}, + {"internal/runtime/maps", "\xa5\x01\x01\x04\x15\b\x03\a\n\t\x03.N"}, + {"internal/runtime/math", "\xc7\x01"}, {"internal/runtime/pprof/label", ""}, {"internal/runtime/startlinetest", ""}, - {"internal/runtime/sys", "\xc6\x01\x04"}, - {"internal/runtime/syscall/linux", "\xc6\x01\x9c\x01"}, + {"internal/runtime/sys", "\xc7\x01\x04"}, + {"internal/runtime/syscall/linux", "\xc7\x01\x9c\x01"}, {"internal/runtime/wasitest", ""}, - {"internal/saferio", "\x85\x02]"}, - {"internal/singleflight", "\xcd\x02"}, - {"internal/strconv", "\x94\x02N"}, - {"internal/stringslite", "\xa8\x01\xba\x01"}, - {"internal/sync", "\xa4\x01\"\x14t\x14"}, - {"internal/synctest", "\xa4\x01\xbe\x01"}, - {"internal/syscall/execenv", "\xcf\x02"}, - {"internal/syscall/unix", "\xeb\x01U\x0e\x01\x13"}, - {"internal/sysinfo", "\x02\x01\xbb\x01G.\x18\x02"}, + {"internal/saferio", "\x86\x02]"}, + {"internal/singleflight", "\xce\x02"}, + {"internal/strconv", "\x95\x02N"}, + {"internal/stringslite", "\xa9\x01\xba\x01"}, + {"internal/sync", "\xa5\x01\"\x14t\x14"}, + {"internal/synctest", "\xa5\x01\xbe\x01"}, + {"internal/syscall/execenv", "\xd0\x02"}, + {"internal/syscall/unix", "\xec\x01U\x0e\x01\x13"}, + {"internal/sysinfo", "\x02\x01\xbc\x01G.\x18\x02"}, {"internal/syslist", ""}, - {"internal/testenv", "\x03\nq\x02\x01)\x1c\x100-\x01\x05\a\n\x01\x02\x02\x01\f"}, - {"internal/testhash", "\x03\x90\x01r\x11:\f"}, - {"internal/testlog", "\xcd\x02\x01\x14"}, - {"internal/testpty", "~\x03\xb2\x01"}, - {"internal/trace", "\x02\x01\x01\x06f\x0e\x03x\x03\x03\x06\x03\t-\n\x01\x01\x01\x11\x06"}, - {"internal/trace/internal/testgen", "\x03m\x11v\x03\x02\x03\x013\v\r\x11"}, - {"internal/trace/internal/tracev1", "\x03\x01l\x0e\x03~\x06\f7\x01"}, - {"internal/trace/raw", "\x02n\x11{\x03\x06E\x01\x13"}, - {"internal/trace/testtrace", "\x02\x01{\x03r\x04\x03\x05\x01\x05.\v\x02\b\x02\x01\x05"}, + {"internal/testenv", "\x03\nr\x02\x01)\x1c\x100-\x01\x05\a\n\x01\x02\x02\x01\f"}, + {"internal/testhash", "\x03\x91\x01r\x11:\f"}, + {"internal/testlog", "\xce\x02\x01\x14"}, + {"internal/testpty", "\x7f\x03\xb2\x01"}, + {"internal/trace", "\x02\x01\x01\x06g\x0e\x03x\x03\x03\x06\x03\t-\n\x01\x01\x01\x11\x06"}, + {"internal/trace/internal/testgen", "\x03n\x11v\x03\x02\x03\x013\v\r\x11"}, + {"internal/trace/internal/tracev1", "\x03\x01m\x0e\x03~\x06\f7\x01"}, + {"internal/trace/raw", "\x02o\x11{\x03\x06E\x01\x13"}, + {"internal/trace/testtrace", "\x02\x01|\x03r\x04\x03\x05\x01\x05.\v\x02\b\x02\x01\x05"}, {"internal/trace/tracev2", ""}, - {"internal/trace/traceviewer", "\x02g\v\r\x19>\x1f\a\a\x04\b\v\x17\x01\x05\a\n\x01\x02\x0f"}, + {"internal/trace/traceviewer", "\x02h\v\r\x19>\x1f\a\a\x04\b\v\x17\x01\x05\a\n\x01\x02\x0f"}, {"internal/trace/traceviewer/format", ""}, - {"internal/trace/version", "\x81\x01{\t"}, - {"internal/txtar", "\x03~\xb2\x01\x18"}, - {"internal/types/errors", "\xca\x02"}, - {"internal/unsafeheader", "\xe2\x02"}, - {"internal/xcoff", "c\r\x0e\x03h\x1c.\x17\x01"}, - {"internal/zstd", "p\x0e\x03\x84\x01\x0f"}, - {"io", "~\xcf\x01"}, - {"io/fs", "~*,13\x10\x14\x04"}, - {"io/ioutil", "\x85\x02\x01-\x15\x03"}, - {"iter", "\xda\x01f\""}, - {"log", "\x81\x01\x84\x01\x05)\r\r\x01\x0e"}, + {"internal/trace/version", "\x82\x01{\t"}, + {"internal/txtar", "\x03\x7f\xb2\x01\x18"}, + {"internal/types/errors", "\xcb\x02"}, + {"internal/unsafeheader", "\xe3\x02"}, + {"internal/xcoff", "d\r\x0e\x03h\x1c.\x17\x01"}, + {"internal/zstd", "q\x0e\x03\x84\x01\x0f"}, + {"io", "\x7f\xcf\x01"}, + {"io/fs", "\x7f*,13\x10\x14\x04"}, + {"io/ioutil", "\x86\x02\x01-\x15\x03"}, + {"iter", "\xdb\x01f\""}, + {"log", "\x82\x01\x84\x01\x05)\r\r\x01\x0e"}, {"log/internal", ""}, - {"log/slog", "\x03\n^\t\n\x03H<\x04\x01\x02\x02\x03*\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"}, + {"log/slog", "\x03\n_\t\n\x03H<\x04\x01\x02\x02\x03*\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"}, {"log/slog/internal", ""}, - {"log/slog/internal/benchmarks", "\rq\x03\x84\x01\x06\x03<\x12"}, - {"log/slog/internal/buffer", "\xcd\x02"}, - {"log/syslog", "~\x03\x88\x01\x12\x18\x18\x02\x0f"}, - {"maps", "\x88\x02Z"}, - {"math", "\xbe\x01VN"}, - {"math/big", "\x03{\x03(\x15G\f\x03\x022\x02\x01\x02\x15"}, - {"math/big/internal/asmgen", "\x03\x01}\x93\x014\x03"}, - {"math/bits", "\xe2\x02"}, - {"math/cmplx", "\x91\x02\x03"}, - {"math/rand", "\xc7\x01J<\x01\x14"}, - {"math/rand/v2", "~+\x03e\x03N"}, - {"mime", "\x02\x01l\x0f\x03\x84\x01\v#\x15\x03\x02\x11\x02"}, - {"mime/multipart", "\x02\x01P+\x03F>\v\x01\a\x02\x17\x02\x06\x0f\x02\x01\x17"}, - {"mime/quotedprintable", "\x02\x01~\x84\x01"}, - {"net", "\x04\tq*\x1f\v\x05\x13\x01\x01\x04\x15\x01'\x06\r\b\x05\x01\x01\r\x06\t"}, - {"net/http", "\x02\x01\x03\x01\x04\x02N\x14\x0f\x03F>\x01\x03\a\x01\x06\x01\x01\x02\x06\x02\x01\x01\f\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\n\x01\x03"}, - {"net/http/cgi", "\x02Y#\x03\x84\x01\x04\a\v\x01\x15\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x10"}, - {"net/http/cookiejar", "\x04z\x03\x9a\x01\x01\b\t\x05\x16\x03\x02\x0f\x04"}, - {"net/http/fcgi", "\x02\x01\nc\x0e\x03\x84\x01\x16\x01\x01\x16\x18\x02\x0f"}, - {"net/http/httptest", "\x02\x01\nN\x02#\x01P4\x04\x12\x01\f\t\x02\r\n\x01\x02\x03\f\x06\n"}, - {"net/http/httptrace", "\rNwI\x16+"}, - {"net/http/httputil", "\x02\x01\nq\x03F>\x04\x0f\x03\x01\x05\x02\x01\r\x01\x19\x02\x01\x0e\x10"}, - {"net/http/internal", "\x02\x01m\x0e\x03\x84\x01"}, - {"net/http/internal/ascii", "\xcb\x02\x13"}, - {"net/http/internal/http2", "\x02\x01\x03\x01\x06F\b\x15\x0e\x03\x84\x01\x01\x03\b\x03\x02\x03\x02\x06\x02\x03\x01\n\x01\x01\b\x05\b\x02\x01\x02\x01\x0e\x10\x02\x02"}, - {"net/http/internal/httpcommon", "\rq\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"}, - {"net/http/internal/httpsfv", "\xc8\x02\x02\x01\x11\x04"}, - {"net/http/internal/testcert", "\xcb\x02"}, - {"net/http/pprof", "\x02\x01\nt\x18.\x11-\x04\x13\x16\x01\r\x04\x03\x01\x02\x01\x11"}, + {"log/slog/internal/benchmarks", "\rr\x03\x84\x01\x06\x03<\x12"}, + {"log/slog/internal/buffer", "\xce\x02"}, + {"log/syslog", "\x7f\x03\x88\x01\x12\x18\x18\x02\x0f"}, + {"maps", "\x89\x02Z"}, + {"math", "\xbf\x01VN"}, + {"math/big", "\x03|\x03(\x15G\f\x03\x022\x02\x01\x02\x15"}, + {"math/big/internal/asmgen", "\x03\x01~\x93\x014\x03"}, + {"math/bits", "\xe3\x02"}, + {"math/cmplx", "\x92\x02\x03"}, + {"math/rand", "\xc8\x01J<\x01\x14"}, + {"math/rand/v2", "\x7f+\x03e\x03N"}, + {"mime", "\x02\x01m\x0f\x03\x84\x01\v#\x15\x03\x02\x11\x02"}, + {"mime/multipart", "\x02\x01Q+\x03F>\v\x01\a\x02\x17\x02\x06\x0f\x02\x01\x17"}, + {"mime/quotedprintable", "\x02\x01\x7f\x84\x01"}, + {"net", "\x04\tr*\x1f\v\x05\x13\x01\x01\x04\x15\x01'\x06\r\b\x05\x01\x01\r\x06\t"}, + {"net/http", "\x02\x01\x03\x01\x04\x02O\x14\x0f\x03F>\x01\x03\a\x01\x06\x01\x01\x02\x06\x02\x01\x01\f\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\n\x01\x03"}, + {"net/http/cgi", "\x02Z#\x03\x84\x01\x04\a\v\x01\x15\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x10"}, + {"net/http/cookiejar", "\x04{\x03\x9a\x01\x01\b\t\x05\x16\x03\x02\x0f\x04"}, + {"net/http/fcgi", "\x02\x01\nd\x0e\x03\x84\x01\x16\x01\x01\x16\x18\x02\x0f"}, + {"net/http/httptest", "\x02\x01\nO\x02#\x01P4\x04\x12\x01\f\t\x02\r\n\x01\x02\x03\f\x06\n"}, + {"net/http/httptrace", "\rOwI\x16+"}, + {"net/http/httputil", "\x02\x01\nr\x03F>\x04\x0f\x03\x01\x05\x02\x01\r\x01\x19\x02\x0f\x10"}, + {"net/http/internal", "\x02\x01n\x0e\x03\x84\x01"}, + {"net/http/internal/ascii", "\xcc\x02\x13"}, + {"net/http/internal/http2", "\x02\x01\x03\x01\x06G\b\x15\x0e\x03\x84\x01\x01\x03\b\x03\x02\x03\x02\x06\x02\x03\x01\n\x01\x01\b\x05\b\x02\x01\x02\x01\x0e\x10\x02\x02"}, + {"net/http/internal/httpcommon", "\rr\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"}, + {"net/http/internal/httpsfv", "\xc9\x02\x02\x01\x11\x04"}, + {"net/http/internal/testcert", "\xcc\x02"}, + {"net/http/pprof", "\x02\x01\nu\x18.\x11-\x04\x13\x16\x01\r\x04\x03\x01\x02\x01\x11"}, {"net/internal/cgotest", ""}, - {"net/internal/socktest", "\x81\x01\xcc\x01\x02"}, - {"net/mail", "\x02|\x03\x84\x01\x04\x0f\x03\x16\x1a\x02\x0f\x04"}, - {"net/netip", "\x04z*\x01h\x036\x17"}, - {"net/rpc", "\x02p\f\x03\x0f\nk\x04\x12\x01\x1f\r\x03\x02"}, - {"net/rpc/jsonrpc", "t\n\x03\x84\x01\x16\x13\x1f"}, - {"net/smtp", "\x195\r\x14\x0f\x03\x84\x01\x16\x16\x1a"}, - {"net/textproto", "\x02\x01{\x03\x84\x01\f\n/\x01\x02\x15"}, - {"net/url", "~\x03Ff\v\x10\x02\x01\x17"}, - {"os", "~*\x01\x19\x04\x11\x14\x01\x03\x01\x05\x10\x01:\b\x05\x01\x01\r\x06"}, - {"os/exec", "\x03\nqI(\x01\x15\x01-\x06\a\n\x01\x03\x01\r"}, - {"os/exec/internal/fdtest", "\xcf\x02"}, - {"os/signal", "\r\xa6\x02\x15\x05\x02"}, - {"os/user", "\x02\x01{\x03\x84\x01.\r\n\x01\x02"}, - {"path", "~*\xb8\x01"}, - {"path/filepath", "~*\x1aD-\r\b\x03\x04\x11"}, - {"plugin", "~"}, - {"reflect", "~&\x04\x1e\x03\x11\b\x04\x05\x17\x06\t/\n\x03\x11\x02\x02"}, + {"net/internal/socktest", "\x82\x01\xcc\x01\x02"}, + {"net/mail", "\x02}\x03\x84\x01\x04\x0f\x03\x16\x1a\x02\x0f\x04"}, + {"net/netip", "\x04{*\x01h\x036\x17"}, + {"net/rpc", "\x02q\f\x03\x0f\nk\x04\x12\x01\x1f\r\x03\x02"}, + {"net/rpc/jsonrpc", "u\n\x03\x84\x01\x16\x13\x1f"}, + {"net/smtp", "\x196\r\x14\x0f\x03\x84\x01\x16\x16\x1a"}, + {"net/textproto", "\x02\x01|\x03\x84\x01\f\n/\x01\x02\x15"}, + {"net/url", "\x7f\x03Ff\v\x10\x02\x01\x17"}, + {"os", "\x7f*\x01\x19\x04\x11\x14\x01\x03\x01\x05\x10\x01:\b\x05\x01\x01\r\x06"}, + {"os/exec", "\x03\nrI(\x01\x15\x01-\x06\a\n\x01\x03\x01\r"}, + {"os/exec/internal/fdtest", "\xd0\x02"}, + {"os/signal", "\r\xa7\x02\x15\x05\x02"}, + {"os/user", "\x02\x01|\x03\x84\x01.\r\n\x01\x02"}, + {"path", "\x7f*\xb8\x01"}, + {"path/filepath", "\x7f*\x1aD-\r\b\x03\x04\x11"}, + {"plugin", "\x7f"}, + {"reflect", "\x7f&\x04\x1e\x03\x11\b\x04\x05\x17\x06\t/\n\x03\x11\x02\x02"}, {"reflect/internal/example1", ""}, {"reflect/internal/example2", ""}, - {"regexp", "\x03\x82\x02\x037\t\x02\x01\x02\x11\x02"}, - {"regexp/syntax", "\xc8\x02\x01\x01\x01\x02\x11\x02"}, - {"runtime", "\xa4\x01\x04\x01\x03\f\x06\b\x02\x01\x01\x0f\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18N"}, - {"runtime/coverage", "\xb0\x01U"}, - {"runtime/debug", "\x81\x01V\\\r\b\x02\x01\x11\x06"}, - {"runtime/metrics", "\xc8\x01I/\""}, - {"runtime/pprof", "\x02\x01\x01\x03\x06c\x0e\x03#5\v!\f\"\r\b\x01\x01\x01\x02\x02\n\x03\x06"}, - {"runtime/race", "\xc6\x02"}, + {"regexp", "\x03\x83\x02\x037\t\x02\x01\x02\x11\x02"}, + {"regexp/syntax", "\xc9\x02\x01\x01\x01\x02\x11\x02"}, + {"runtime", "\xa5\x01\x04\x01\x03\f\x06\b\x02\x01\x01\x0f\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18N"}, + {"runtime/coverage", "\xb1\x01U"}, + {"runtime/debug", "\x82\x01V\\\r\b\x02\x01\x11\x06"}, + {"runtime/metrics", "\xc9\x01I/\""}, + {"runtime/pprof", "\x02\x01\x01\x03\x06d\x0e\x03#5\v!\f\"\r\b\x01\x01\x01\x02\x02\n\x03\x06"}, + {"runtime/race", "\xc7\x02"}, {"runtime/race/internal/amd64v1", ""}, - {"runtime/trace", "\rq\x03{\t;\b\x05\x01\x0e\x06"}, - {"slices", "\x04\x84\x02\fN"}, - {"sort", "\xdb\x0194"}, - {"strconv", "~*C\x01t"}, - {"strings", "~&\x04D\x19\x03\f9\x11\x02\x02"}, + {"runtime/trace", "\rr\x03{\t;\b\x05\x01\x0e\x06"}, + {"slices", "\x04\x85\x02\fN"}, + {"sort", "\xdc\x0194"}, + {"strconv", "\x7f*C\x01t"}, + {"strings", "\x7f&\x04D\x19\x03\f9\x11\x02\x02"}, {"structs", ""}, - {"sync", "\xda\x01\x02\x11\x01R\x0e\x14"}, - {"sync/atomic", "\xe2\x02"}, - {"syscall", "~'\x03\x01\x1d\n\x04\x06\r\x04U\b\x05\x01\x14"}, - {"testing", "\x03\nq\x02\x01Y\x17\x14\f\x05\x1d\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"}, - {"testing/cryptotest", "SV\\\x126\x03\x12"}, - {"testing/fstest", "~\x03\x84\x01\x01\n(\x10\x03\t\b"}, - {"testing/internal/testdeps", "\x02\v\xb7\x011\x10.\x03\x05\x03\x06\a\x02\x0f"}, - {"testing/iotest", "\x03{\x03\x84\x01\x04"}, - {"testing/quick", "\x80\x01\x01\x90\x01\x05%\x10\x11"}, - {"testing/slogtest", "\rq\x03\x8a\x010\x05\x10\f"}, - {"testing/synctest", "\xee\x01b\f\x06"}, - {"text/scanner", "\x03~\x84\x01.+\x02"}, - {"text/tabwriter", "\x81\x01\x84\x01["}, - {"text/template", "~\x03BB\x01\n\"\x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"}, - {"text/template/parse", "\x03~\xbf\x01\n\x01\x13\x02"}, - {"time", "~*D(,\r\x02\x13"}, - {"time/tzdata", "~\xd1\x01\x13"}, + {"sync", "\xdb\x01\x02\x11\x01R\x0e\x14"}, + {"sync/atomic", "\xe3\x02"}, + {"syscall", "\x7f'\x03\x01\x1d\n\x04\x06\r\x04U\b\x05\x01\x14"}, + {"testing", "\x03\nr\x02\x01Y\x17\x14\f\x05\x1d\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"}, + {"testing/cryptotest", "TV\\\x126\x03\x12"}, + {"testing/fstest", "\x7f\x03\x84\x01\x01\n(\x10\x03\t\b"}, + {"testing/internal/testdeps", "\x02\v\xb8\x011\x10.\x03\x05\x03\x06\a\x02\x0f"}, + {"testing/iotest", "\x03|\x03\x84\x01\x04"}, + {"testing/quick", "\x81\x01\x01\x90\x01\x05%\x10\x11"}, + {"testing/slogtest", "\rr\x03\x8a\x010\x05\x10\f"}, + {"testing/synctest", "\xef\x01b\f\x06"}, + {"text/scanner", "\x03\x7f\x84\x01.+\x02"}, + {"text/tabwriter", "\x82\x01\x84\x01["}, + {"text/template", "\x7f\x03BB\x01\n\"\x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"}, + {"text/template/parse", "\x03\x7f\xbf\x01\n\x01\x13\x02"}, + {"time", "\x7f*D(,\r\x02\x13"}, + {"time/tzdata", "\x7f\xd1\x01\x13"}, {"unicode", ""}, {"unicode/utf16", ""}, {"unicode/utf8", ""}, - {"unique", "\xa4\x01\"&\x01S\r\x01\x14\x19"}, + {"unique", "\xa5\x01\"&\x01S\r\x01\x14\x19"}, {"unsafe", ""}, - {"uuid", "\x03\x01O\x1d\x03\v\xcf\x01\x0f"}, - {"vendor/golang.org/x/crypto/chacha20", "\x10`\x0e\x96\x01,)"}, - {"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aY\x0e\xe6\x01\x05\x01\f"}, - {"vendor/golang.org/x/crypto/cryptobyte", "m\x11\x03\x91\x01)!\v"}, + {"uuid", "\x03\x01P\x1d\x03\v\xcf\x01\x0f"}, + {"vendor/golang.org/x/crypto/chacha20", "\x10a\x0e\x96\x01,)"}, + {"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aZ\x0e\xe6\x01\x05\x01\f"}, + {"vendor/golang.org/x/crypto/cryptobyte", "n\x11\x03\x91\x01)!\v"}, {"vendor/golang.org/x/crypto/cryptobyte/asn1", ""}, - {"vendor/golang.org/x/crypto/hkdf", "\x18\x01e\x15r"}, - {"vendor/golang.org/x/crypto/internal/alias", "\xe2\x02"}, - {"vendor/golang.org/x/crypto/internal/poly1305", "Z\x16\xa4\x01"}, - {"vendor/golang.org/x/net/dns/dnsmessage", "~\xca\x01"}, - {"vendor/golang.org/x/net/http/httpguts", "\x9b\x02\x16\x1a\x15\x10"}, - {"vendor/golang.org/x/net/http/httpproxy", "~\x03\x9a\x01\x12\x05\x01\x18\x15\x10"}, - {"vendor/golang.org/x/net/http2/hpack", "\x03{\x03\x84\x01H"}, - {"vendor/golang.org/x/net/http3", "\x9c\x02@\x06\x0f\x04"}, - {"vendor/golang.org/x/net/idna", "\x81\x01\x90\x01:\x13\x02\x17\x02\x01"}, - {"vendor/golang.org/x/net/internal/http3", "\rN#\x03\x84\x01\v\x04\a\x01\x05\x10\x01\x16\x02\x01\x02\x0f\x10\x02\x04\x03"}, - {"vendor/golang.org/x/net/internal/httpcommon", "\rq\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"}, - {"vendor/golang.org/x/net/internal/quic/quicwire", "p"}, - {"vendor/golang.org/x/net/nettest", "\x03m\x0e\x03\x84\x01\x11\x05\x18\x01\f\n\x01\x02\x02\x01\f"}, - {"vendor/golang.org/x/net/quic", "\x03\n\x01\x01\x01\t:\x04\x04\x15\x03\v\x03\x12r\x06\x06\x06\x04\x12\x06\x15\x02\x01\x02\x01\x01\r\x06\x02\x01\x01\x02\v"}, - {"vendor/golang.org/x/sys/cpu", "\xb3\x02\r\n\x01\x17"}, - {"vendor/golang.org/x/text/secure/bidirule", "~\xe2\x01\x18\x01"}, - {"vendor/golang.org/x/text/transform", "\x03{\x87\x01["}, - {"vendor/golang.org/x/text/unicode/bidi", "\x03\bv\x88\x01@\x17"}, - {"vendor/golang.org/x/text/unicode/norm", "p\x11\x84\x01H\x13\x18"}, - {"weak", "\xa4\x01\x9c\x01\""}, + {"vendor/golang.org/x/crypto/hkdf", "\x18\x01f\x15r"}, + {"vendor/golang.org/x/crypto/internal/alias", "\xe3\x02"}, + {"vendor/golang.org/x/crypto/internal/poly1305", "[\x16\xa4\x01"}, + {"vendor/golang.org/x/net/dns/dnsmessage", "\x7f\xca\x01"}, + {"vendor/golang.org/x/net/http/httpguts", "\x9c\x02\x16\x1a\x15\x10"}, + {"vendor/golang.org/x/net/http/httpproxy", "\x7f\x03\x9a\x01\x12\x05\x01\x18\x15\x10"}, + {"vendor/golang.org/x/net/http2/hpack", "\x03|\x03\x84\x01H"}, + {"vendor/golang.org/x/net/http3", "\x9d\x02@\x06\x0f\x04"}, + {"vendor/golang.org/x/net/idna", "\x82\x01\x90\x01:\x13\x02\x17\x02\x01"}, + {"vendor/golang.org/x/net/internal/http3", "\rO#\x03\x84\x01\v\x04\a\x01\x05\x10\x01\x16\x02\x01\x02\x0f\x10\x02\x04\x03"}, + {"vendor/golang.org/x/net/internal/httpcommon", "\rr\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"}, + {"vendor/golang.org/x/net/internal/quic/quicwire", "q"}, + {"vendor/golang.org/x/net/nettest", "\x03n\x0e\x03\x84\x01\x11\x05\x18\x01\f\n\x01\x02\x02\x01\f"}, + {"vendor/golang.org/x/net/quic", "\x03\n\x01\x01\x01\t;\x04\x04\x15\x03\v\x03\x12r\x06\x06\x06\x04\x12\x06\x15\x02\x01\x02\x01\x01\r\x06\x02\x01\x01\x02\v"}, + {"vendor/golang.org/x/sys/cpu", "\xb4\x02\r\n\x01\x17"}, + {"vendor/golang.org/x/text/secure/bidirule", "\x7f\xe2\x01\x18\x01"}, + {"vendor/golang.org/x/text/transform", "\x03|\x87\x01["}, + {"vendor/golang.org/x/text/unicode/bidi", "\x03\bw\x88\x01@\x17"}, + {"vendor/golang.org/x/text/unicode/norm", "q\x11\x84\x01H\x13\x18"}, + {"weak", "\xa5\x01\x9c\x01\""}, } // bootstrap is the list of bootstrap packages extracted from cmd/dist. diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go index 2180c296ec0..e11abf04553 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go +++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go @@ -9153,6 +9153,7 @@ var PackageSymbols = map[string][]Symbol{ {"CrossOriginProtection", Type, 25, ""}, {"DefaultClient", Var, 0, ""}, {"DefaultMaxHeaderBytes", Const, 0, ""}, + {"DefaultMaxHeaderValueCount", Const, 27, ""}, {"DefaultMaxIdleConnsPerHost", Const, 0, ""}, {"DefaultServeMux", Var, 0, ""}, {"DefaultTransport", Var, 0, ""}, @@ -9317,6 +9318,7 @@ var PackageSymbols = map[string][]Symbol{ {"Server.Handler", Field, 0, ""}, {"Server.IdleTimeout", Field, 8, ""}, {"Server.MaxHeaderBytes", Field, 0, ""}, + {"Server.MaxHeaderValueCount", Field, 27, ""}, {"Server.Protocols", Field, 24, ""}, {"Server.ReadHeaderTimeout", Field, 8, ""}, {"Server.ReadTimeout", Field, 0, ""}, diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 29d332e7b67..33344812746 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -150,8 +150,18 @@ var ( // throttling limit if unforeseen issues arise, and it will be removed in a // future release. // - // TODO: Remove this env var once v1.83.0 is release. + // TODO: Remove this env var once v1.83.0 is released. ControlBufferThrottleLimit = uint64FromEnv("GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT", 100, 1, 10000) + + // EnableReceiveBufferCompaction enables the compaction of data buffers + // to reduce the number of buffers in the receive buffer. + // + // This environment variable serves as an escape hatch to disable the + // feature if unforeseen issues arise, and it will be removed in a future + // release. + // + // TODO: Remove this env var once v1.85.0 is released. + EnableReceiveBufferCompaction = boolFromEnv("GRPC_GO_EXPERIMENTAL_ENABLE_RECEIVE_BUFFER_COMPACTION", true) ) func boolFromEnv(envVar string, def bool) bool { diff --git a/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go b/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go index 2d83b2eced1..00aeca419fe 100644 --- a/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go +++ b/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go @@ -26,12 +26,26 @@ import ( "slices" "sort" "sync" + + "google.golang.org/grpc/internal" ) const ( goPageSize = 4 * 1024 // 4KiB. N.B. this must be a power of 2. ) +var ( + // BufferPoolingThreshold is the minimum size of a buffer that can be pooled. + // This is used to determine whether to pool buffers or allocate them directly. + BufferPoolingThreshold = 1 << 10 +) + +func init() { + internal.SetBufferPoolingThresholdForTesting = func(threshold int) { + BufferPoolingThreshold = threshold + } +} + var uintSize = bits.UintSize // use a variable for mocking during tests. // bufferPool is a copy of the public bufferPool interface used to avoid diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index a8356c9adbc..9cd8d28d33e 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -424,7 +424,7 @@ func (ht *serverHandlerTransport) HandleStreams(ctx context.Context, startStream st: ht, headerWireLength: 0, // won't have access to header wire length until golang/go#18997. } - s.Stream.buf.init() + s.Stream.buf.init(ht.bufferPool) s.readRequester = s s.trReader = transportReader{ reader: recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: &s.buf}, diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index c19b45080e1..10d19774159 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -500,7 +500,7 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr, handler s headerChan: make(chan struct{}), statsHandler: handler, } - s.Stream.buf.init() + s.Stream.buf.init(t.bufferPool) s.Stream.wq.init(defaultWriteQuota, s.done) s.readRequester = s // The client side stream context should have exactly the same life cycle with the user provided context. diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index be8ae9f9c54..63c6539a3d3 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -407,7 +407,7 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade st: t, headerWireLength: int(frame.Header().Length), } - s.Stream.buf.init() + s.Stream.buf.init(t.bufferPool) var ( // if false, content-type was missing or invalid isGRPC = false diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index d2e49538f0b..5fc901e5cf1 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -30,11 +30,14 @@ import ( "sync" "sync/atomic" "time" + "unsafe" "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/envconfig" + imem "google.golang.org/grpc/internal/mem" "google.golang.org/grpc/internal/transport/internal" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/mem" @@ -45,7 +48,30 @@ import ( "google.golang.org/grpc/tap" ) -const logLevel = 2 +const ( + logLevel = 2 + // recvMsgSize estimates the memory overhead of a recvMsg in the backlog. + // It accounts for the recvMsg struct itself and the slice header of the + // underlying buffer's data. + recvMsgSize = int(unsafe.Sizeof(recvMsg{}) + unsafe.Sizeof([]byte{})) + + // utilizationFactor controls when we consider memory utilization acceptable. + // When backlogHeapSize / payloadSize <= utilizationFactor (meaning at least + // 50% of the heap memory is actual payload data), compaction is skipped. + utilizationFactor = 2 +) + +var ( + // compactionThreshold is approx 57KB (on 64-bit systems). It allows + // accumulating up to 1024 1-byte payloads before triggering compaction. + // + // Because individual payloads <= 1024 bytes are allocated on the heap + // outside mem.BufferPool, waiting for at least 1024 bytes to accumulate + // ensures that compaction coalesces those small heap allocations into a + // single large buffer from mem.BufferPool, enabling buffer reuse while + // avoiding frequent copying for small bursts of frames. + compactionThreshold = imem.BufferPoolingThreshold * (recvMsgSize + 1) +) func init() { internal.TimeNowFunc = func() int64 { return time.Now().UnixNano() } @@ -71,23 +97,31 @@ type recvBuffer struct { c chan recvMsg mu sync.Mutex backlog []recvMsg - err error + // uncompactedSuffixLen tracks the number of consecutive data messages at + // the tail of backlog that have not been compacted. + uncompactedSuffixLen int + // uncompactedBytes tracks the total payload bytes across the trailing + // uncompactedSuffixLen messages. + uncompactedBytes int + err error + bufPool mem.BufferPool } // init allows a recvBuffer to be initialized in-place, which is useful // for resetting a buffer or for avoiding a heap allocation when the buffer // is embedded in another struct. -func (b *recvBuffer) init() { +func (b *recvBuffer) init(pool mem.BufferPool) { b.c = make(chan recvMsg, 1) + b.bufPool = pool } func (b *recvBuffer) put(r recvMsg) { b.mu.Lock() + defer b.mu.Unlock() if b.err != nil { // drop the buffer on the floor. Since b.err is not nil, any subsequent reads // will always return an error, making this buffer inaccessible. r.buffer.Free() - b.mu.Unlock() // An error had occurred earlier, don't accept more // data or errors. return @@ -96,13 +130,70 @@ func (b *recvBuffer) put(r recvMsg) { if len(b.backlog) == 0 { select { case b.c <- r: - b.mu.Unlock() return default: } } b.backlog = append(b.backlog, r) - b.mu.Unlock() + b.compactBacklogLocked(r) +} + +func (b *recvBuffer) compactBacklogLocked(r recvMsg) { + if !envconfig.EnableReceiveBufferCompaction { + return + } + if r.buffer == nil { + b.uncompactedBytes = 0 + b.uncompactedSuffixLen = 0 + return + } + + b.uncompactedSuffixLen++ + b.uncompactedBytes += r.buffer.Len() + backlogHeapSize := b.uncompactedSuffixLen*recvMsgSize + b.uncompactedBytes + + // If the memory overhead is less than 50% of the heap usage (e.g., because + // a large DATA frame arrived), the average message size in the suffix is + // large enough that memory bloat is not a concern. Reset suffix tracking. + if backlogHeapSize <= utilizationFactor*b.uncompactedBytes { + b.uncompactedBytes = 0 + b.uncompactedSuffixLen = 0 + return + } + // Avoid compacting too frequently for short bursts of small frames. + // Wait until we have accumulated at least ~1024 small messages (~57 KB). + if backlogHeapSize <= compactionThreshold { + // Still can accumulate more payloads. + return + } + + // Since the memory utilization is less than 50%, the average payload size + // of each recvMsg must be less than recvMsgSize (approx 56 bytes). + // In the worst case for bytes copied (where the average payload is just + // below recvMsgSize), compaction will occur once every: + // compactionThreshold / (recvMsgSize + avg_payload) = ~520 messages, + // copying ~29KB of data. + + start := 0 + newBuf := b.bufPool.Get(b.uncompactedBytes) + startIdx := len(b.backlog) - b.uncompactedSuffixLen + + for i := startIdx; i < len(b.backlog); i++ { + m := b.backlog[i] + b.backlog[i] = recvMsg{} + start += copy((*newBuf)[start:], m.buffer.ReadOnlyData()) + m.buffer.Free() + } + b.backlog[startIdx] = recvMsg{ + buffer: mem.NewBuffer(newBuf, b.bufPool), + } + b.backlog = b.backlog[:startIdx+1] + // After compaction, the suffix is replaced with a single message containing + // the combined payload. The new utilization is close to 1.0 (overhead of + // one recvMsg relative to the large compacted payload), which is well + // below the utilization factor of 2. + b.uncompactedBytes = 0 + b.uncompactedSuffixLen = 0 } func (b *recvBuffer) load() { @@ -110,6 +201,13 @@ func (b *recvBuffer) load() { if len(b.backlog) > 0 { select { case b.c <- b.backlog[0]: + // backlog[0] is only part of the tracked uncompacted suffix if the + // entire backlog currently consists of the suffix. If an earlier + // compaction or reset occurred, backlog[0] is already compacted. + if envconfig.EnableReceiveBufferCompaction && b.uncompactedSuffixLen == len(b.backlog) { + b.uncompactedSuffixLen-- + b.uncompactedBytes -= b.backlog[0].buffer.Len() + } b.backlog[0] = recvMsg{} b.backlog = b.backlog[1:] default: diff --git a/vendor/google.golang.org/grpc/internal/xds/httpfilter/rbac/rbac.go b/vendor/google.golang.org/grpc/internal/xds/httpfilter/rbac/rbac.go index eb42a7fb1ff..1af2c2065ba 100644 --- a/vendor/google.golang.org/grpc/internal/xds/httpfilter/rbac/rbac.go +++ b/vendor/google.golang.org/grpc/internal/xds/httpfilter/rbac/rbac.go @@ -32,6 +32,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" v3rbacpb "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" + v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" rpb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" ) @@ -68,36 +69,25 @@ func parseConfig(rbacCfg *rpb.RBAC) (httpfilter.FilterConfig, error) { } // "It is also a validation failure if Permission or Principal has a - // header matcher for a grpc- prefixed header name or :scheme." - A41 - for _, principal := range policy.Principals { - name := principal.GetHeader().GetName() - if name == ":scheme" || strings.HasPrefix(name, "grpc-") { - return nil, fmt.Errorf("rbac: principal header matcher for %v is :scheme or starts with grpc", name) + // header matcher for a grpc- prefixed header name or :scheme." - A41. + // + // "Envoy aliases :authority and Host in its header map implementation, + // so they should be treated equivalent for the RBAC matchers; there must + // be no behavior change depending on which of the two header names is + // used in the RBAC policy." - A41. Any header matcher with value "host" + // is rewritten to ":authority", as that is what grpc-go shifts both + // headers to in the transport layer. + // + // Both rules apply to header matchers nested inside and/or/not rules, so + // the whole permission and principal trees are walked. + for _, principal := range policy.GetPrincipals() { + if err := normalizePrincipalHeaders(principal); err != nil { + return nil, err } } - for _, permission := range policy.Permissions { - name := permission.GetHeader().GetName() - if name == ":scheme" || strings.HasPrefix(name, "grpc-") { - return nil, fmt.Errorf("rbac: permission header matcher for %v is :scheme or starts with grpc", name) - } - } - } - - // "Envoy aliases :authority and Host in its header map implementation, so - // they should be treated equivalent for the RBAC matchers; there must be no - // behavior change depending on which of the two header names is used in the - // RBAC policy." - A41. Loop through config's principals and policies, change - // any header matcher with value "host" to :authority", as that is what - // grpc-go shifts both headers to in transport layer. - for _, policy := range rbacCfg.GetRules().GetPolicies() { - for _, principal := range policy.Principals { - if principal.GetHeader().GetName() == "host" { - principal.GetHeader().Name = ":authority" - } - } - for _, permission := range policy.Permissions { - if permission.GetHeader().GetName() == "host" { - permission.GetHeader().Name = ":authority" + for _, permission := range policy.GetPermissions() { + if err := normalizePermissionHeaders(permission); err != nil { + return nil, err } } } @@ -126,6 +116,82 @@ func parseConfig(rbacCfg *rpb.RBAC) (httpfilter.FilterConfig, error) { return config{chainEngine: ce}, nil } +// normalizePermissionHeaders applies the A41 header-name rules to every header +// matcher reachable from permission, including those nested inside and/or/not +// rules. +func normalizePermissionHeaders(permission *v3rbacpb.Permission) error { + switch p := permission.GetRule().(type) { + case *v3rbacpb.Permission_Header: + return normalizeHeaderMatcher(p.Header) + case *v3rbacpb.Permission_AndRules: + for _, rule := range p.AndRules.GetRules() { + if err := normalizePermissionHeaders(rule); err != nil { + return err + } + } + case *v3rbacpb.Permission_OrRules: + for _, rule := range p.OrRules.GetRules() { + if err := normalizePermissionHeaders(rule); err != nil { + return err + } + } + case *v3rbacpb.Permission_NotRule: + return normalizePermissionHeaders(p.NotRule) + } + return nil +} + +// normalizePrincipalHeaders applies the A41 header-name rules to every header +// matcher reachable from principal, including those nested inside and/or/not +// ids. +func normalizePrincipalHeaders(principal *v3rbacpb.Principal) error { + switch p := principal.GetIdentifier().(type) { + case *v3rbacpb.Principal_Header: + return normalizeHeaderMatcher(p.Header) + case *v3rbacpb.Principal_AndIds: + for _, id := range p.AndIds.GetIds() { + if err := normalizePrincipalHeaders(id); err != nil { + return err + } + } + case *v3rbacpb.Principal_OrIds: + for _, id := range p.OrIds.GetIds() { + if err := normalizePrincipalHeaders(id); err != nil { + return err + } + } + case *v3rbacpb.Principal_NotId: + return normalizePrincipalHeaders(p.NotId) + } + return nil +} + +// normalizeHeaderMatcher lowercases the name of a header matcher, rejects the +// names that A41 forbids (:scheme or a grpc- prefixed name) and rewrites a +// "host" matcher to ":authority". +func normalizeHeaderMatcher(header *v3routepb.HeaderMatcher) error { + // The keys of the metadata the matchers run against are always lowercase, + // so a name that contains an uppercase character matches no header at all + // and the rule using it never fires. Lowercase the name, as Envoy and + // grpc-java do, both to make it match and to keep the checks below from + // being evaded by the case of the name. + name := header.GetName() + lowerName := strings.ToLower(name) + if lowerName != name { + header.Name = lowerName + } + if lowerName == ":scheme" { + return fmt.Errorf("rbac: header matcher for %q is %q", name, ":scheme") + } + if strings.HasPrefix(lowerName, "grpc-") { + return fmt.Errorf("rbac: header matcher for %q starts with %q", name, "grpc-") + } + if lowerName == "host" { + header.Name = ":authority" + } + return nil +} + func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) { if cfg == nil { return nil, fmt.Errorf("rbac: nil configuration message provided") diff --git a/vendor/google.golang.org/grpc/mem/buffer_pool.go b/vendor/google.golang.org/grpc/mem/buffer_pool.go index 3b02b909164..aa121379fd5 100644 --- a/vendor/google.golang.org/grpc/mem/buffer_pool.go +++ b/vendor/google.golang.org/grpc/mem/buffer_pool.go @@ -59,10 +59,6 @@ func init() { internal.SetDefaultBufferPool = func(pool BufferPool) { defaultBufferPool = pool } - - internal.SetBufferPoolingThresholdForTesting = func(threshold int) { - bufferPoolingThreshold = threshold - } } // DefaultBufferPool returns the current default buffer pool. It is a BufferPool diff --git a/vendor/google.golang.org/grpc/mem/buffers.go b/vendor/google.golang.org/grpc/mem/buffers.go index 2b410b16ebd..9b355d4465b 100644 --- a/vendor/google.golang.org/grpc/mem/buffers.go +++ b/vendor/google.golang.org/grpc/mem/buffers.go @@ -29,6 +29,8 @@ import ( "fmt" "sync" "sync/atomic" + + "google.golang.org/grpc/internal/mem" ) // A Buffer represents a reference counted piece of data (in bytes) that can be @@ -63,8 +65,6 @@ type Buffer interface { } var ( - bufferPoolingThreshold = 1 << 10 - bufferObjectPool = sync.Pool{New: func() any { return new(buffer) }} ) @@ -72,7 +72,7 @@ var ( // equal to the threshold for buffer pooling. This is used to determine whether // to pool buffers or allocate them directly. func IsBelowBufferPoolingThreshold(size int) bool { - return size <= bufferPoolingThreshold + return size <= mem.BufferPoolingThreshold } type buffer struct { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 4083c03908f..64ec3b3cfd0 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.83.0" +const Version = "1.83.1" diff --git a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go index 2ef36bbcf92..ec63689e725 100644 --- a/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go +++ b/vendor/google.golang.org/protobuf/encoding/protodelim/protodelim.go @@ -10,6 +10,7 @@ import ( "encoding/binary" "fmt" "io" + "math" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" @@ -117,7 +118,13 @@ func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error { if maxSize == 0 { maxSize = defaultMaxSize } - if maxSize != -1 && size > uint64(maxSize) { + if maxSize == -1 { + // No limit specified: Just check that size fits into an integer, + // otherwise the make([]byte, size) call below will panic. + if size > math.MaxInt { + return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: math.MaxInt}, "") + } + } else if size > uint64(maxSize) { return errors.Wrap(&SizeTooLargeError{Size: size, MaxSize: uint64(maxSize)}, "") } diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go index 737d6876d5e..1d6608dc7d5 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/decode.go @@ -365,6 +365,10 @@ func unmarshalInt(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getInt(tok, bitSize) } return protoreflect.Value{}, false @@ -397,6 +401,10 @@ func unmarshalUint(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getUint(tok, bitSize) } return protoreflect.Value{}, false @@ -447,6 +455,10 @@ func unmarshalFloat(tok json.Token, bitSize int) (protoreflect.Value, bool) { if err != nil { return protoreflect.Value{}, false } + // Ensure there is no non-number content in this string. + if next, err := dec.Read(); err != nil || next.Kind() != json.EOF { + return protoreflect.Value{}, false + } return getFloat(tok, bitSize) } return protoreflect.Value{}, false diff --git a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go index e9fe1039437..d2eab469474 100644 --- a/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +++ b/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go @@ -52,7 +52,10 @@ func wellKnownTypeMarshaler(name protoreflect.FullName) marshalFunc { case genid.FieldMask_message_name: return encoder.marshalFieldMask case genid.Empty_message_name: - return encoder.marshalEmpty + // The spec explicitly specifies that the Empty message + // is not considered to have any special JSON mapping: + // https://protobuf.dev/programming-guides/json/#any + return nil } } return nil diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index b53805056a9..20ec09e1948 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -8,6 +8,7 @@ import ( "fmt" "unicode/utf8" + "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/text" "google.golang.org/protobuf/internal/errors" @@ -49,12 +50,19 @@ type UnmarshalOptions struct { protoregistry.MessageTypeResolver protoregistry.ExtensionTypeResolver } + + // RecursionLimit limits how deeply messages may be nested. + // If zero, a default limit is applied. + RecursionLimit int } // Unmarshal reads the given []byte and populates the given [proto.Message] // using options in the UnmarshalOptions object. // The provided message must be mutable (e.g., a non-nil pointer to a message). func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error { + if o.RecursionLimit == 0 { + o.RecursionLimit = protowire.DefaultRecursionLimit + } return o.unmarshal(b, m) } @@ -102,8 +110,14 @@ func (d decoder) syntaxError(pos int, f string, x ...any) error { return errors.New(head+f, x...) } +var errRecursionDepth = errors.New("exceeded maximum recursion depth") + // unmarshalMessage unmarshals into the given protoreflect.Message. func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + messageDesc := m.Descriptor() if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { return errors.New("no support for proto1 MessageSets") @@ -437,6 +451,10 @@ func (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflec // unmarshalMap unmarshals into given protoreflect.Map. A map value is a // textproto message containing {key: , value: }. func (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error { + if d.opts.RecursionLimit--; d.opts.RecursionLimit < 0 { + return errRecursionDepth + } + // Determine ahead whether map entry is a scalar type or a message type in // order to call the appropriate unmarshalMapValue func inside // unmarshalMapEntry. diff --git a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go index 87e46bd4dfb..0b0dfacbe5a 100644 --- a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go +++ b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go @@ -83,12 +83,13 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { case protoreflect.FileImports: for i := 0; i < vs.Len(); i++ { var rs records - rv := reflect.ValueOf(vs.Get(i)) - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPublic"), "IsPublic"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, + fi := vs.Get(i) + rv := reflect.ValueOf(fi) + rs.Append(rv, []attrAndName{ + {fi.Path(), "Path"}, + {fi.Package(), "Package"}, + {fi.IsPublic, "IsPublic"}, + {fi.IsWeak, "IsWeak"}, }...) ss = append(ss, "{"+rs.Join()+"}") } @@ -104,9 +105,9 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } } -type methodAndName struct { - method reflect.Value - name string +type attrAndName struct { + attr any + name string } func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) { @@ -126,58 +127,58 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu start = rt.Name() + "{" } - _, isFile := t.(protoreflect.FileDescriptor) + fd, isFile := t.(protoreflect.FileDescriptor) rs := records{ allowMulti: allowMulti, record: record, } if t.IsPlaceholder() { if isFile { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {fd.Path(), "Path"}, + {fd.Package(), "Package"}, + {fd.IsPlaceholder(), "IsPlaceholder"}, }...) } else { - rs.Append(rv, []methodAndName{ - {rv.MethodByName("FullName"), "FullName"}, - {rv.MethodByName("IsPlaceholder"), "IsPlaceholder"}, + rs.Append(rv, []attrAndName{ + {t.FullName(), "FullName"}, + {t.IsPlaceholder(), "IsPlaceholder"}, }...) } } else { switch { case isFile: - rs.Append(rv, methodAndName{rv.MethodByName("Syntax"), "Syntax"}) + rs.Append(rv, attrAndName{fd.Syntax(), "Syntax"}) case isRoot: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Syntax"), "Syntax"}, - {rv.MethodByName("FullName"), "FullName"}, + rs.Append(rv, []attrAndName{ + {t.Syntax(), "Syntax"}, + {t.FullName(), "FullName"}, }...) default: - rs.Append(rv, methodAndName{rv.MethodByName("Name"), "Name"}) + rs.Append(rv, attrAndName{t.Name(), "Name"}) } switch t := t.(type) { case protoreflect.FieldDescriptor: - accessors := []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - {rv.MethodByName("Cardinality"), "Cardinality"}, - {rv.MethodByName("Kind"), "Kind"}, - {rv.MethodByName("HasJSONName"), "HasJSONName"}, - {rv.MethodByName("JSONName"), "JSONName"}, - {rv.MethodByName("HasPresence"), "HasPresence"}, - {rv.MethodByName("IsExtension"), "IsExtension"}, - {rv.MethodByName("IsPacked"), "IsPacked"}, - {rv.MethodByName("IsWeak"), "IsWeak"}, - {rv.MethodByName("IsList"), "IsList"}, - {rv.MethodByName("IsMap"), "IsMap"}, - {rv.MethodByName("MapKey"), "MapKey"}, - {rv.MethodByName("MapValue"), "MapValue"}, - {rv.MethodByName("HasDefault"), "HasDefault"}, - {rv.MethodByName("Default"), "Default"}, - {rv.MethodByName("ContainingOneof"), "ContainingOneof"}, - {rv.MethodByName("ContainingMessage"), "ContainingMessage"}, - {rv.MethodByName("Message"), "Message"}, - {rv.MethodByName("Enum"), "Enum"}, + accessors := []attrAndName{ + {t.Number(), "Number"}, + {t.Cardinality(), "Cardinality"}, + {t.Kind(), "Kind"}, + {t.HasJSONName(), "HasJSONName"}, + {t.JSONName(), "JSONName"}, + {t.HasPresence(), "HasPresence"}, + {t.IsExtension(), "IsExtension"}, + {t.IsPacked(), "IsPacked"}, + {t.IsWeak(), "IsWeak"}, + {t.IsList(), "IsList"}, + {t.IsMap(), "IsMap"}, + {t.MapKey(), "MapKey"}, + {t.MapValue(), "MapValue"}, + {t.HasDefault(), "HasDefault"}, + {t.Default(), "Default"}, + {t.ContainingOneof(), "ContainingOneof"}, + {t.ContainingMessage(), "ContainingMessage"}, + {t.Message(), "Message"}, + {t.Enum(), "Enum"}, } for _, s := range accessors { switch s.name { @@ -223,58 +224,54 @@ func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool, record fu } case protoreflect.FileDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Path"), "Path"}, - {rv.MethodByName("Package"), "Package"}, - {rv.MethodByName("Imports"), "Imports"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, - {rv.MethodByName("Services"), "Services"}, + rs.Append(rv, []attrAndName{ + {t.Path(), "Path"}, + {t.Package(), "Package"}, + {t.Imports(), "Imports"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, + {t.Services(), "Services"}, }...) case protoreflect.MessageDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("IsMapEntry"), "IsMapEntry"}, - {rv.MethodByName("Fields"), "Fields"}, - {rv.MethodByName("Oneofs"), "Oneofs"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("RequiredNumbers"), "RequiredNumbers"}, - {rv.MethodByName("ExtensionRanges"), "ExtensionRanges"}, - {rv.MethodByName("Messages"), "Messages"}, - {rv.MethodByName("Enums"), "Enums"}, - {rv.MethodByName("Extensions"), "Extensions"}, + rs.Append(rv, []attrAndName{ + {t.IsMapEntry(), "IsMapEntry"}, + {t.Fields(), "Fields"}, + {t.Oneofs(), "Oneofs"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.RequiredNumbers(), "RequiredNumbers"}, + {t.ExtensionRanges(), "ExtensionRanges"}, + {t.Messages(), "Messages"}, + {t.Enums(), "Enums"}, + {t.Extensions(), "Extensions"}, }...) case protoreflect.EnumDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Values"), "Values"}, - {rv.MethodByName("ReservedNames"), "ReservedNames"}, - {rv.MethodByName("ReservedRanges"), "ReservedRanges"}, - {rv.MethodByName("IsClosed"), "IsClosed"}, + rs.Append(rv, []attrAndName{ + {t.Values(), "Values"}, + {t.ReservedNames(), "ReservedNames"}, + {t.ReservedRanges(), "ReservedRanges"}, + {t.IsClosed(), "IsClosed"}, }...) case protoreflect.EnumValueDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Number"), "Number"}, - }...) + rs.Append(rv, attrAndName{t.Number(), "Number"}) case protoreflect.ServiceDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Methods"), "Methods"}, - }...) + rs.Append(rv, attrAndName{t.Methods(), "Methods"}) case protoreflect.MethodDescriptor: - rs.Append(rv, []methodAndName{ - {rv.MethodByName("Input"), "Input"}, - {rv.MethodByName("Output"), "Output"}, - {rv.MethodByName("IsStreamingClient"), "IsStreamingClient"}, - {rv.MethodByName("IsStreamingServer"), "IsStreamingServer"}, + rs.Append(rv, []attrAndName{ + {t.Input(), "Input"}, + {t.Output(), "Output"}, + {t.IsStreamingClient(), "IsStreamingClient"}, + {t.IsStreamingServer(), "IsStreamingServer"}, }...) } - if m := rv.MethodByName("GoType"); m.IsValid() { - rs.Append(rv, methodAndName{m, "GoType"}) + if m, ok := t.(interface{ GoType() reflect.Type }); ok { + rs.Append(rv, attrAndName{m.GoType(), "GoType"}) } } return start + rs.Join() + end @@ -297,68 +294,66 @@ func (rs *records) AppendRecs(fieldName string, newRecs [2]string) { rs.recs = append(rs.recs, newRecs) } -func (rs *records) Append(v reflect.Value, accessors ...methodAndName) { - for _, a := range accessors { - if rs.record != nil { - rs.record(a.name) - } - var rv reflect.Value - if a.method.IsValid() { - rv = a.method.Call(nil)[0] - } - if v.Kind() == reflect.Struct && !rv.IsValid() { - rv = v.FieldByName(a.name) - } - if !rv.IsValid() { - panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a.name)) - } - if _, ok := rv.Interface().(protoreflect.Value); ok { - rv = rv.MethodByName("Interface").Call(nil)[0] - if !rv.IsNil() { - rv = rv.Elem() - } - } +func (rs *records) Append(v reflect.Value, results ...attrAndName) { + for _, r := range results { + rs.appendAttribute(v, r.name, r.attr) + } +} - // Ignore zero values. - var isZero bool - switch rv.Kind() { - case reflect.Interface, reflect.Slice: - isZero = rv.IsNil() - case reflect.Bool: - isZero = rv.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - isZero = rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - isZero = rv.Uint() == 0 - case reflect.String: - isZero = rv.String() == "" - } - if n, ok := rv.Interface().(list); ok { - isZero = n.Len() == 0 - } - if isZero { - continue +func (rs *records) appendAttribute(val reflect.Value, name string, attrVal any) { + if rs.record != nil { + rs.record(name) + } + if attrVal == nil { + return + } + rv := reflect.ValueOf(attrVal) + if _, ok := rv.Interface().(protoreflect.Value); ok { + rv = rv.MethodByName("Interface").Call(nil)[0] + if !rv.IsNil() { + rv = rv.Elem() } + } - // Format the value. - var s string - v := rv.Interface() - switch v := v.(type) { - case list: - s = formatListOpt(v, false, rs.allowMulti) - case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: - s = string(v.(protoreflect.Descriptor).Name()) - case protoreflect.Descriptor: - s = string(v.FullName()) - case string: - s = strconv.Quote(v) - case []byte: - s = fmt.Sprintf("%q", v) - default: - s = fmt.Sprint(v) - } - rs.recs = append(rs.recs, [2]string{a.name, s}) + // Ignore zero values. + var isZero bool + switch rv.Kind() { + case reflect.Interface, reflect.Slice: + isZero = rv.IsNil() + case reflect.Bool: + isZero = rv.Bool() == false + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + isZero = rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + isZero = rv.Uint() == 0 + case reflect.String: + isZero = rv.String() == "" + } + if n, ok := rv.Interface().(list); ok { + isZero = n.Len() == 0 + } + if isZero { + return + } + + // Format the value. + var s string + v := rv.Interface() + switch v := v.(type) { + case list: + s = formatListOpt(v, false, rs.allowMulti) + case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: + s = string(v.(protoreflect.Descriptor).Name()) + case protoreflect.Descriptor: + s = string(v.FullName()) + case string: + s = strconv.Quote(v) + case []byte: + s = fmt.Sprintf("%q", v) + default: + s = fmt.Sprint(v) } + rs.recs = append(rs.recs, [2]string{name, s}) } func (rs *records) Join() string { diff --git a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb index 04696351eee..ad35ea4c449 100644 Binary files a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb and b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb differ diff --git a/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go b/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go index 328dc733b04..079a53dd15a 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go @@ -69,19 +69,19 @@ func Unmarshal(s string, k protoreflect.Kind, evs protoreflect.EnumValueDescript } } case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - if v, err := strconv.ParseInt(s, 10, 32); err == nil { + if v, err := strconv.ParseInt(s, 0, 32); err == nil { return protoreflect.ValueOfInt32(int32(v)), nil, nil } case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - if v, err := strconv.ParseInt(s, 10, 64); err == nil { + if v, err := strconv.ParseInt(s, 0, 64); err == nil { return protoreflect.ValueOfInt64(int64(v)), nil, nil } case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - if v, err := strconv.ParseUint(s, 10, 32); err == nil { + if v, err := strconv.ParseUint(s, 0, 32); err == nil { return protoreflect.ValueOfUint32(uint32(v)), nil, nil } case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - if v, err := strconv.ParseUint(s, 10, 64); err == nil { + if v, err := strconv.ParseUint(s, 0, 64); err == nil { return protoreflect.ValueOfUint64(uint64(v)), nil, nil } case protoreflect.FloatKind, protoreflect.DoubleKind: diff --git a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go index 65aaf4d210a..58aeff8456d 100644 --- a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go +++ b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go @@ -26,6 +26,7 @@ const ( Edition_EDITION_PROTO3_enum_value = 999 Edition_EDITION_2023_enum_value = 1000 Edition_EDITION_2024_enum_value = 1001 + Edition_EDITION_2026_enum_value = 1002 Edition_EDITION_UNSTABLE_enum_value = 9999 Edition_EDITION_1_TEST_ONLY_enum_value = 1 Edition_EDITION_2_TEST_ONLY_enum_value = 2 @@ -806,11 +807,13 @@ const ( FieldOptions_FeatureSupport_EditionDeprecated_field_name protoreflect.Name = "edition_deprecated" FieldOptions_FeatureSupport_DeprecationWarning_field_name protoreflect.Name = "deprecation_warning" FieldOptions_FeatureSupport_EditionRemoved_field_name protoreflect.Name = "edition_removed" + FieldOptions_FeatureSupport_RemovalError_field_name protoreflect.Name = "removal_error" FieldOptions_FeatureSupport_EditionIntroduced_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_introduced" FieldOptions_FeatureSupport_EditionDeprecated_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_deprecated" FieldOptions_FeatureSupport_DeprecationWarning_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.deprecation_warning" FieldOptions_FeatureSupport_EditionRemoved_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_removed" + FieldOptions_FeatureSupport_RemovalError_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.removal_error" ) // Field numbers for google.protobuf.FieldOptions.FeatureSupport. @@ -819,6 +822,7 @@ const ( FieldOptions_FeatureSupport_EditionDeprecated_field_number protoreflect.FieldNumber = 2 FieldOptions_FeatureSupport_DeprecationWarning_field_number protoreflect.FieldNumber = 3 FieldOptions_FeatureSupport_EditionRemoved_field_number protoreflect.FieldNumber = 4 + FieldOptions_FeatureSupport_RemovalError_field_number protoreflect.FieldNumber = 5 ) // Names for google.protobuf.OneofOptions. @@ -1152,6 +1156,7 @@ const ( FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN_enum_value = 0 FeatureSet_STYLE2024_enum_value = 1 FeatureSet_STYLE_LEGACY_enum_value = 2 + FeatureSet_STYLE2026_enum_value = 3 ) // Names for google.protobuf.FeatureSet.VisibilityFeature. diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 763fd82841c..58ff0e24644 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -52,7 +52,7 @@ import ( const ( Major = 1 Minor = 36 - Patch = 11 + Patch = 12 PreRelease = "" ) diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go index c826ad04303..84a3228edb4 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go @@ -201,6 +201,7 @@ func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescript return nil, err } x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures()) + x.L2.IsProto3Optional = xd.GetProto3Optional() if opts := xd.GetOptions(); opts != nil { opts = proto.Clone(opts).(*descriptorpb.FieldOptions) x.L2.Options = func() protoreflect.ProtoMessage { return opts } diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go index 730331e6668..86f0d092620 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go @@ -546,6 +546,8 @@ func (p *SourcePath) appendFieldOptions_FeatureSupport(b []byte) []byte { b = p.appendSingularField(b, "deprecation_warning", nil) case 4: b = p.appendSingularField(b, "edition_removed", nil) + case 5: + b = p.appendSingularField(b, "removal_error", nil) } return b } diff --git a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go index 0b23faa957c..a51cb1e546c 100644 --- a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go +++ b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ +// Copyright 2008 Google LLC. All rights reserved. // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd // Author: kenton@google.com (Kenton Varda) // Based on original Protocol Buffers design by @@ -69,6 +46,7 @@ const ( // comparison. Edition_EDITION_2023 Edition = 1000 Edition_EDITION_2024 Edition = 1001 + Edition_EDITION_2026 Edition = 1002 // A placeholder edition for developing and testing unscheduled features. Edition_EDITION_UNSTABLE Edition = 9999 // Placeholder editions for testing feature resolution. These should not be @@ -93,6 +71,7 @@ var ( 999: "EDITION_PROTO3", 1000: "EDITION_2023", 1001: "EDITION_2024", + 1002: "EDITION_2026", 9999: "EDITION_UNSTABLE", 1: "EDITION_1_TEST_ONLY", 2: "EDITION_2_TEST_ONLY", @@ -108,6 +87,7 @@ var ( "EDITION_PROTO3": 999, "EDITION_2023": 1000, "EDITION_2024": 1001, + "EDITION_2026": 1002, "EDITION_UNSTABLE": 9999, "EDITION_1_TEST_ONLY": 1, "EDITION_2_TEST_ONLY": 2, @@ -1213,6 +1193,7 @@ const ( FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN FeatureSet_EnforceNamingStyle = 0 FeatureSet_STYLE2024 FeatureSet_EnforceNamingStyle = 1 FeatureSet_STYLE_LEGACY FeatureSet_EnforceNamingStyle = 2 + FeatureSet_STYLE2026 FeatureSet_EnforceNamingStyle = 3 ) // Enum value maps for FeatureSet_EnforceNamingStyle. @@ -1221,11 +1202,13 @@ var ( 0: "ENFORCE_NAMING_STYLE_UNKNOWN", 1: "STYLE2024", 2: "STYLE_LEGACY", + 3: "STYLE2026", } FeatureSet_EnforceNamingStyle_value = map[string]int32{ "ENFORCE_NAMING_STYLE_UNKNOWN": 0, "STYLE2024": 1, "STYLE_LEGACY": 2, + "STYLE2026": 3, } ) @@ -4204,8 +4187,11 @@ type FieldOptions_FeatureSupport struct { // this one, the last default assigned will be used, and proto files will // not be able to override it. EditionRemoved *Edition `protobuf:"varint,4,opt,name=edition_removed,json=editionRemoved,enum=google.protobuf.Edition" json:"edition_removed,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // The removal error text if this feature is used after the edition it was + // removed in. + RemovalError *string `protobuf:"bytes,5,opt,name=removal_error,json=removalError" json:"removal_error,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FieldOptions_FeatureSupport) Reset() { @@ -4266,6 +4252,13 @@ func (x *FieldOptions_FeatureSupport) GetEditionRemoved() Edition { return Edition_EDITION_UNKNOWN } +func (x *FieldOptions_FeatureSupport) GetRemovalError() string { + if x != nil && x.RemovalError != nil { + return *x.RemovalError + } + return "" +} + // The name of the uninterpreted option. Each string represents a segment in // a dot-separated name. is_extension is true iff a segment represents an // extension (denoted with parentheses in options specs in .proto files). @@ -4719,7 +4712,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\aoptions\x18\x03 \x01(\v2&.google.protobuf.ExtensionRangeOptionsR\aoptions\x1a7\n" + "\rReservedRange\x12\x14\n" + "\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n" + - "\x03end\x18\x02 \x01(\x05R\x03end\"\xcc\x04\n" + + "\x03end\x18\x02 \x01(\x05R\x03end\"\xd4\x04\n" + "\x15ExtensionRangeOptions\x12X\n" + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x12Y\n" + "\vdeclaration\x18\x02 \x03(\v22.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02R\vdeclaration\x127\n" + @@ -4735,7 +4728,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x11VerificationState\x12\x0f\n" + "\vDECLARATION\x10\x00\x12\x0e\n" + "\n" + - "UNVERIFIED\x10\x01*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xc1\x06\n" + + "UNVERIFIED\x10\x01*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xc1\x06\n" + "\x14FieldDescriptorProto\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" + "\x06number\x18\x03 \x01(\x05R\x06number\x12A\n" + @@ -4810,12 +4803,13 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "outputType\x128\n" + "\aoptions\x18\x04 \x01(\v2\x1e.google.protobuf.MethodOptionsR\aoptions\x120\n" + "\x10client_streaming\x18\x05 \x01(\b:\x05falseR\x0fclientStreaming\x120\n" + - "\x10server_streaming\x18\x06 \x01(\b:\x05falseR\x0fserverStreaming\"\xad\t\n" + + "\x10server_streaming\x18\x06 \x01(\b:\x05falseR\x0fserverStreaming\"\xfa\n" + + "\n" + "\vFileOptions\x12!\n" + "\fjava_package\x18\x01 \x01(\tR\vjavaPackage\x120\n" + - "\x14java_outer_classname\x18\b \x01(\tR\x12javaOuterClassname\x125\n" + + "\x14java_outer_classname\x18\b \x01(\tR\x12javaOuterClassname\x12\xf9\x01\n" + "\x13java_multiple_files\x18\n" + - " \x01(\b:\x05falseR\x11javaMultipleFiles\x12D\n" + + " \x01(\b:\x05falseB\xc1\x01\xb2\x01\xbd\x01\b\xe6\a \xe9\a*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.R\x11javaMultipleFiles\x12D\n" + "\x1djava_generate_equals_and_hash\x18\x14 \x01(\bB\x02\x18\x01R\x19javaGenerateEqualsAndHash\x12:\n" + "\x16java_string_check_utf8\x18\x1b \x01(\b:\x05falseR\x13javaStringCheckUtf8\x12S\n" + "\foptimize_for\x18\t \x01(\x0e2).google.protobuf.FileOptions.OptimizeMode:\x05SPEEDR\voptimizeFor\x12\x1d\n" + @@ -4840,7 +4834,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\fOptimizeMode\x12\t\n" + "\x05SPEED\x10\x01\x12\r\n" + "\tCODE_SIZE\x10\x02\x12\x10\n" + - "\fLITE_RUNTIME\x10\x03*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b*\x10+J\x04\b&\x10'R\x14php_generic_services\"\xf4\x03\n" + + "\fLITE_RUNTIME\x10\x03*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b*\x10+J\x04\b&\x10'R\x14php_generic_services\"\xfc\x03\n" + "\x0eMessageOptions\x12<\n" + "\x17message_set_wire_format\x18\x01 \x01(\b:\x05falseR\x14messageSetWireFormat\x12L\n" + "\x1fno_standard_descriptor_accessor\x18\x02 \x01(\b:\x05falseR\x1cnoStandardDescriptorAccessor\x12%\n" + @@ -4850,8 +4844,8 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\tmap_entry\x18\a \x01(\bR\bmapEntry\x12V\n" + "&deprecated_legacy_json_field_conflicts\x18\v \x01(\bB\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x127\n" + "\bfeatures\x18\f \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" + - "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\x06\x10\aJ\x04\b\b\x10\tJ\x04\b\t\x10\n" + - "\"\xa1\r\n" + + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\x06\x10\aJ\x04\b\b\x10\tJ\x04\b\t\x10\n" + + "\"\xce\r\n" + "\fFieldOptions\x12A\n" + "\x05ctype\x18\x01 \x01(\x0e2#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05ctype\x12\x16\n" + "\x06packed\x18\x02 \x01(\bR\x06packed\x12G\n" + @@ -4872,12 +4866,13 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x1aZ\n" + "\x0eEditionDefault\x122\n" + "\aedition\x18\x03 \x01(\x0e2\x18.google.protobuf.EditionR\aedition\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value\x1a\x96\x02\n" + + "\x05value\x18\x02 \x01(\tR\x05value\x1a\xbb\x02\n" + "\x0eFeatureSupport\x12G\n" + "\x12edition_introduced\x18\x01 \x01(\x0e2\x18.google.protobuf.EditionR\x11editionIntroduced\x12G\n" + "\x12edition_deprecated\x18\x02 \x01(\x0e2\x18.google.protobuf.EditionR\x11editionDeprecated\x12/\n" + "\x13deprecation_warning\x18\x03 \x01(\tR\x12deprecationWarning\x12A\n" + - "\x0fedition_removed\x18\x04 \x01(\x0e2\x18.google.protobuf.EditionR\x0eeditionRemoved\"/\n" + + "\x0fedition_removed\x18\x04 \x01(\x0e2\x18.google.protobuf.EditionR\x0eeditionRemoved\x12#\n" + + "\rremoval_error\x18\x05 \x01(\tR\fremovalError\"/\n" + "\x05CType\x12\n" + "\n" + "\x06STRING\x10\x00\x12\b\n" + @@ -4901,10 +4896,10 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n" + "\x16TARGET_TYPE_ENUM_ENTRY\x10\a\x12\x17\n" + "\x13TARGET_TYPE_SERVICE\x10\b\x12\x16\n" + - "\x12TARGET_TYPE_METHOD\x10\t*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x12\x10\x13\"\xac\x01\n" + + "\x12TARGET_TYPE_METHOD\x10\t*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x12\x10\x13\"\xb4\x01\n" + "\fOneofOptions\x127\n" + "\bfeatures\x18\x01 \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" + - "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xd1\x02\n" + + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xd9\x02\n" + "\vEnumOptions\x12\x1f\n" + "\vallow_alias\x18\x02 \x01(\bR\n" + "allowAlias\x12%\n" + @@ -4913,7 +4908,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "deprecated\x12V\n" + "&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\bB\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x127\n" + "\bfeatures\x18\a \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" + - "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x05\x10\x06\"\xd8\x02\n" + + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x05\x10\x06\"\xe0\x02\n" + "\x10EnumValueOptions\x12%\n" + "\n" + "deprecated\x18\x01 \x01(\b:\x05falseR\n" + @@ -4921,13 +4916,13 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\bfeatures\x18\x02 \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12(\n" + "\fdebug_redact\x18\x03 \x01(\b:\x05falseR\vdebugRedact\x12U\n" + "\x0ffeature_support\x18\x04 \x01(\v2,.google.protobuf.FieldOptions.FeatureSupportR\x0efeatureSupport\x12X\n" + - "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xd5\x01\n" + + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xdd\x01\n" + "\x0eServiceOptions\x127\n" + "\bfeatures\x18\" \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12%\n" + "\n" + "deprecated\x18! \x01(\b:\x05falseR\n" + "deprecated\x12X\n" + - "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\x99\x03\n" + + "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xa1\x03\n" + "\rMethodOptions\x12%\n" + "\n" + "deprecated\x18! \x01(\b:\x05falseR\n" + @@ -4939,7 +4934,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n" + "\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n" + "\n" + - "IDEMPOTENT\x10\x02*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\x9a\x03\n" + + "IDEMPOTENT\x10\x02*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\x9a\x03\n" + "\x13UninterpretedOption\x12A\n" + "\x04name\x18\x02 \x03(\v2-.google.protobuf.UninterpretedOption.NamePartR\x04name\x12)\n" + "\x10identifier_value\x18\x03 \x01(\tR\x0fidentifierValue\x12,\n" + @@ -4950,7 +4945,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x0faggregate_value\x18\b \x01(\tR\x0eaggregateValue\x1aJ\n" + "\bNamePart\x12\x1b\n" + "\tname_part\x18\x01 \x02(\tR\bnamePart\x12!\n" + - "\fis_extension\x18\x02 \x02(\bR\visExtension\"\x8e\x0f\n" + + "\fis_extension\x18\x02 \x02(\bR\visExtension\"\xae\x0f\n" + "\n" + "FeatureSet\x12\x91\x01\n" + "\x0efield_presence\x18\x01 \x01(\x0e2).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\bEXPLICIT\x18\x84\a\xa2\x01\r\x12\bIMPLICIT\x18\xe7\a\xa2\x01\r\x12\bEXPLICIT\x18\xe8\a\xb2\x01\x03\b\xe8\aR\rfieldPresence\x12l\n" + @@ -4960,8 +4955,8 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\x10message_encoding\x18\x05 \x01(\x0e2+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\a\xb2\x01\x03\b\xe8\aR\x0fmessageEncoding\x12\x82\x01\n" + "\vjson_format\x18\x06 \x01(\x0e2&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\a\xa2\x01\n" + "\x12\x05ALLOW\x18\xe7\a\xb2\x01\x03\b\xe8\aR\n" + - "jsonFormat\x12\xab\x01\n" + - "\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBI\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\x12\xb9\x01\n" + + "jsonFormat\x12\xbc\x01\n" + + "\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xa2\x01\x0e\x12\tSTYLE2026\x18\x8fN\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\x12\xb9\x01\n" + "\x19default_symbol_visibility\x18\b \x01(\x0e2E.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityB6\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\n" + "EXPORT_ALL\x18\x84\a\xa2\x01\x15\x12\x10EXPORT_TOP_LEVEL\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x17defaultSymbolVisibility\x1a\xa1\x01\n" + "\x11VisibilityFeature\"\x81\x01\n" + @@ -5001,11 +4996,12 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "JsonFormat\x12\x17\n" + "\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n" + "\x05ALLOW\x10\x01\x12\x16\n" + - "\x12LEGACY_BEST_EFFORT\x10\x02\"W\n" + + "\x12LEGACY_BEST_EFFORT\x10\x02\"f\n" + "\x12EnforceNamingStyle\x12 \n" + "\x1cENFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n" + "\tSTYLE2024\x10\x01\x12\x10\n" + - "\fSTYLE_LEGACY\x10\x02*\x06\b\xe8\a\x10\x8bN*\x06\b\x8bN\x10\x90N*\x06\b\x90N\x10\x91NJ\x06\b\xe7\a\x10\xe8\a\"\xef\x03\n" + + "\fSTYLE_LEGACY\x10\x02\x12\r\n" + + "\tSTYLE2026\x10\x03*\x06\b\xe8\a\x10\x8bN*\x06\b\x8bN\x10\x90N*\x06\b\x90N\x10\x91NJ\x06\b\xe7\a\x10\xe8\a\"\xef\x03\n" + "\x12FeatureSetDefaults\x12X\n" + "\bdefaults\x18\x01 \x03(\v2<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefaultR\bdefaults\x12A\n" + "\x0fminimum_edition\x18\x04 \x01(\x0e2\x18.google.protobuf.EditionR\x0eminimumEdition\x12A\n" + @@ -5037,14 +5033,15 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" + "\bSemantic\x12\b\n" + "\x04NONE\x10\x00\x12\a\n" + "\x03SET\x10\x01\x12\t\n" + - "\x05ALIAS\x10\x02*\xbe\x02\n" + + "\x05ALIAS\x10\x02*\xd1\x02\n" + "\aEdition\x12\x13\n" + "\x0fEDITION_UNKNOWN\x10\x00\x12\x13\n" + "\x0eEDITION_LEGACY\x10\x84\a\x12\x13\n" + "\x0eEDITION_PROTO2\x10\xe6\a\x12\x13\n" + "\x0eEDITION_PROTO3\x10\xe7\a\x12\x11\n" + "\fEDITION_2023\x10\xe8\a\x12\x11\n" + - "\fEDITION_2024\x10\xe9\a\x12\x15\n" + + "\fEDITION_2024\x10\xe9\a\x12\x11\n" + + "\fEDITION_2026\x10\xea\a\x12\x15\n" + "\x10EDITION_UNSTABLE\x10\x8fN\x12\x17\n" + "\x13EDITION_1_TEST_ONLY\x10\x01\x12\x17\n" + "\x13EDITION_2_TEST_ONLY\x10\x02\x12\x1d\n" + diff --git a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go index 1ff0d1494d4..510894f2b0d 100644 --- a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go @@ -128,120 +128,66 @@ import ( // `Any` contains an arbitrary serialized protocol buffer message along with a // URL that describes the type of the serialized message. // -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// // or ... -// if (any.isSameTypeAs(Foo.getDefaultInstance())) { -// foo = any.unpack(Foo.getDefaultInstance()); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := anypb.New(foo) -// if err != nil { -// ... -// } -// ... -// foo := &pb.Foo{} -// if err := any.UnmarshalTo(foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } +// In its binary encoding, an `Any` is an ordinary message; but in other wire +// forms like JSON, it has a special encoding. The format of the type URL is +// described on the `type_url` field. +// +// Protobuf APIs provide utilities to interact with `Any` values: +// +// - A 'pack' operation accepts a message and constructs a generic `Any` wrapper +// around it. +// - An 'unpack' operation reads the content of an `Any` message, either into an +// existing message or a new one. Unpack operations must check the type of the +// value they unpack against the declared `type_url`. +// - An 'is' operation decides whether an `Any` contains a message of the given +// type, i.e. whether it can 'unpack' that type. +// +// The JSON format representation of an `Any` follows one of these cases: +// +// - For types without special-cased JSON encodings, the JSON format +// representation of the `Any` is the same as that of the message, with an +// additional `@type` field which contains the type URL. +// - For types with special-cased JSON encodings (typically called 'well-known' +// types, listed in https://protobuf.dev/programming-guides/json/#any), the +// JSON format representation has a key `@type` which contains the type URL +// and a key `value` which contains the JSON-serialized value. +// +// The text format representation of an `Any` is like a message with one field +// whose name is the type URL in brackets. For example, an `Any` containing a +// `foo.Bar` message may be written `[type.googleapis.com/foo.Bar] { a: 2 }`. type Any struct { state protoimpl.MessageState `protogen:"open.v1"` - // A URL/resource name that uniquely identifies the type of the serialized - // protocol buffer message. This string must contain at least - // one "/" character. The last segment of the URL's path must represent - // the fully qualified name of the type (as in - // `path/google.protobuf.Duration`). The name should be in a canonical form - // (e.g., leading "." is not accepted). + // Identifies the type of the serialized Protobuf message with a URI reference + // consisting of a prefix ending in a slash and the fully-qualified type name. + // + // Example: type.googleapis.com/google.protobuf.StringValue // - // In practice, teams usually precompile into the binary all types that they - // expect it to use in the context of Any. However, for URLs which use the - // scheme `http`, `https`, or no scheme, one can optionally set up a type - // server that maps type URLs to message definitions as follows: + // This string must contain at least one `/` character, and the content after + // the last `/` must be the fully-qualified name of the type in canonical + // form, without a leading dot. Do not write a scheme on these URI references + // so that clients do not attempt to contact them. // - // - If no scheme is provided, `https` is assumed. - // - An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // - Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) + // The prefix is arbitrary and Protobuf implementations are expected to + // simply strip off everything up to and including the last `/` to identify + // the type. `type.googleapis.com/` is a common default prefix that some + // legacy implementations require. This prefix does not indicate the origin of + // the type, and URIs containing it are not expected to respond to any + // requests. // - // Note: this functionality is not currently available in the official - // protobuf release, and it is not used for type URLs beginning with - // type.googleapis.com. As of May 2023, there are no widely used type server - // implementations and no plans to implement one. + // All type URL strings must be legal URI references with the additional + // restriction (for the text format) that the content of the reference + // must consist only of alphanumeric characters, percent-encoded escapes, and + // characters in the following set (not including the outer backticks): + // `/-.~_!$&()*+,;=`. Despite our allowing percent encodings, implementations + // should not unescape them to prevent confusion with existing parsers. For + // example, `type.googleapis.com%2FFoo` should be rejected. // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. + // In the original design of `Any`, the possibility of launching a type + // resolution service at these type URLs was considered but Protobuf never + // implemented one and considers contacting these URLs to be problematic and + // a potential security issue. Do not attempt to contact type URLs. TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` - // Must be a valid serialized protocol buffer of the above specified type. + // Holds a Protobuf serialization of the type described by type_url. Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache diff --git a/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go b/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go index 91ee89a5cd9..4a0437911d9 100644 --- a/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go @@ -197,24 +197,22 @@ import ( // An implementation may provide options to override this default behavior for // repeated and message fields. // -// In order to reset a field's value to the default, the field must -// be in the mask and set to the default value in the provided resource. -// Hence, in order to reset all fields of a resource, provide a default -// instance of the resource and set all fields in the mask, or do -// not provide a mask as described below. -// -// If a field mask is not present on update, the operation applies to -// all fields (as if a field mask of all fields has been specified). -// Note that in the presence of schema evolution, this may mean that -// fields the client does not know and has therefore not filled into -// the request will be reset to their default. If this is unwanted -// behavior, a specific service may require a client to always specify -// a field mask, producing an error if not. -// -// As with get operations, the location of the resource which -// describes the updated values in the request message depends on the -// operation kind. In any case, the effect of the field mask is -// required to be honored by the API. +// Note that libraries which implement FieldMask resolution have various +// different behaviors in the face of empty masks or the special "*" mask. +// When implementing a service you should confirm these cases have the +// appropriate behavior in the underlying FieldMask library that you desire, +// and you may need to special case those cases in your application code if +// the underlying field mask library behavior differs from your intended +// service semantics. +// +// Update methods implementing https://google.aip.dev/134 +// - MUST support the special value * meaning "full replace" +// - MUST treat an omitted field mask as "replace fields which are present". +// +// Other methods implementing https://google.aip.dev/157 +// - SHOULD support the special value "*" to mean "get all". +// - MUST treat an omitted field mask to mean "get all", unless otherwise +// documented. // // ## Considerations for HTTP REST // diff --git a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go index 30411b72838..8325a504892 100644 --- a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go @@ -131,10 +131,15 @@ import ( unsafe "unsafe" ) -// `NullValue` is a singleton enumeration to represent the null value for the -// `Value` type union. +// Represents a JSON `null`. // -// The JSON representation for `NullValue` is JSON `null`. +// `NullValue` is a sentinel, using an enum with only one value to represent +// the null value for the `Value` type union. +// +// A field of type `NullValue` with any value other than `0` is considered +// invalid. Most ProtoJSON serializers will emit a Value with a `null_value` set +// as a JSON `null` regardless of the integer value, and so will round trip to +// a `0` value. type NullValue int32 const ( @@ -179,14 +184,19 @@ func (NullValue) EnumDescriptor() ([]byte, []int) { return file_google_protobuf_struct_proto_rawDescGZIP(), []int{0} } -// `Struct` represents a structured data value, consisting of fields -// which map to dynamically typed values. In some languages, `Struct` -// might be supported by a native representation. For example, in -// scripting languages like JS a struct is represented as an -// object. The details of that representation are described together -// with the proto support for the language. +// Represents a JSON object. +// +// An unordered key-value map, intending to perfectly capture the semantics of a +// JSON object. This enables parsing any arbitrary JSON payload as a message +// field in ProtoJSON format. +// +// This follows RFC 8259 guidelines for interoperable JSON: notably this type +// cannot represent large Int64 values or `NaN`/`Infinity` numbers, +// since the JSON format generally does not support those values in its number +// type. // -// The JSON representation for `Struct` is JSON object. +// If you do not intend to parse arbitrary JSON into your message, a custom +// typed message should be preferred instead of using this type. type Struct struct { state protoimpl.MessageState `protogen:"open.v1"` // Unordered map of dynamically typed values. @@ -269,12 +279,12 @@ func (x *Struct) GetFields() map[string]*Value { return nil } +// Represents a JSON value. +// // `Value` represents a dynamically typed value which can be either // null, a number, a string, a boolean, a recursive struct value, or a // list of values. A producer of value is expected to set one of these -// variants. Absence of any variant indicates an error. -// -// The JSON representation for `Value` is JSON value. +// variants. Absence of any variant is an invalid state. type Value struct { state protoimpl.MessageState `protogen:"open.v1"` // The kind of value. @@ -548,32 +558,35 @@ type isValue_Kind interface { } type Value_NullValue struct { - // Represents a null value. + // Represents a JSON `null`. NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"` } type Value_NumberValue struct { - // Represents a double value. + // Represents a JSON number. Must not be `NaN`, `Infinity` or + // `-Infinity`, since those are not supported in JSON. This also cannot + // represent large Int64 values, since JSON format generally does not + // support them in its number type. NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,proto3,oneof"` } type Value_StringValue struct { - // Represents a string value. + // Represents a JSON string. StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` } type Value_BoolValue struct { - // Represents a boolean value. + // Represents a JSON boolean (`true` or `false` literal in JSON). BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` } type Value_StructValue struct { - // Represents a structured value. + // Represents a JSON object. StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,proto3,oneof"` } type Value_ListValue struct { - // Represents a repeated `Value`. + // Represents a JSON array. ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,proto3,oneof"` } @@ -589,9 +602,7 @@ func (*Value_StructValue) isValue_Kind() {} func (*Value_ListValue) isValue_Kind() {} -// `ListValue` is a wrapper around a repeated field of values. -// -// The JSON representation for `ListValue` is JSON array. +// Represents a JSON array. type ListValue struct { state protoimpl.MessageState `protogen:"open.v1"` // Repeated field of dynamically typed values. diff --git a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go index 484c21fd536..2cd60946cf0 100644 --- a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go @@ -153,8 +153,8 @@ import ( // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required. A proto3 JSON serializer should always use UTC (as indicated by -// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// is required. A ProtoJSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a ProtoJSON parser should be // able to accept both UTC and other timezones (as indicated by an offset). // // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past @@ -173,7 +173,7 @@ import ( type Timestamp struct { state protoimpl.MessageState `protogen:"open.v1"` // Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must - // be between -315576000000 and 315576000000 inclusive (which corresponds to + // be between -62135596800 and 253402300799 inclusive (which corresponds to // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z). Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` // Non-negative fractions of a second at nanosecond resolution. This field is diff --git a/vendor/gopkg.in/ini.v1/key.go b/vendor/gopkg.in/ini.v1/key.go index b1ef5c96d7f..800d04a473b 100644 --- a/vendor/gopkg.in/ini.v1/key.go +++ b/vendor/gopkg.in/ini.v1/key.go @@ -15,12 +15,12 @@ package ini import ( - "bytes" "errors" "fmt" "strconv" "strings" "time" + "unicode/utf8" ) // Key represents a key under a section. @@ -495,31 +495,38 @@ func (k *Key) Strings(delim string) []string { return []string{} } - runes := []rune(str) - vals := make([]string, 0, 2) - var buf bytes.Buffer - escape := false - idx := 0 + maxParts := strings.Count(str, delim) + 1 + vals := make([]string, 0, maxParts) + + var buf strings.Builder + buf.Grow(len(str)) + + i := 0 for { - if escape { - escape = false - if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) { + if str[i] == '\\' { + i++ + if i >= len(str) { + break + } + + if str[i] != '\\' && !strings.HasPrefix(str[i:], delim) { buf.WriteRune('\\') } - buf.WriteRune(runes[idx]) + + r, size := utf8.DecodeRuneInString(str[i:]) + i += size + buf.WriteRune(r) + } else if strings.HasPrefix(str[i:], delim) { + i += len(delim) + vals = append(vals, strings.TrimSpace(buf.String())) + buf.Reset() } else { - if runes[idx] == '\\' { - escape = true - } else if strings.HasPrefix(string(runes[idx:]), delim) { - idx += len(delim) - 1 - vals = append(vals, strings.TrimSpace(buf.String())) - buf.Reset() - } else { - buf.WriteRune(runes[idx]) - } + r, size := utf8.DecodeRuneInString(str[i:]) + i += size + buf.WriteRune(r) } - idx++ - if idx == len(runes) { + + if i >= len(str) { break } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0d87a6c6f28..dd486779867 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -173,7 +173,7 @@ github.com/andybalholm/brotli/matchfinder # github.com/armon/go-metrics v0.4.1 ## explicit; go 1.12 github.com/armon/go-metrics -# github.com/aws/aws-sdk-go-v2 v1.42.0 +# github.com/aws/aws-sdk-go-v2 v1.45.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/aws github.com/aws/aws-sdk-go-v2/aws/defaults @@ -199,11 +199,12 @@ github.com/aws/aws-sdk-go-v2/internal/shareddefaults github.com/aws/aws-sdk-go-v2/internal/strings github.com/aws/aws-sdk-go-v2/internal/sync/singleflight github.com/aws/aws-sdk-go-v2/internal/timeconv -# github.com/aws/aws-sdk-go-v2/config v1.32.26 +github.com/aws/aws-sdk-go-v2/internal/timeouts +# github.com/aws/aws-sdk-go-v2/config v1.33.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/config github.com/aws/aws-sdk-go-v2/config/internal/ini -# github.com/aws/aws-sdk-go-v2/credentials v1.19.25 +# github.com/aws/aws-sdk-go-v2/credentials v1.20.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/credentials github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds @@ -213,37 +214,37 @@ github.com/aws/aws-sdk-go-v2/credentials/logincreds github.com/aws/aws-sdk-go-v2/credentials/processcreds github.com/aws/aws-sdk-go-v2/credentials/ssocreds github.com/aws/aws-sdk-go-v2/credentials/stscreds -# github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.29 +# github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/feature/ec2/imds github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config -# github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 +# github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/internal/configsources -# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 +# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 -# github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 +# github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/internal/v4a github.com/aws/aws-sdk-go-v2/internal/v4a/internal/crypto github.com/aws/aws-sdk-go-v2/internal/v4a/internal/v4 -# github.com/aws/aws-sdk-go-v2/service/dynamodb v1.59.1 +# github.com/aws/aws-sdk-go-v2/service/dynamodb v1.65.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/dynamodb github.com/aws/aws-sdk-go-v2/service/dynamodb/internal/customizations github.com/aws/aws-sdk-go-v2/service/dynamodb/internal/endpoints github.com/aws/aws-sdk-go-v2/service/dynamodb/types -# github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 +# github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding -# github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.12.6 +# github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.13.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery -# github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 +# github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url -# github.com/aws/aws-sdk-go-v2/service/signin v1.2.1 +# github.com/aws/aws-sdk-go-v2/service/signin v1.7.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/signin github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints @@ -253,22 +254,22 @@ github.com/aws/aws-sdk-go-v2/service/signin/types github.com/aws/aws-sdk-go-v2/service/sns github.com/aws/aws-sdk-go-v2/service/sns/internal/endpoints github.com/aws/aws-sdk-go-v2/service/sns/types -# github.com/aws/aws-sdk-go-v2/service/sso v1.31.4 +# github.com/aws/aws-sdk-go-v2/service/sso v1.35.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/sso github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints github.com/aws/aws-sdk-go-v2/service/sso/types -# github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.7 +# github.com/aws/aws-sdk-go-v2/service/ssooidc v1.40.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/ssooidc github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints github.com/aws/aws-sdk-go-v2/service/ssooidc/types -# github.com/aws/aws-sdk-go-v2/service/sts v1.43.4 +# github.com/aws/aws-sdk-go-v2/service/sts v1.47.1 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/service/sts github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints github.com/aws/aws-sdk-go-v2/service/sts/types -# github.com/aws/smithy-go v1.27.1 +# github.com/aws/smithy-go v1.28.1 ## explicit; go 1.24 github.com/aws/smithy-go github.com/aws/smithy-go/auth @@ -456,8 +457,8 @@ github.com/fatih/faillint/faillint # github.com/felixge/fgprof v0.9.5 ## explicit; go 1.14 github.com/felixge/fgprof -# github.com/felixge/httpsnoop v1.0.4 -## explicit; go 1.13 +# github.com/felixge/httpsnoop v1.1.0 +## explicit; go 1.25 github.com/felixge/httpsnoop # github.com/fsnotify/fsnotify v1.10.0 ## explicit; go 1.23 @@ -485,7 +486,7 @@ github.com/go-logr/logr/funcr # github.com/go-logr/stdr v1.2.2 ## explicit; go 1.16 github.com/go-logr/stdr -# github.com/go-openapi/analysis v0.25.0 +# github.com/go-openapi/analysis v0.25.5 ## explicit; go 1.25.0 github.com/go-openapi/analysis github.com/go-openapi/analysis/internal/debug @@ -497,76 +498,84 @@ github.com/go-openapi/analysis/internal/flatten/sortref # github.com/go-openapi/errors v0.22.8 ## explicit; go 1.25.0 github.com/go-openapi/errors -# github.com/go-openapi/jsonpointer v0.22.5 -## explicit; go 1.24.0 +# github.com/go-openapi/jsonpointer v1.0.0 +## explicit; go 1.25.0 github.com/go-openapi/jsonpointer -# github.com/go-openapi/jsonreference v0.21.5 -## explicit; go 1.24.0 +github.com/go-openapi/jsonpointer/jsonname +# github.com/go-openapi/jsonreference v1.0.0 +## explicit; go 1.25.0 github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal -# github.com/go-openapi/loads v0.23.3 -## explicit; go 1.24.0 +# github.com/go-openapi/loads v0.25.0 +## explicit; go 1.25.0 github.com/go-openapi/loads -# github.com/go-openapi/runtime v0.29.4 +# github.com/go-openapi/runtime v0.33.0 ## explicit; go 1.25.0 github.com/go-openapi/runtime github.com/go-openapi/runtime/client +github.com/go-openapi/runtime/client/internal/request github.com/go-openapi/runtime/flagext github.com/go-openapi/runtime/logger github.com/go-openapi/runtime/middleware github.com/go-openapi/runtime/middleware/denco -github.com/go-openapi/runtime/middleware/header github.com/go-openapi/runtime/middleware/untyped github.com/go-openapi/runtime/security github.com/go-openapi/runtime/yamlpc -# github.com/go-openapi/spec v0.22.4 => github.com/go-openapi/spec v0.20.6 +# github.com/go-openapi/runtime/server-middleware v0.30.0 +## explicit; go 1.25.0 +github.com/go-openapi/runtime/server-middleware/docui +github.com/go-openapi/runtime/server-middleware/mediatype +github.com/go-openapi/runtime/server-middleware/negotiate +github.com/go-openapi/runtime/server-middleware/negotiate/header +# github.com/go-openapi/spec v0.22.9 => github.com/go-openapi/spec v0.20.6 ## explicit; go 1.13 github.com/go-openapi/spec -# github.com/go-openapi/strfmt v0.26.4 +# github.com/go-openapi/strfmt v0.27.0 ## explicit; go 1.25.0 github.com/go-openapi/strfmt github.com/go-openapi/strfmt/internal/bsonlite -# github.com/go-openapi/swag v0.26.0 +github.com/go-openapi/strfmt/internal/countries +# github.com/go-openapi/swag v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag -# github.com/go-openapi/swag/cmdutils v0.26.0 +# github.com/go-openapi/swag/cmdutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/cmdutils -# github.com/go-openapi/swag/conv v0.27.0 +# github.com/go-openapi/swag/conv v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/conv -# github.com/go-openapi/swag/fileutils v0.26.0 +# github.com/go-openapi/swag/fileutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/fileutils -# github.com/go-openapi/swag/jsonname v0.26.0 -## explicit; go 1.25.0 -github.com/go-openapi/swag/jsonname -# github.com/go-openapi/swag/jsonutils v0.27.0 +# github.com/go-openapi/swag/jsonutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/jsonutils github.com/go-openapi/swag/jsonutils/adapters github.com/go-openapi/swag/jsonutils/adapters/ifaces github.com/go-openapi/swag/jsonutils/adapters/stdlib/json -# github.com/go-openapi/swag/loading v0.26.0 +# github.com/go-openapi/swag/loading v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/loading -# github.com/go-openapi/swag/mangling v0.26.0 +# github.com/go-openapi/swag/mangling v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/mangling -# github.com/go-openapi/swag/netutils v0.26.0 +# github.com/go-openapi/swag/netutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/netutils -# github.com/go-openapi/swag/stringutils v0.26.0 +# github.com/go-openapi/swag/pools v0.29.1 +## explicit; go 1.25.0 +github.com/go-openapi/swag/pools +# github.com/go-openapi/swag/stringutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/stringutils -# github.com/go-openapi/swag/typeutils v0.27.0 +# github.com/go-openapi/swag/typeutils v0.29.1 ## explicit; go 1.25.0 github.com/go-openapi/swag/typeutils -# github.com/go-openapi/swag/yamlutils v0.26.0 +# github.com/go-openapi/swag/yamlutils v0.28.0 ## explicit; go 1.25.0 github.com/go-openapi/swag/yamlutils -# github.com/go-openapi/validate v0.25.2 -## explicit; go 1.24.0 +# github.com/go-openapi/validate v0.26.1 +## explicit; go 1.25.0 github.com/go-openapi/validate # github.com/go-redis/redis/v8 v8.11.5 ## explicit; go 1.17 @@ -707,12 +716,12 @@ github.com/grpc-ecosystem/go-grpc-middleware github.com/grpc-ecosystem/go-grpc-middleware/v2 github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging -# github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 +# github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 ## explicit; go 1.25.0 github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule github.com/grpc-ecosystem/grpc-gateway/v2/runtime github.com/grpc-ecosystem/grpc-gateway/v2/utilities -# github.com/hashicorp/consul/api v1.34.3 +# github.com/hashicorp/consul/api v1.34.4 ## explicit; go 1.26 github.com/hashicorp/consul/api # github.com/hashicorp/errwrap v1.1.0 @@ -727,9 +736,10 @@ github.com/hashicorp/go-hclog # github.com/hashicorp/go-immutable-radix v1.3.1 ## explicit github.com/hashicorp/go-immutable-radix -# github.com/hashicorp/go-metrics v0.6.0 -## explicit; go 1.25 +# github.com/hashicorp/go-metrics v0.6.1 +## explicit; go 1.25.0 github.com/hashicorp/go-metrics +github.com/hashicorp/go-metrics/compat github.com/hashicorp/go-metrics/prometheus # github.com/hashicorp/go-msgpack v0.5.5 ## explicit @@ -746,7 +756,7 @@ github.com/hashicorp/go-sockaddr # github.com/hashicorp/go-version v1.9.0 ## explicit github.com/hashicorp/go-version -# github.com/hashicorp/golang-lru v0.6.0 +# github.com/hashicorp/golang-lru v1.0.2 ## explicit; go 1.12 github.com/hashicorp/golang-lru/simplelru # github.com/hashicorp/golang-lru/v2 v2.0.7 @@ -755,11 +765,11 @@ github.com/hashicorp/golang-lru/v2 github.com/hashicorp/golang-lru/v2/expirable github.com/hashicorp/golang-lru/v2/internal github.com/hashicorp/golang-lru/v2/simplelru -# github.com/hashicorp/memberlist v0.5.4 => github.com/grafana/memberlist v0.3.1-0.20220714140823-09ffed8adbbe +# github.com/hashicorp/memberlist v0.6.0 => github.com/grafana/memberlist v0.3.1-0.20220714140823-09ffed8adbbe ## explicit; go 1.12 github.com/hashicorp/memberlist -# github.com/hashicorp/serf v0.10.1 -## explicit; go 1.12 +# github.com/hashicorp/serf v0.10.4 +## explicit; go 1.25.0 github.com/hashicorp/serf/coordinate # github.com/huaweicloud/huaweicloud-sdk-go-obs v3.25.4+incompatible ## explicit @@ -779,7 +789,7 @@ github.com/julienschmidt/httprouter # github.com/kamstrup/intmap v0.5.2 ## explicit; go 1.23 github.com/kamstrup/intmap -# github.com/klauspost/compress v1.18.7 +# github.com/klauspost/compress v1.19.2 ## explicit; go 1.24 github.com/klauspost/compress github.com/klauspost/compress/flate @@ -799,8 +809,8 @@ github.com/klauspost/compress/snappy github.com/klauspost/compress/zlib github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash -# github.com/klauspost/cpuid/v2 v2.2.11 -## explicit; go 1.22 +# github.com/klauspost/cpuid/v2 v2.4.0 +## explicit; go 1.24.0 github.com/klauspost/cpuid/v2 # github.com/klauspost/crc32 v1.3.0 ## explicit; go 1.23.0 @@ -833,11 +843,11 @@ github.com/lib/pq/internal/pqutil github.com/lib/pq/internal/proto github.com/lib/pq/oid github.com/lib/pq/scram -# github.com/mattn/go-colorable v0.1.14 +# github.com/mattn/go-colorable v0.1.15 ## explicit; go 1.18 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.20 -## explicit; go 1.15 +# github.com/mattn/go-isatty v0.0.22 +## explicit; go 1.21 github.com/mattn/go-isatty # github.com/mdlayher/socket v0.5.1 ## explicit; go 1.20 @@ -848,7 +858,7 @@ github.com/mdlayher/vsock # github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a ## explicit; go 1.14 github.com/metalmatze/signal/server/signalhttp -# github.com/miekg/dns v1.1.69 +# github.com/miekg/dns v1.1.72 ## explicit; go 1.24.0 github.com/miekg/dns # github.com/minio/crc64nvme v1.1.1 @@ -857,7 +867,7 @@ github.com/minio/crc64nvme # github.com/minio/md5-simd v1.1.2 ## explicit; go 1.14 github.com/minio/md5-simd -# github.com/minio/minio-go/v7 v7.2.1 +# github.com/minio/minio-go/v7 v7.3.0 ## explicit; go 1.25.0 github.com/minio/minio-go/v7 github.com/minio/minio-go/v7/pkg/cors @@ -866,6 +876,7 @@ github.com/minio/minio-go/v7/pkg/encrypt github.com/minio/minio-go/v7/pkg/kvcache github.com/minio/minio-go/v7/pkg/lifecycle github.com/minio/minio-go/v7/pkg/notification +github.com/minio/minio-go/v7/pkg/policy github.com/minio/minio-go/v7/pkg/replication github.com/minio/minio-go/v7/pkg/s3utils github.com/minio/minio-go/v7/pkg/set @@ -915,7 +926,7 @@ github.com/oklog/run # github.com/oklog/ulid v1.3.1 ## explicit github.com/oklog/ulid -# github.com/oklog/ulid/v2 v2.1.1 +# github.com/oklog/ulid/v2 v2.1.2 ## explicit; go 1.15 github.com/oklog/ulid/v2 # github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.142.0 @@ -961,7 +972,7 @@ github.com/parquet-go/bitpack/unsafecast # github.com/parquet-go/jsonlite v1.0.0 ## explicit; go 1.23 github.com/parquet-go/jsonlite -# github.com/parquet-go/parquet-go v0.30.1 +# github.com/parquet-go/parquet-go v0.32.0 ## explicit; go 1.24.9 github.com/parquet-go/parquet-go github.com/parquet-go/parquet-go/bloom @@ -1016,9 +1027,6 @@ github.com/planetscale/vtprotobuf/types/known/emptypb github.com/planetscale/vtprotobuf/types/known/structpb github.com/planetscale/vtprotobuf/types/known/timestamppb github.com/planetscale/vtprotobuf/types/known/wrapperspb -# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 -## explicit -github.com/pmezard/go-difflib/difflib # github.com/prometheus-community/parquet-common v0.0.0-20260614025832-5f32460b5373 ## explicit; go 1.24.0 github.com/prometheus-community/parquet-common/convert @@ -1095,8 +1103,8 @@ github.com/prometheus/alertmanager/template github.com/prometheus/alertmanager/timeinterval github.com/prometheus/alertmanager/tracing github.com/prometheus/alertmanager/types -# github.com/prometheus/client_golang v1.23.2 -## explicit; go 1.23.0 +# github.com/prometheus/client_golang v1.24.1 +## explicit; go 1.25.0 github.com/prometheus/client_golang/api github.com/prometheus/client_golang/api/prometheus/v1 github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil @@ -1119,7 +1127,7 @@ github.com/prometheus/client_golang/exp/internal/github.com/efficientgo/core/bac # github.com/prometheus/client_model v0.6.2 ## explicit; go 1.22.0 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.69.0 +# github.com/prometheus/common v0.70.1 ## explicit; go 1.25.0 github.com/prometheus/common/config github.com/prometheus/common/expfmt @@ -1134,7 +1142,7 @@ github.com/prometheus/exporter-toolkit/web # github.com/prometheus/otlptranslator v1.0.0 => github.com/prometheus/otlptranslator v1.0.0 ## explicit; go 1.23.0 github.com/prometheus/otlptranslator -# github.com/prometheus/procfs v0.21.0 +# github.com/prometheus/procfs v0.21.1 ## explicit; go 1.25.0 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs @@ -1262,13 +1270,15 @@ github.com/spiffe/go-spiffe/v2/internal/jwtutil github.com/spiffe/go-spiffe/v2/internal/pemutil github.com/spiffe/go-spiffe/v2/internal/x509util github.com/spiffe/go-spiffe/v2/spiffeid -# github.com/stretchr/objx v0.5.2 +# github.com/stretchr/objx v0.5.3 ## explicit; go 1.20 github.com/stretchr/objx -# github.com/stretchr/testify v1.11.1 +# github.com/stretchr/testify v1.12.1 ## explicit; go 1.17 github.com/stretchr/testify/assert github.com/stretchr/testify/assert/yaml +github.com/stretchr/testify/internal/difflib +github.com/stretchr/testify/internal/spew github.com/stretchr/testify/mock github.com/stretchr/testify/require # github.com/tencentyun/cos-go-sdk-v5 v0.7.66 @@ -1377,11 +1387,11 @@ github.com/thanos-io/thanos/pkg/tracing/interceptors github.com/thanos-io/thanos/pkg/tracing/migration github.com/thanos-io/thanos/pkg/tracing/tracing_middleware github.com/thanos-io/thanos/pkg/tracing/util/metautils -# github.com/tinylib/msgp v1.6.1 +# github.com/tinylib/msgp v1.6.4 ## explicit; go 1.24 github.com/tinylib/msgp/msgp github.com/tinylib/msgp/msgp/setof -# github.com/tjhop/slog-gokit v0.2.0 +# github.com/tjhop/slog-gokit v0.2.2 ## explicit; go 1.21 github.com/tjhop/slog-gokit # github.com/twmb/franz-go v1.21.2 @@ -1528,10 +1538,10 @@ go.opentelemetry.io/collector/confmap/xconfmap ## explicit; go 1.24.0 go.opentelemetry.io/collector/consumer go.opentelemetry.io/collector/consumer/internal -# go.opentelemetry.io/collector/featuregate v1.61.0 +# go.opentelemetry.io/collector/featuregate v1.65.0 ## explicit; go 1.25.0 go.opentelemetry.io/collector/featuregate -# go.opentelemetry.io/collector/pdata v1.61.0 +# go.opentelemetry.io/collector/pdata v1.65.0 ## explicit; go 1.25.0 go.opentelemetry.io/collector/pdata/internal go.opentelemetry.io/collector/pdata/internal/json @@ -1558,15 +1568,15 @@ go.opentelemetry.io/collector/semconv/v1.6.1 # go.opentelemetry.io/contrib/detectors/gcp v1.44.0 ## explicit; go 1.25.0 go.opentelemetry.io/contrib/detectors/gcp -# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 -## explicit; go 1.23.0 +# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0 +## explicit; go 1.25.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal # go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 ## explicit; go 1.25.0 go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 +# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 ## explicit; go 1.25.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request @@ -1574,7 +1584,7 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv # go.opentelemetry.io/contrib/propagators/autoprop v0.61.0 ## explicit; go 1.23.0 go.opentelemetry.io/contrib/propagators/autoprop -# go.opentelemetry.io/contrib/propagators/aws v1.44.0 +# go.opentelemetry.io/contrib/propagators/aws v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/contrib/propagators/aws/xray # go.opentelemetry.io/contrib/propagators/b3 v1.36.0 @@ -1586,7 +1596,7 @@ go.opentelemetry.io/contrib/propagators/jaeger # go.opentelemetry.io/contrib/propagators/ot v1.36.0 ## explicit; go 1.23.0 go.opentelemetry.io/contrib/propagators/ot -# go.opentelemetry.io/otel v1.45.0 +# go.opentelemetry.io/otel v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -1602,23 +1612,25 @@ go.opentelemetry.io/otel/semconv/internal/metricpool go.opentelemetry.io/otel/semconv/v1.17.0 go.opentelemetry.io/otel/semconv/v1.21.0 go.opentelemetry.io/otel/semconv/v1.24.0 -go.opentelemetry.io/otel/semconv/v1.30.0 go.opentelemetry.io/otel/semconv/v1.37.0 +go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv go.opentelemetry.io/otel/semconv/v1.40.0 go.opentelemetry.io/otel/semconv/v1.40.0/httpconv go.opentelemetry.io/otel/semconv/v1.40.0/otelconv go.opentelemetry.io/otel/semconv/v1.41.0 -go.opentelemetry.io/otel/semconv/v1.41.0/otelconv go.opentelemetry.io/otel/semconv/v1.43.0 -# go.opentelemetry.io/otel/bridge/opentracing v1.45.0 +go.opentelemetry.io/otel/semconv/v1.43.0/httpconv +go.opentelemetry.io/otel/semconv/v1.43.0/otelconv +go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv +# go.opentelemetry.io/otel/bridge/opentracing v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/bridge/opentracing go.opentelemetry.io/otel/bridge/opentracing/migration -# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform -# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal @@ -1638,39 +1650,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x -# go.opentelemetry.io/otel/metric v1.45.0 +# go.opentelemetry.io/otel/metric v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric/embedded go.opentelemetry.io/otel/metric/noop -# go.opentelemetry.io/otel/sdk v1.44.0 +# go.opentelemetry.io/otel/sdk v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/instrumentation +go.opentelemetry.io/otel/sdk/internal/attrnorm go.opentelemetry.io/otel/sdk/internal/x go.opentelemetry.io/otel/sdk/resource go.opentelemetry.io/otel/sdk/trace go.opentelemetry.io/otel/sdk/trace/internal/env go.opentelemetry.io/otel/sdk/trace/internal/observ go.opentelemetry.io/otel/sdk/trace/tracetest -# go.opentelemetry.io/otel/sdk/metric v1.44.0 +# go.opentelemetry.io/otel/sdk/metric v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/sdk/metric go.opentelemetry.io/otel/sdk/metric/exemplar go.opentelemetry.io/otel/sdk/metric/internal go.opentelemetry.io/otel/sdk/metric/internal/aggregate +go.opentelemetry.io/otel/sdk/metric/internal/attrnorm go.opentelemetry.io/otel/sdk/metric/internal/observ go.opentelemetry.io/otel/sdk/metric/internal/reservoir go.opentelemetry.io/otel/sdk/metric/internal/x go.opentelemetry.io/otel/sdk/metric/metricdata -# go.opentelemetry.io/otel/trace v1.45.0 +# go.opentelemetry.io/otel/trace v1.46.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/internal/telemetry go.opentelemetry.io/otel/trace/noop -# go.opentelemetry.io/proto/otlp v1.10.0 -## explicit; go 1.24.0 +# go.opentelemetry.io/proto/otlp v1.11.0 +## explicit; go 1.25.0 go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 go.opentelemetry.io/proto/otlp/resource/v1 @@ -1706,10 +1720,10 @@ go.uber.org/zap/zapgrpc # go.yaml.in/yaml/v2 v2.4.4 ## explicit; go 1.15 go.yaml.in/yaml/v2 -# go.yaml.in/yaml/v3 v3.0.4 +# go.yaml.in/yaml/v3 v3.0.5 ## explicit; go 1.16 go.yaml.in/yaml/v3 -# golang.org/x/crypto v0.54.0 +# golang.org/x/crypto v0.55.0 ## explicit; go 1.25.0 golang.org/x/crypto/argon2 golang.org/x/crypto/bcrypt @@ -1730,10 +1744,10 @@ golang.org/x/crypto/scrypt ## explicit; go 1.25.0 golang.org/x/exp/constraints golang.org/x/exp/slices -# golang.org/x/mod v0.37.0 +# golang.org/x/mod v0.38.0 ## explicit; go 1.25.0 golang.org/x/mod/semver -# golang.org/x/net v0.57.0 +# golang.org/x/net v0.58.0 ## explicit; go 1.25.0 golang.org/x/net/bpf golang.org/x/net/context @@ -1777,12 +1791,16 @@ golang.org/x/sys/cpu golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/text v0.40.0 +# golang.org/x/text v0.41.0 ## explicit; go 1.25.0 golang.org/x/text/cases +golang.org/x/text/currency 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/number +golang.org/x/text/internal/stringset golang.org/x/text/internal/tag golang.org/x/text/language golang.org/x/text/runes @@ -1793,7 +1811,7 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.15.0 ## explicit; go 1.25.0 golang.org/x/time/rate -# golang.org/x/tools v0.47.0 +# golang.org/x/tools v0.48.0 ## explicit; go 1.25.0 golang.org/x/tools/go/analysis golang.org/x/tools/go/analysis/checker @@ -1856,7 +1874,7 @@ google.golang.org/genproto/googleapis/type/calendarperiod google.golang.org/genproto/googleapis/type/date google.golang.org/genproto/googleapis/type/expr google.golang.org/genproto/googleapis/type/timeofday -# google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa +# google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations @@ -1866,12 +1884,12 @@ google.golang.org/genproto/googleapis/api/httpbody google.golang.org/genproto/googleapis/api/label google.golang.org/genproto/googleapis/api/metric google.golang.org/genproto/googleapis/api/monitoredres -# google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d +# google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.83.0 +# google.golang.org/grpc v1.83.1 ## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes @@ -2037,7 +2055,7 @@ google.golang.org/grpc/xds google.golang.org/grpc/xds/bootstrap google.golang.org/grpc/xds/csds google.golang.org/grpc/xds/googledirectpath -# google.golang.org/protobuf v1.36.11 +# google.golang.org/protobuf v1.36.12 ## explicit; go 1.23 google.golang.org/protobuf/encoding/protodelim google.golang.org/protobuf/encoding/protojson @@ -2081,7 +2099,7 @@ google.golang.org/protobuf/types/known/fieldmaskpb google.golang.org/protobuf/types/known/structpb google.golang.org/protobuf/types/known/timestamppb google.golang.org/protobuf/types/known/wrapperspb -# gopkg.in/ini.v1 v1.67.2 +# gopkg.in/ini.v1 v1.67.3 ## explicit; go 1.13 gopkg.in/ini.v1 # gopkg.in/telebot.v3 v3.3.8