From db47e7a46b7ec51549e9ef547c8c19f458b9c782 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 26 Aug 2026 01:59:09 -0700 Subject: [PATCH] vendor: align dependencies with Moby Update shared Go dependencies to the versions used by Moby and regenerate vendor. Leave go-archive and sys/userns unchanged. Signed-off-by: Tonis Tiigi --- go.mod | 71 +- go.sum | 223 +- vendor/cyphar.com/go-pathrs/.golangci.yml | 2 +- vendor/cyphar.com/go-pathrs/doc.go | 2 +- vendor/cyphar.com/go-pathrs/handle_linux.go | 18 +- .../go-pathrs/internal/fdutils/fd_linux.go | 2 +- .../internal/libpathrs/error_unix.go | 2 +- .../internal/libpathrs/libpathrs_linux.go | 82 +- .../go-pathrs/procfs/procfs_linux.go | 25 +- vendor/cyphar.com/go-pathrs/root_linux.go | 84 +- vendor/cyphar.com/go-pathrs/utils_linux.go | 2 +- vendor/cyphar.com/go-pathrs/version_linux.go | 27 + .../github.com/Microsoft/hcsshim/.gitignore | 7 + vendor/github.com/Microsoft/hcsshim/Makefile | 12 +- .../Microsoft/hcsshim/Protobuild.toml | 5 +- vendor/github.com/Microsoft/hcsshim/README.md | 101 +- .../options/runhcs.pb.go | 21 +- .../options/runhcs.proto | 5 +- .../hcsshim/computestorage/attach.go | 20 +- .../hcsshim/computestorage/destroy.go | 10 +- .../hcsshim/computestorage/detach.go | 16 +- .../hcsshim/computestorage/export.go | 14 +- .../hcsshim/computestorage/format.go | 6 +- .../hcsshim/computestorage/import.go | 14 +- .../hcsshim/computestorage/initialize.go | 12 +- .../Microsoft/hcsshim/computestorage/mount.go | 6 +- .../Microsoft/hcsshim/computestorage/setup.go | 22 +- .../Microsoft/hcsshim/hcn/hcnnamespace.go | 8 +- .../Microsoft/hcsshim/hcn/hcnpolicy.go | 23 +- .../Microsoft/hcsshim/internal/cow/cow.go | 19 + .../Microsoft/hcsshim/internal/hcs/errors.go | 6 +- .../Microsoft/hcsshim/internal/hcs/process.go | 71 +- .../hcsshim/internal/hcs/schema1/schema1.go | 1 + .../hcsshim/internal/hcs/schema2/com_port.go | 2 +- .../hcsshim/internal/hcs/schema2/container.go | 11 + .../schema2/container_memory_information.go | 2 +- .../hcs/schema2/guest_connection_info.go | 2 +- .../internal/hcs/schema2/hv_socket_2.go | 2 +- .../internal/hcs/schema2/hv_socket_address.go | 4 +- .../hcs/schema2/hv_socket_system_config.go | 2 +- .../internal/hcs/schema2/memory_stats.go | 2 +- .../hcsshim/internal/hcs/schema2/migration.go | 205 + .../internal/hcs/schema2/numa_setting.go | 12 +- .../hcs/schema2/pause_notification.go | 2 +- .../internal/hcs/schema2/pause_options.go | 2 +- .../internal/hcs/schema2/plan9_share.go | 11 +- .../internal/hcs/schema2/plan9_share_flags.go | 38 + .../internal/hcs/schema2/process_details.go | 2 +- .../hcsshim/internal/hcs/schema2/processor.go | 2 +- .../internal/hcs/schema2/processor_stats.go | 2 +- .../internal/hcs/schema2/properties.go | 10 + .../internal/hcs/schema2/property_query.go | 6 +- .../internal/hcs/schema2/silo_properties.go | 2 +- .../internal/hcs/schema2/statistics.go | 2 +- .../hcsshim/internal/hcs/schema2/storage.go | 3 + .../internal/hcs/schema2/storage_stats.go | 2 +- .../hcsshim/internal/hcs/schema2/topology.go | 6 +- .../internal/hcs/schema2/virtual_machine.go | 25 +- .../hcs/schema2/virtual_machine_memory.go | 8 +- .../hcs/schema2/virtual_machine_processor.go | 12 +- .../hcs/schema2/virtual_pci_device.go | 4 +- .../Microsoft/hcsshim/internal/hcs/system.go | 161 +- .../hcsshim/internal/jobobject/jobobject.go | 13 +- .../hcsshim/internal/jobobject/limits.go | 95 +- .../Microsoft/hcsshim/internal/log/format.go | 2 +- .../Microsoft/hcsshim/internal/log/hook.go | 12 +- .../Microsoft/hcsshim/internal/log/scrub.go | 21 +- .../hcsshim/internal/logfields/fields.go | 42 +- .../Microsoft/hcsshim/internal/oc/errors.go | 69 - .../Microsoft/hcsshim/internal/oc/exporter.go | 86 - .../Microsoft/hcsshim/internal/oc/span.go | 58 - .../Microsoft/hcsshim/internal/ot/exporter.go | 98 + .../Microsoft/hcsshim/internal/ot/span.go | 76 + .../hcsshim/internal/vmcompute/vmcompute.go | 187 +- .../hcsshim/internal/wclayer/activatelayer.go | 10 +- .../internal/wclayer/baselayerreader.go | 10 +- .../internal/wclayer/baselayerwriter.go | 8 +- .../internal/wclayer/converttobaselayer.go | 10 +- .../hcsshim/internal/wclayer/createlayer.go | 14 +- .../internal/wclayer/createscratchlayer.go | 14 +- .../internal/wclayer/deactivatelayer.go | 10 +- .../hcsshim/internal/wclayer/destroylayer.go | 10 +- .../internal/wclayer/expandscratchsize.go | 17 +- .../hcsshim/internal/wclayer/exportlayer.go | 31 +- .../internal/wclayer/getlayermountpath.go | 12 +- .../internal/wclayer/getsharedbaseimages.go | 10 +- .../hcsshim/internal/wclayer/grantvmaccess.go | 14 +- .../hcsshim/internal/wclayer/importlayer.go | 35 +- .../hcsshim/internal/wclayer/layerexists.go | 12 +- .../hcsshim/internal/wclayer/layerid.go | 10 +- .../hcsshim/internal/wclayer/legacy.go | 37 +- .../hcsshim/internal/wclayer/nametoguid.go | 12 +- .../hcsshim/internal/wclayer/preparelayer.go | 14 +- .../hcsshim/internal/wclayer/processimage.go | 16 +- .../internal/wclayer/unpreparelayer.go | 10 +- .../internal/winapi/cimwriter/cimwriter.go | 37 +- .../hcsshim/internal/winapi/cpuaffinity.go | 21 + .../hcsshim/internal/winapi/jobobject.go | 20 + .../internal/winapi/zsyscall_windows.go | 25 + .../aws/protocol/eventstream/CHANGELOG.md | 8 + .../eventstream/go_module_metadata.go | 2 +- .../pathrs-lite/internal/fd/openat2_linux.go | 4 +- .../gocompat/gocompat_atomic_go119.go | 19 + .../gocompat/gocompat_atomic_unsupported.go | 48 + .../internal/gopathrs/lookup_linux.go | 9 +- .../internal/gopathrs/openat2_linux.go | 1 + .../internal/linux/openat2_linux.go | 16 +- .../felixge/httpsnoop/capture_metrics.go | 37 +- .../felixge/httpsnoop/wrap_generated.go | 16179 ++++++++++++++++ .../httpsnoop/wrap_generated_gteq_1.8.go | 436 - .../httpsnoop/wrap_generated_lt_1.8.go | 278 - .../github.com/go-logr/logr/context_noslog.go | 1 - .../github.com/go-logr/logr/context_slog.go | 1 - vendor/github.com/go-logr/logr/funcr/funcr.go | 47 +- .../github.com/go-logr/logr/funcr/slogsink.go | 22 +- vendor/github.com/go-logr/logr/sloghandler.go | 1 - vendor/github.com/go-logr/logr/slogr.go | 1 - vendor/github.com/go-logr/logr/slogsink.go | 1 - .../pelletier/go-toml/v2/.goreleaser.yaml | 32 +- .../github.com/pelletier/go-toml/v2/AGENTS.md | 11 +- .../pelletier/go-toml/v2/CONTRIBUTING.md | 19 + .../pelletier/go-toml/v2/Dockerfile | 7 +- .../github.com/pelletier/go-toml/v2/README.md | 341 +- .../go-toml/v2/capability_baseline.txt | 1 + .../github.com/pelletier/go-toml/v2/caps.sh | 101 + vendor/github.com/pelletier/go-toml/v2/ci.sh | 6 +- .../github.com/pelletier/go-toml/v2/decode.go | 825 +- .../pelletier/go-toml/v2/decode_fused.go | 362 + .../github.com/pelletier/go-toml/v2/errors.go | 316 +- .../go-toml/v2/internal/characters/ascii.go | 42 - .../go-toml/v2/internal/characters/utf8.go | 175 - .../v2/internal/parserbridge/parserbridge.go | 37 + .../go-toml/v2/internal/tracker/key.go | 3 +- .../go-toml/v2/internal/tracker/seen.go | 569 +- .../pelletier/go-toml/v2/localtime.go | 7 +- .../pelletier/go-toml/v2/marshaler.go | 2405 ++- .../github.com/pelletier/go-toml/v2/strict.go | 98 +- .../github.com/pelletier/go-toml/v2/toml.abnf | 21 +- .../github.com/pelletier/go-toml/v2/types.go | 13 +- .../pelletier/go-toml/v2/unmarshaler.go | 3124 +-- .../pelletier/go-toml/v2/unstable/ast.go | 85 +- .../pelletier/go-toml/v2/unstable/bridge.go | 21 + .../pelletier/go-toml/v2/unstable/builder.go | 64 - .../pelletier/go-toml/v2/unstable/kind.go | 4 +- .../go-toml/v2/unstable/marshaler.go | 29 + .../pelletier/go-toml/v2/unstable/parser.go | 2617 +-- .../pelletier/go-toml/v2/unstable/scanner.go | 270 - .../go-toml/v2/unstable/unmarshaler.go | 31 +- .../golang/gddo/httputil/header/header.go | 2 +- .../client_golang/prometheus/counter.go | 11 +- .../client_golang/prometheus/desc.go | 37 +- .../prometheus/expvar_collector.go | 8 +- .../client_golang/prometheus/gauge.go | 11 +- .../prometheus/go_collector_go116.go | 122 - .../prometheus/go_collector_latest.go | 20 +- .../client_golang/prometheus/histogram.go | 29 +- .../prometheus/internal/difflib.go | 4 +- .../client_golang/prometheus/labels.go | 3 +- .../client_golang/prometheus/metric.go | 3 + .../prometheus/process_collector_darwin.go | 13 +- .../prometheus/process_collector_windows.go | 19 +- .../client_golang/prometheus/promhttp/http.go | 197 +- .../prometheus/promhttp/instrument_client.go | 12 +- .../prometheus/promhttp/instrument_server.go | 88 +- .../prometheus/promhttp/option.go | 42 +- .../client_golang/prometheus/registry.go | 63 +- .../client_golang/prometheus/summary.go | 9 +- .../client_golang/prometheus/timer.go | 10 +- .../client_golang/prometheus/vec.go | 10 +- .../client_golang/prometheus/wrap.go | 5 +- .../prometheus/common/expfmt/expfmt.go | 4 +- .../common/expfmt/openmetrics_create.go | 26 +- .../prometheus/common/expfmt/text_create.go | 4 +- .../prometheus/common/expfmt/text_parse.go | 10 + .../prometheus/common/model/labels.go | 2 +- .../prometheus/common/model/labelset.go | 13 +- .../prometheus/common/model/metric.go | 14 +- .../prometheus/common/model/time.go | 44 +- .../prometheus/common/model/value.go | 8 +- .../prometheus/common/model/value_float.go | 2 +- .../common/model/value_histogram.go | 8 +- .../prometheus/procfs/Makefile.common | 84 +- vendor/github.com/prometheus/procfs/README.md | 2 +- .../github.com/prometheus/procfs/SECURITY.md | 2 +- vendor/github.com/prometheus/procfs/crypto.go | 8 +- .../github.com/prometheus/procfs/mountinfo.go | 22 +- .../prometheus/procfs/net_wireless.go | 18 +- .../prometheus/procfs/proc_cgroup.go | 2 +- .../github.com/sirupsen/logrus/.golangci.yml | 48 +- vendor/github.com/sirupsen/logrus/.travis.yml | 15 - .../github.com/sirupsen/logrus/CHANGELOG.md | 239 +- vendor/github.com/sirupsen/logrus/README.md | 92 +- vendor/github.com/sirupsen/logrus/alt_exit.go | 4 +- .../github.com/sirupsen/logrus/buffer_pool.go | 22 +- vendor/github.com/sirupsen/logrus/doc.go | 26 +- vendor/github.com/sirupsen/logrus/entry.go | 414 +- vendor/github.com/sirupsen/logrus/exported.go | 169 +- .../github.com/sirupsen/logrus/formatter.go | 47 +- .../sirupsen/logrus/json_formatter.go | 37 +- vendor/github.com/sirupsen/logrus/level.go | 101 + vendor/github.com/sirupsen/logrus/logger.go | 156 +- vendor/github.com/sirupsen/logrus/logrus.go | 221 +- .../logrus/terminal_check_appengine.go | 8 +- .../sirupsen/logrus/terminal_check_bsd.go | 3 +- .../sirupsen/logrus/terminal_check_js.go | 7 - .../logrus/terminal_check_no_terminal.go | 8 +- .../logrus/terminal_check_notappengine.go | 8 +- .../sirupsen/logrus/terminal_check_solaris.go | 2 + .../sirupsen/logrus/terminal_check_unix.go | 5 +- .../sirupsen/logrus/terminal_check_wasi.go | 8 - .../sirupsen/logrus/terminal_check_wasip1.go | 8 - .../sirupsen/logrus/terminal_check_windows.go | 2 +- .../sirupsen/logrus/text_formatter.go | 491 +- vendor/github.com/sirupsen/logrus/writer.go | 6 +- vendor/go.opencensus.io/.gitignore | 9 - vendor/go.opencensus.io/AUTHORS | 1 - vendor/go.opencensus.io/CONTRIBUTING.md | 63 - vendor/go.opencensus.io/LICENSE | 202 - vendor/go.opencensus.io/Makefile | 97 - vendor/go.opencensus.io/README.md | 267 - vendor/go.opencensus.io/appveyor.yml | 24 - vendor/go.opencensus.io/internal/internal.go | 37 - vendor/go.opencensus.io/internal/sanitize.go | 50 - .../internal/traceinternals.go | 53 - vendor/go.opencensus.io/opencensus.go | 21 - vendor/go.opencensus.io/trace/basetypes.go | 129 - vendor/go.opencensus.io/trace/config.go | 86 - vendor/go.opencensus.io/trace/doc.go | 52 - vendor/go.opencensus.io/trace/evictedqueue.go | 38 - vendor/go.opencensus.io/trace/export.go | 97 - .../trace/internal/internal.go | 22 - vendor/go.opencensus.io/trace/lrumap.go | 61 - vendor/go.opencensus.io/trace/sampling.go | 75 - vendor/go.opencensus.io/trace/spanbucket.go | 130 - vendor/go.opencensus.io/trace/spanstore.go | 308 - vendor/go.opencensus.io/trace/status_codes.go | 37 - vendor/go.opencensus.io/trace/trace.go | 595 - vendor/go.opencensus.io/trace/trace_api.go | 265 - vendor/go.opencensus.io/trace/trace_go11.go | 33 - .../go.opencensus.io/trace/trace_nongo11.go | 26 - .../trace/tracestate/tracestate.go | 147 - .../google.golang.org/grpc/otelgrpc/config.go | 2 +- .../google.golang.org/grpc/otelgrpc/doc.go | 2 +- .../grpc/otelgrpc/interceptor.go | 45 +- .../grpc/otelgrpc/interceptorinfo.go | 2 +- .../grpc/otelgrpc/internal/parse.go | 4 +- .../grpc/otelgrpc/metadata_supplier.go | 2 +- .../grpc/otelgrpc/stats_handler.go | 42 +- .../grpc/otelgrpc/version.go | 4 +- .../net/http/httptrace/otelhttptrace/api.go | 2 +- .../httptrace/otelhttptrace/clienttrace.go | 2 +- .../http/httptrace/otelhttptrace/httptrace.go | 2 +- .../otelhttptrace/internal/semconv/client.go | 70 +- .../otelhttptrace/internal/semconv/gen.go | 2 +- .../otelhttptrace/internal/semconv/server.go | 42 +- .../otelhttptrace/internal/semconv/util.go | 24 +- .../http/httptrace/otelhttptrace/version.go | 4 +- .../net/http/otelhttp/common.go | 2 +- .../net/http/otelhttp/config.go | 2 +- .../instrumentation/net/http/otelhttp/doc.go | 2 +- .../net/http/otelhttp/handler.go | 2 +- .../otelhttp/internal/request/body_wrapper.go | 8 +- .../net/http/otelhttp/internal/request/gen.go | 2 +- .../internal/request/resp_writer_wrapper.go | 8 +- .../http/otelhttp/internal/semconv/client.go | 70 +- .../net/http/otelhttp/internal/semconv/gen.go | 2 +- .../http/otelhttp/internal/semconv/server.go | 42 +- .../http/otelhttp/internal/semconv/util.go | 24 +- .../net/http/otelhttp/labeler.go | 2 +- .../net/http/otelhttp/start_time_context.go | 2 +- .../net/http/otelhttp/transport.go | 23 +- .../net/http/otelhttp/version.go | 4 +- vendor/go.opentelemetry.io/otel/.golangci.yml | 4 +- vendor/go.opentelemetry.io/otel/.lycheeignore | 14 + vendor/go.opentelemetry.io/otel/AGENTS.md | 3 + vendor/go.opentelemetry.io/otel/CHANGELOG.md | 78 +- .../go.opentelemetry.io/otel/CONTRIBUTING.md | 12 +- vendor/go.opentelemetry.io/otel/Makefile | 20 +- vendor/go.opentelemetry.io/otel/README.md | 7 + .../go.opentelemetry.io/otel/attribute/doc.go | 2 +- .../otel/attribute/encoder.go | 2 +- .../otel/attribute/filter.go | 2 +- .../otel/attribute/hash.go | 162 +- .../otel/attribute/internal/attribute.go | 2 +- .../otel/attribute/internal/xxhash/xxhash.go | 2 +- .../otel/attribute/iterator.go | 2 +- .../go.opentelemetry.io/otel/attribute/key.go | 134 +- .../go.opentelemetry.io/otel/attribute/kv.go | 80 +- .../otel/attribute/rawhelpers.go | 2 +- .../go.opentelemetry.io/otel/attribute/set.go | 2 +- .../otel/attribute/type_string.go | 5 +- .../otel/attribute/value.go | 312 +- .../otel/baggage/baggage.go | 2 +- .../otel/baggage/context.go | 2 +- .../go.opentelemetry.io/otel/baggage/doc.go | 2 +- .../go.opentelemetry.io/otel/codes/codes.go | 4 +- vendor/go.opentelemetry.io/otel/codes/doc.go | 2 +- .../otel/dependencies.Dockerfile | 2 +- vendor/go.opentelemetry.io/otel/doc.go | 2 +- .../go.opentelemetry.io/otel/error_handler.go | 2 +- .../otlp/otlpmetric/otlpmetricgrpc/client.go | 2 +- .../otlp/otlpmetric/otlpmetricgrpc/config.go | 2 +- .../otlp/otlpmetric/otlpmetricgrpc/doc.go | 2 +- .../otlpmetric/otlpmetricgrpc/exporter.go | 2 +- .../internal/counter/counter.go | 8 +- .../internal/envconfig/envconfig.go | 10 +- .../otlpmetric/otlpmetricgrpc/internal/gen.go | 6 +- .../internal/observ/instrumentation.go | 6 +- .../otlpmetricgrpc/internal/observ/target.go | 13 +- .../internal/oconf/envconfig.go | 62 +- .../otlpmetricgrpc/internal/oconf/options.go | 19 +- .../internal/oconf/optiontypes.go | 8 +- .../otlpmetricgrpc/internal/oconf/tls.go | 8 +- .../otlpmetricgrpc/internal/partialsuccess.go | 10 +- .../otlpmetricgrpc/internal/retry/retry.go | 8 +- .../internal/transform/attribute.go | 17 +- .../internal/transform/error.go | 8 +- .../internal/transform/metricdata.go | 11 +- .../otlpmetricgrpc/internal/x/observ.go | 2 +- .../otlpmetric/otlpmetricgrpc/internal/x/x.go | 8 +- .../otlp/otlpmetric/otlpmetricgrpc/version.go | 4 +- .../otlp/otlpmetric/otlpmetrichttp/client.go | 26 +- .../otlp/otlpmetric/otlpmetrichttp/config.go | 7 +- .../otlp/otlpmetric/otlpmetrichttp/doc.go | 2 +- .../otlpmetric/otlpmetrichttp/exporter.go | 2 +- .../internal/counter/counter.go | 8 +- .../internal/envconfig/envconfig.go | 10 +- .../otlpmetric/otlpmetrichttp/internal/gen.go | 4 +- .../otlpmetrichttp/internal/observ/count.go | 2 +- .../internal/observ/instrumentation.go | 6 +- .../internal/oconf/envconfig.go | 62 +- .../otlpmetrichttp/internal/oconf/options.go | 19 +- .../internal/oconf/optiontypes.go | 8 +- .../otlpmetrichttp/internal/oconf/tls.go | 8 +- .../otlpmetrichttp/internal/partialsuccess.go | 10 +- .../otlpmetrichttp/internal/retry/retry.go | 8 +- .../internal/transform/attribute.go | 17 +- .../internal/transform/error.go | 8 +- .../internal/transform/metricdata.go | 11 +- .../otlpmetrichttp/internal/version.go | 4 +- .../otlpmetrichttp/internal/x/README.md | 2 +- .../otlpmetrichttp/internal/x/observ.go | 2 +- .../otlpmetric/otlpmetrichttp/internal/x/x.go | 8 +- .../otlp/otlpmetric/otlpmetrichttp/version.go | 2 +- .../otel/exporters/otlp/otlptrace/clients.go | 2 +- .../otel/exporters/otlp/otlptrace/doc.go | 2 +- .../otel/exporters/otlp/otlptrace/exporter.go | 6 +- .../internal/tracetransform/attribute.go | 8 +- .../tracetransform/instrumentation.go | 2 +- .../internal/tracetransform/resource.go | 2 +- .../otlptrace/internal/tracetransform/span.go | 26 +- .../otlp/otlptrace/otlptracegrpc/client.go | 10 +- .../otlp/otlptrace/otlptracegrpc/doc.go | 2 +- .../otlp/otlptrace/otlptracegrpc/exporter.go | 2 +- .../otlptracegrpc/internal/counter/counter.go | 8 +- .../internal/envconfig/envconfig.go | 10 +- .../otlptrace/otlptracegrpc/internal/gen.go | 6 +- .../otlptracegrpc/internal/observ/doc.go | 2 +- .../internal/observ/instrumentation.go | 6 +- .../otlptracegrpc/internal/observ/target.go | 13 +- .../internal/otlpconfig/envconfig.go | 62 +- .../internal/otlpconfig/options.go | 19 +- .../internal/otlpconfig/optiontypes.go | 8 +- .../otlptracegrpc/internal/otlpconfig/tls.go | 8 +- .../otlptracegrpc/internal/partialsuccess.go | 10 +- .../otlptracegrpc/internal/retry/retry.go | 8 +- .../otlptracegrpc/internal/version.go | 4 +- .../otlptracegrpc/internal/x/observ.go | 2 +- .../otlptrace/otlptracegrpc/internal/x/x.go | 8 +- .../otlp/otlptrace/otlptracegrpc/options.go | 2 +- .../otlp/otlptrace/otlptracehttp/client.go | 38 +- .../otlp/otlptrace/otlptracehttp/doc.go | 2 +- .../otlp/otlptrace/otlptracehttp/exporter.go | 2 +- .../otlptracehttp/internal/counter/counter.go | 8 +- .../internal/envconfig/envconfig.go | 10 +- .../otlptrace/otlptracehttp/internal/gen.go | 4 +- .../internal/observ/instrumentation.go | 6 +- .../internal/otlpconfig/envconfig.go | 62 +- .../internal/otlpconfig/options.go | 19 +- .../internal/otlpconfig/optiontypes.go | 8 +- .../otlptracehttp/internal/otlpconfig/tls.go | 8 +- .../otlptracehttp/internal/partialsuccess.go | 10 +- .../otlptracehttp/internal/retry/retry.go | 8 +- .../otlptracehttp/internal/version.go | 4 +- .../otlptracehttp/internal/x/observ.go | 2 +- .../otlptrace/otlptracehttp/internal/x/x.go | 8 +- .../otlp/otlptrace/otlptracehttp/options.go | 7 +- .../otel/exporters/otlp/otlptrace/version.go | 4 +- .../otel/exporters/prometheus/config.go | 2 +- .../otel/exporters/prometheus/doc.go | 2 +- .../otel/exporters/prometheus/errors.go | 2 +- .../otel/exporters/prometheus/exporter.go | 9 +- .../prometheus/internal/counter/counter.go | 8 +- .../otel/exporters/prometheus/internal/gen.go | 4 +- .../internal/observ/instrumentation.go | 6 +- .../exporters/prometheus/internal/version.go | 4 +- .../prometheus/internal/x/features.go | 2 +- .../otel/exporters/prometheus/internal/x/x.go | 8 +- vendor/go.opentelemetry.io/otel/handler.go | 2 +- .../otel/internal/baggage/baggage.go | 2 +- .../otel/internal/baggage/context.go | 2 +- .../internal/errorhandler/errorhandler.go | 2 +- .../otel/internal/global/handler.go | 2 +- .../otel/internal/global/instruments.go | 2 +- .../otel/internal/global/internal_logging.go | 2 +- .../otel/internal/global/meter.go | 2 +- .../otel/internal/global/propagator.go | 2 +- .../otel/internal/global/state.go | 2 +- .../otel/internal/global/trace.go | 2 +- .../otel/internal_logging.go | 2 +- vendor/go.opentelemetry.io/otel/metric.go | 2 +- .../otel/metric/asyncfloat64.go | 2 +- .../otel/metric/asyncint64.go | 2 +- .../go.opentelemetry.io/otel/metric/config.go | 2 +- vendor/go.opentelemetry.io/otel/metric/doc.go | 2 +- .../otel/metric/embedded/embedded.go | 2 +- .../otel/metric/instrument.go | 2 +- .../go.opentelemetry.io/otel/metric/meter.go | 2 +- .../otel/metric/noop/noop.go | 2 +- .../otel/metric/syncfloat64.go | 4 +- .../otel/metric/syncint64.go | 4 +- .../go.opentelemetry.io/otel/propagation.go | 2 +- .../otel/propagation/baggage.go | 2 +- .../otel/propagation/doc.go | 2 +- .../otel/propagation/propagation.go | 2 +- .../otel/propagation/trace_context.go | 2 +- .../go.opentelemetry.io/otel/requirements.txt | 2 +- .../otel/sdk/instrumentation/doc.go | 2 +- .../otel/sdk/instrumentation/library.go | 2 +- .../otel/sdk/instrumentation/scope.go | 2 +- .../otel/sdk/internal/attrnorm/dedup.go | 300 + .../otel/sdk/internal/attrnorm/truncate.go | 232 + .../otel/sdk/internal/x/features.go | 2 +- .../otel/sdk/internal/x/x.go | 8 +- .../otel/sdk/metric/aggregation.go | 2 +- .../otel/sdk/metric/cache.go | 2 +- .../otel/sdk/metric/config.go | 4 +- .../otel/sdk/metric/doc.go | 2 +- .../otel/sdk/metric/env.go | 2 +- .../otel/sdk/metric/exemplar.go | 2 +- .../otel/sdk/metric/exemplar/doc.go | 2 +- .../otel/sdk/metric/exemplar/exemplar.go | 2 +- .../otel/sdk/metric/exemplar/filter.go | 2 +- .../metric/exemplar/fixed_size_reservoir.go | 170 +- .../metric/exemplar/histogram_reservoir.go | 58 +- .../otel/sdk/metric/exemplar/next_tracker.go | 154 + .../otel/sdk/metric/exemplar/reservoir.go | 2 +- .../otel/sdk/metric/exemplar/storage.go | 57 +- .../otel/sdk/metric/exemplar/value.go | 2 +- .../otel/sdk/metric/exporter.go | 2 +- .../otel/sdk/metric/instrument.go | 55 +- .../metric/internal/aggregate/aggregate.go | 2 +- .../sdk/metric/internal/aggregate/atomic.go | 18 +- .../otel/sdk/metric/internal/aggregate/doc.go | 2 +- .../sdk/metric/internal/aggregate/drop.go | 2 +- .../sdk/metric/internal/aggregate/exemplar.go | 2 +- .../aggregate/exponential_histogram.go | 28 +- .../internal/aggregate/filtered_reservoir.go | 2 +- .../metric/internal/aggregate/histogram.go | 94 +- .../metric/internal/aggregate/lastvalue.go | 14 +- .../sdk/metric/internal/aggregate/limit.go | 2 +- .../otel/sdk/metric/internal/aggregate/sum.go | 14 +- .../sdk/metric/internal/attrnorm/dedup.go | 300 + .../otel/sdk/metric/internal/gen.go | 10 + .../metric/internal/observ/instrumentation.go | 6 +- .../internal/reservoir/concurrent_safe.go | 2 +- .../otel/sdk/metric/internal/reservoir/doc.go | 2 +- .../otel/sdk/metric/internal/reuse_slice.go | 2 +- .../otel/sdk/metric/internal/x/features.go | 22 + .../otel/sdk/metric/internal/x/x.go | 52 +- .../otel/sdk/metric/manual_reader.go | 2 +- .../otel/sdk/metric/meter.go | 16 +- .../otel/sdk/metric/metricdata/data.go | 2 +- .../otel/sdk/metric/metricdata/temporality.go | 2 +- .../otel/sdk/metric/periodic_reader.go | 4 +- .../otel/sdk/metric/pipeline.go | 2 +- .../otel/sdk/metric/provider.go | 6 +- .../otel/sdk/metric/reader.go | 2 +- .../otel/sdk/metric/splitmetrics.go | 2 +- .../otel/sdk/metric/version.go | 4 +- .../otel/sdk/metric/view.go | 2 +- .../otel/sdk/resource/auto.go | 2 +- .../otel/sdk/resource/builtin.go | 4 +- .../otel/sdk/resource/config.go | 6 +- .../otel/sdk/resource/container.go | 4 +- .../otel/sdk/resource/doc.go | 2 +- .../otel/sdk/resource/env.go | 4 +- .../otel/sdk/resource/host_id.go | 4 +- .../otel/sdk/resource/host_id_bsd.go | 2 +- .../otel/sdk/resource/host_id_darwin.go | 2 +- .../otel/sdk/resource/host_id_exec.go | 2 +- .../otel/sdk/resource/host_id_linux.go | 2 +- .../otel/sdk/resource/host_id_readfile.go | 2 +- .../otel/sdk/resource/host_id_unsupported.go | 2 +- .../otel/sdk/resource/host_id_windows.go | 2 +- .../otel/sdk/resource/os.go | 4 +- .../otel/sdk/resource/os_release_darwin.go | 2 +- .../otel/sdk/resource/os_release_unix.go | 2 +- .../otel/sdk/resource/os_unix.go | 2 +- .../otel/sdk/resource/os_unsupported.go | 2 +- .../otel/sdk/resource/os_windows.go | 2 +- .../otel/sdk/resource/process.go | 4 +- .../otel/sdk/resource/resource.go | 23 +- .../otel/sdk/trace/batch_span_processor.go | 7 +- .../go.opentelemetry.io/otel/sdk/trace/doc.go | 2 +- .../otel/sdk/trace/event.go | 2 +- .../otel/sdk/trace/evictedqueue.go | 2 +- .../otel/sdk/trace/id_generator.go | 2 +- .../otel/sdk/trace/internal/env/env.go | 2 +- .../internal/observ/batch_span_processor.go | 6 +- .../otel/sdk/trace/internal/observ/doc.go | 2 +- .../internal/observ/simple_span_processor.go | 6 +- .../otel/sdk/trace/internal/observ/tracer.go | 4 +- .../otel/sdk/trace/link.go | 2 +- .../otel/sdk/trace/provider.go | 61 +- .../otel/sdk/trace/sampler_env.go | 2 +- .../otel/sdk/trace/sampling.go | 2 +- .../otel/sdk/trace/simple_span_processor.go | 14 +- .../otel/sdk/trace/snapshot.go | 2 +- .../otel/sdk/trace/span.go | 250 +- .../otel/sdk/trace/span_exporter.go | 2 +- .../otel/sdk/trace/span_limits.go | 10 +- .../otel/sdk/trace/span_processor.go | 2 +- .../otel/sdk/trace/tracer.go | 2 +- .../otel/sdk/trace/tracetest/exporter.go | 2 +- .../otel/sdk/trace/tracetest/recorder.go | 2 +- .../otel/sdk/trace/tracetest/span.go | 2 +- .../go.opentelemetry.io/otel/sdk/version.go | 4 +- .../otel/semconv/internal/metricpool/pool.go | 48 + .../otel/semconv/v1.21.0/attribute_group.go | 2 +- .../otel/semconv/v1.21.0/doc.go | 2 +- .../otel/semconv/v1.21.0/event.go | 2 +- .../otel/semconv/v1.21.0/exception.go | 2 +- .../otel/semconv/v1.21.0/resource.go | 2 +- .../otel/semconv/v1.21.0/schema.go | 2 +- .../otel/semconv/v1.21.0/trace.go | 2 +- .../otel/semconv/v1.37.0/attribute_group.go | 2 +- .../otel/semconv/v1.37.0/doc.go | 2 +- .../otel/semconv/v1.37.0/error_type.go | 2 +- .../otel/semconv/v1.37.0/exception.go | 2 +- .../otel/semconv/v1.37.0/schema.go | 2 +- .../otel/semconv/v1.41.0/MIGRATION.md | 17 - .../otel/semconv/v1.41.0/README.md | 3 - .../otel/semconv/v1.43.0/MIGRATION.md | 4 + .../otel/semconv/v1.43.0/README.md | 3 + .../{v1.41.0 => v1.43.0}/attribute_group.go | 2093 +- .../otel/semconv/{v1.41.0 => v1.43.0}/doc.go | 4 +- .../{v1.41.0 => v1.43.0}/error_type.go | 2 +- .../semconv/{v1.41.0 => v1.43.0}/exception.go | 2 +- .../{v1.41.0 => v1.43.0}/httpconv/metric.go | 209 +- .../{v1.41.0 => v1.43.0}/otelconv/metric.go | 327 +- .../{v1.41.0 => v1.43.0}/rpcconv/metric.go | 39 +- .../semconv/{v1.41.0 => v1.43.0}/schema.go | 4 +- vendor/go.opentelemetry.io/otel/trace.go | 2 +- vendor/go.opentelemetry.io/otel/trace/auto.go | 14 +- .../go.opentelemetry.io/otel/trace/config.go | 2 +- .../go.opentelemetry.io/otel/trace/context.go | 2 +- vendor/go.opentelemetry.io/otel/trace/doc.go | 2 +- .../otel/trace/embedded/embedded.go | 2 +- vendor/go.opentelemetry.io/otel/trace/hex.go | 2 +- .../otel/trace/internal/telemetry/attr.go | 2 +- .../otel/trace/internal/telemetry/doc.go | 2 +- .../otel/trace/internal/telemetry/id.go | 2 +- .../otel/trace/internal/telemetry/number.go | 2 +- .../otel/trace/internal/telemetry/resource.go | 2 +- .../otel/trace/internal/telemetry/scope.go | 2 +- .../otel/trace/internal/telemetry/span.go | 2 +- .../otel/trace/internal/telemetry/status.go | 2 +- .../otel/trace/internal/telemetry/traces.go | 2 +- .../otel/trace/internal/telemetry/value.go | 2 +- .../otel/trace/nonrecording.go | 2 +- vendor/go.opentelemetry.io/otel/trace/noop.go | 2 +- .../otel/trace/noop/noop.go | 2 +- .../otel/trace/provider.go | 2 +- vendor/go.opentelemetry.io/otel/trace/span.go | 2 +- .../go.opentelemetry.io/otel/trace/trace.go | 2 +- .../go.opentelemetry.io/otel/trace/tracer.go | 2 +- .../otel/trace/tracestate.go | 2 +- vendor/go.opentelemetry.io/otel/version.go | 4 +- vendor/go.opentelemetry.io/otel/versions.yaml | 8 +- .../proto/otlp/common/v1/common.pb.go | 6 +- .../proto/otlp/metrics/v1/metrics.pb.go | 2 +- .../x/crypto/internal/poly1305/mac_noasm.go | 2 +- .../x/crypto/internal/poly1305/sum_asm.go | 2 +- .../x/crypto/internal/poly1305/sum_riscv64.s | 158 + .../golang.org/x/crypto/ssh/agent/keyring.go | 2 +- .../golang.org/x/crypto/ssh/agent/server.go | 4 +- vendor/golang.org/x/crypto/ssh/certs.go | 15 +- vendor/golang.org/x/crypto/ssh/channel.go | 67 +- vendor/golang.org/x/crypto/ssh/client_auth.go | 2 +- vendor/golang.org/x/crypto/ssh/common.go | 8 +- vendor/golang.org/x/crypto/ssh/connection.go | 2 +- vendor/golang.org/x/crypto/ssh/handshake.go | 2 +- vendor/golang.org/x/crypto/ssh/keys.go | 17 +- vendor/golang.org/x/crypto/ssh/messages.go | 11 +- vendor/golang.org/x/crypto/ssh/mux.go | 13 +- vendor/golang.org/x/crypto/ssh/server.go | 79 +- vendor/golang.org/x/crypto/ssh/ssh_gss.go | 16 +- vendor/golang.org/x/crypto/ssh/streamlocal.go | 2 + vendor/golang.org/x/crypto/ssh/tcpip.go | 2 + vendor/golang.org/x/net/http2/hpack/encode.go | 1 - vendor/golang.org/x/net/http2/hpack/hpack.go | 1 - vendor/golang.org/x/net/http2/hpack/tables.go | 51 +- .../golang.org/x/net/http2/transport_wrap.go | 51 +- vendor/google.golang.org/grpc/clientconn.go | 23 +- .../clientconn_disconnect_reason_noplan9.go | 48 + .../clientconn_disconnect_reason_plan9.go | 39 + .../grpc/cmd/protoc-gen-go-grpc/grpc.go | 146 +- .../grpc/cmd/protoc-gen-go-grpc/main.go | 4 +- .../protoc-gen-go-grpc_test.sh | 2 +- .../grpc/internal/envconfig/envconfig.go | 12 +- .../grpc/internal/envconfig/xds.go | 7 +- .../internal/grpcsync/callback_serializer.go | 26 + .../grpc/internal/mem/buffer_pool.go | 14 + .../grpc/internal/resolver/config_selector.go | 78 +- .../grpc/internal/transport/client_stream.go | 5 +- .../grpc/internal/transport/handler_server.go | 2 +- .../grpc/internal/transport/http2_client.go | 6 +- .../grpc/internal/transport/http2_server.go | 2 +- .../grpc/internal/transport/transport.go | 112 +- .../google.golang.org/grpc/mem/buffer_pool.go | 4 - vendor/google.golang.org/grpc/mem/buffers.go | 6 +- vendor/google.golang.org/grpc/stream.go | 35 +- vendor/google.golang.org/grpc/version.go | 2 +- .../editiondefaults/editions_defaults.binpb | Bin 154 -> 191 bytes .../internal/encoding/defval/default.go | 8 +- .../protobuf/internal/genid/descriptor_gen.go | 5 + .../protobuf/internal/version/version.go | 4 +- .../reflect/protoreflect/source_gen.go | 2 + .../types/descriptorpb/descriptor.pb.go | 101 +- .../protobuf/types/known/anypb/any.pb.go | 150 +- .../types/known/fieldmaskpb/field_mask.pb.go | 30 +- .../types/known/structpb/struct.pb.go | 55 +- .../types/known/timestamppb/timestamp.pb.go | 6 +- vendor/modules.txt | 106 +- 635 files changed, 31289 insertions(+), 15074 deletions(-) create mode 100644 vendor/cyphar.com/go-pathrs/version_linux.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/migration.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share_flags.go delete mode 100644 vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go delete mode 100644 vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go delete mode 100644 vendor/github.com/Microsoft/hcsshim/internal/oc/span.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/ot/exporter.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/ot/span.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/winapi/cpuaffinity.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go create mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated.go delete mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go delete mode 100644 vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/capability_baseline.txt create mode 100644 vendor/github.com/pelletier/go-toml/v2/caps.sh create mode 100644 vendor/github.com/pelletier/go-toml/v2/decode_fused.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/internal/parserbridge/parserbridge.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/bridge.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/builder.go create mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/marshaler.go delete mode 100644 vendor/github.com/pelletier/go-toml/v2/unstable/scanner.go delete mode 100644 vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go delete mode 100644 vendor/github.com/sirupsen/logrus/.travis.yml create mode 100644 vendor/github.com/sirupsen/logrus/level.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_js.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_wasi.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go delete mode 100644 vendor/go.opencensus.io/.gitignore delete mode 100644 vendor/go.opencensus.io/AUTHORS delete mode 100644 vendor/go.opencensus.io/CONTRIBUTING.md delete mode 100644 vendor/go.opencensus.io/LICENSE delete mode 100644 vendor/go.opencensus.io/Makefile delete mode 100644 vendor/go.opencensus.io/README.md delete mode 100644 vendor/go.opencensus.io/appveyor.yml delete mode 100644 vendor/go.opencensus.io/internal/internal.go delete mode 100644 vendor/go.opencensus.io/internal/sanitize.go delete mode 100644 vendor/go.opencensus.io/internal/traceinternals.go delete mode 100644 vendor/go.opencensus.io/opencensus.go delete mode 100644 vendor/go.opencensus.io/trace/basetypes.go delete mode 100644 vendor/go.opencensus.io/trace/config.go delete mode 100644 vendor/go.opencensus.io/trace/doc.go delete mode 100644 vendor/go.opencensus.io/trace/evictedqueue.go delete mode 100644 vendor/go.opencensus.io/trace/export.go delete mode 100644 vendor/go.opencensus.io/trace/internal/internal.go delete mode 100644 vendor/go.opencensus.io/trace/lrumap.go delete mode 100644 vendor/go.opencensus.io/trace/sampling.go delete mode 100644 vendor/go.opencensus.io/trace/spanbucket.go delete mode 100644 vendor/go.opencensus.io/trace/spanstore.go delete mode 100644 vendor/go.opencensus.io/trace/status_codes.go delete mode 100644 vendor/go.opencensus.io/trace/trace.go delete mode 100644 vendor/go.opencensus.io/trace/trace_api.go delete mode 100644 vendor/go.opencensus.io/trace/trace_go11.go delete mode 100644 vendor/go.opencensus.io/trace/trace_nongo11.go delete mode 100644 vendor/go.opencensus.io/trace/tracestate/tracestate.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/dedup.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/truncate.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/next_tracker.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/metric/internal/attrnorm/dedup.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/metric/internal/gen.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/features.go create mode 100644 vendor/go.opentelemetry.io/otel/semconv/internal/metricpool/pool.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.43.0/MIGRATION.md create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.43.0/README.md rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/attribute_group.go (90%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/doc.go (83%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/error_type.go (96%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/exception.go (80%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/httpconv/metric.go (96%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/otelconv/metric.go (93%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/rpcconv/metric.go (94%) rename vendor/go.opentelemetry.io/otel/semconv/{v1.41.0 => v1.43.0}/schema.go (75%) create mode 100644 vendor/golang.org/x/crypto/internal/poly1305/sum_riscv64.s create mode 100644 vendor/google.golang.org/grpc/clientconn_disconnect_reason_noplan9.go create mode 100644 vendor/google.golang.org/grpc/clientconn_disconnect_reason_plan9.go diff --git a/go.mod b/go.mod index 9d284eac5..26ffbd402 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0 github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 - github.com/Microsoft/hcsshim v0.15.0-rc.1 + github.com/Microsoft/hcsshim v0.15.0-rc.4 github.com/ProtonMail/go-crypto v1.4.1 github.com/agext/levenshtein v1.2.3 github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 @@ -65,15 +65,15 @@ require ( github.com/opencontainers/runtime-spec v1.3.0 github.com/opencontainers/selinux v1.15.1 github.com/package-url/packageurl-go v0.1.1 - github.com/pelletier/go-toml/v2 v2.3.1 + github.com/pelletier/go-toml/v2 v2.4.3 github.com/pkg/errors v0.9.1 github.com/pkg/profile v1.7.0 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 - github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/procfs v0.20.1 + github.com/prometheus/client_golang v1.24.1 + github.com/prometheus/procfs v0.21.1 github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b github.com/sigstore/sigstore-go v1.2.2 - github.com/sirupsen/logrus v1.9.4 + github.com/sirupsen/logrus v1.10.1 github.com/spdx/tools-golang v0.5.7 github.com/stretchr/testify v1.12.1 github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 @@ -87,43 +87,43 @@ require ( github.com/vishvananda/netlink v1.3.1 github.com/vishvananda/netns v0.0.5 go.etcd.io/bbolt v1.5.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 - go.opentelemetry.io/otel v1.44.0 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0 + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.70.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 + go.opentelemetry.io/otel v1.45.0 go.opentelemetry.io/otel/exporters/jaeger v1.17.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.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/exporters/otlp/otlptrace/otlptracehttp v1.44.0 - go.opentelemetry.io/otel/exporters/prometheus v0.66.0 - go.opentelemetry.io/otel/metric v1.44.0 - go.opentelemetry.io/otel/sdk v1.44.0 - go.opentelemetry.io/otel/sdk/metric v1.44.0 - go.opentelemetry.io/otel/trace v1.44.0 - go.opentelemetry.io/proto/otlp v1.10.0 - golang.org/x/crypto v0.54.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0 + go.opentelemetry.io/otel/exporters/prometheus v0.67.0 + go.opentelemetry.io/otel/metric v1.45.0 + go.opentelemetry.io/otel/sdk v1.45.0 + go.opentelemetry.io/otel/sdk/metric v1.45.0 + go.opentelemetry.io/otel/trace v1.45.0 + go.opentelemetry.io/proto/otlp v1.11.0 + golang.org/x/crypto v0.55.0 golang.org/x/exp v0.0.0-20260603202125-055de637280b - golang.org/x/mod v0.38.0 - golang.org/x/net v0.57.0 + golang.org/x/mod v0.40.0 + golang.org/x/net v0.58.0 golang.org/x/sync v0.22.0 golang.org/x/sys v0.47.0 golang.org/x/time v0.15.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa - google.golang.org/grpc v1.82.1 - google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d + google.golang.org/grpc v1.83.1 + google.golang.org/protobuf v1.36.12 kernel.org/pub/linux/libs/security/libcap/cap v1.2.78 tags.cncf.io/container-device-interface v1.1.0 ) require ( - cyphar.com/go-pathrs v0.2.1 // indirect + cyphar.com/go-pathrs v0.2.5 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 // indirect github.com/anchore/go-struct-converter v0.1.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.39 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.39 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.39 // indirect @@ -147,16 +147,16 @@ require ( github.com/containerd/ttrpc v1.2.9 // indirect github.com/containernetworking/cni v1.3.0 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect - github.com/cyphar/filepath-securejoin v0.6.0 // indirect + github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/docker/docker-credential-helpers v0.9.8 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/felixge/fgprof v0.9.3 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/go-logr/logr v1.4.3 // 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.2 // indirect github.com/go-openapi/errors v0.22.8 // indirect @@ -201,7 +201,7 @@ require ( github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/common v0.70.1 // indirect github.com/prometheus/otlptranslator v1.0.0 // indirect github.com/sasha-s/go-deadlock v0.3.5 // indirect github.com/secure-systems-lab/go-securesystemslib v0.11.0 // indirect @@ -216,14 +216,13 @@ require ( github.com/transparency-dev/merkle v0.0.2 // indirect github.com/vbatts/tar-split v0.12.3 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect - go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.40.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 // indirect + golang.org/x/text v0.41.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.140.0 // indirect kernel.org/pub/linux/libs/security/libcap/psx v1.2.78 // indirect diff --git a/go.sum b/go.sum index 0f90307cb..5e9605f5d 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA= @@ -13,8 +12,8 @@ cloud.google.com/go/kms v1.31.0 h1:LS8N92OxFDgOLg5NCo3OmbvjtQAIVT5gUHVLKIDHaFE= cloud.google.com/go/kms v1.31.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= cloud.google.com/go/longrunning v1.0.0 h1:lwzWEYD8+NkYV7dhexOz6kmlvajZA70+bW/xMhRVVdY= cloud.google.com/go/longrunning v1.0.0/go.mod h1:8nqFBPOO1U/XkhWl0I19AMZEphrHi73VNABIpKYaTwM= -cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= -cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= +cyphar.com/go-pathrs v0.2.5 h1:SnX9FBvnoyn3lUs1dkMgZ52bAETpirNu3FTRh5HlRik= +cyphar.com/go-pathrs v0.2.5/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= filippo.io/mldsa v0.0.0-20260215214346-43d0283efc3e h1:VsUbObBMxXlc23Eb9VeeJYE4jvTs87qa5RqSN2U5FJU= @@ -43,14 +42,13 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 h1:4iB+IesclUXdP0ICgAabvq2FYLXrJWKx1fJQ+GxSo3Y= github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 h1:0kQAzHq8vLs7Pptv+7TxjdETLf/nIqJpIB4oC6Ba4vY= github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29/go.mod h1:ZWa7ssZJT30CCDGJ7fk/2SBTq9BIQrrVjrcss0UW2s0= -github.com/Microsoft/hcsshim v0.15.0-rc.1 h1:FbbwtQmiD+BVHynGkx5S65JkLyhkEiiTP8nrpmg2SZw= -github.com/Microsoft/hcsshim v0.15.0-rc.1/go.mod h1:HWvvUPIy9HF6LotILj1G4VyS065rcLQ6tqj6tMUdOfI= +github.com/Microsoft/hcsshim v0.15.0-rc.4 h1:aZFX4LH0S20Lgjq0wG61StIClj7im4yzrxIClkaR8Z8= +github.com/Microsoft/hcsshim v0.15.0-rc.4/go.mod h1:BA9CBztgu4h/6Jsvo1O1M4qjWw09PoYpaEYgexPE578= github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM= github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= @@ -67,8 +65,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go-v2 v1.43.8 h1:fpnrxwuwsoGIgjvgLeDU3y9w7YaHBxyF6AF3vQL8duw= github.com/aws/aws-sdk-go-v2 v1.43.8/go.mod h1:j7gYSq8dL95QejkFXxvQNESH4I9WGHFI6iO+vhqEi5Q= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16 h1:aiuaKlDweRC5qExJondpWjOgyzMHpofpwspGXUtwn4c= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16/go.mod h1:nG/LOlmox9BDe9HvQnXWzgcK8uKbgBMZ/Hp5pVt/21I= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 h1:LAfOuhAH331fmOjTQpAaOlH+Ftn7RzSDJ2VFwjdMMy4= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18/go.mod h1:4e5xhuXHx1e4U9EthvbPP1r/DIMp5c2823OL8karzcM= github.com/aws/aws-sdk-go-v2/config v1.32.39 h1:3TYUWYWawsE9KF02G3dA7vsbwoCphyGOpFFEUugRs/4= github.com/aws/aws-sdk-go-v2/config v1.32.39/go.mod h1:/lPP/ciQurgJa6l6mbBX+b5MB1qaLrC9dd3YHtGvrhk= github.com/aws/aws-sdk-go-v2/credentials v1.19.38 h1:Xf8j1+vzwPRCta9pFXjj0677BzXrRO2JbpAVNcdXnnI= @@ -117,16 +115,13 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= github.com/containerd/accelerated-container-image v1.3.0 h1:sFbTgSuMboeKHa9f7MY11hWF1XxVWjFoiTsXYtOtvdU= @@ -179,8 +174,8 @@ github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= -github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is= -github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= +github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= +github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ= github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -202,18 +197,14 @@ github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQ github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erofs/go-erofs v0.3.0 h1:o/W5ABAA3sHYl97WL93dacKEfeDpJhdFf3c2snAti7I= github.com/erofs/go-erofs v0.3.0/go.mod h1:XkSeN9MHszGd4+3gcEjadJLYHCQpWzJ7/8yznzMuzJs= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -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/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM= @@ -224,8 +215,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +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.2 h1:I0vy4n3alz+DHTiN1PRhCb7QZxkK6g5YmswZKv2TKuw= @@ -294,31 +285,16 @@ github.com/gohugoio/hashstructure v0.6.0 h1:7wMB/2CfXoThFYhdWRGv3u3rUM761Cq29CxU github.com/gohugoio/hashstructure v0.6.0/go.mod h1:lapVLk9XidheHG1IQ4ZSbyYrXcaILU1ZEP/+vno5rBQ= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/certificate-transparency-go v1.3.3 h1:hq/rSxztSkXN2tx/3jQqF6Xc0O565UQPdHrOWvZwybo= github.com/google/certificate-transparency-go v1.3.3/go.mod h1:iR17ZgSaXRzSa5qvjFl8TnVD5h8ky2JMVio+dzoKMgA= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-containerregistry v0.21.7 h1:/vPFuVXDjtFREsVArW+0h1CIl5urnOhzei4X2DMW9IU= @@ -333,7 +309,6 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/trillian v1.7.3 h1:hziW+vo4czis48tzx2GK5xRBl/ZxBA9B0/UR5avXOro= github.com/google/trillian v1.7.3/go.mod h1:qh8iy4x/GvnVXUBd5pK4oncuT1Y9vVYfibQVsR/WpKg= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.16 h1:F/VPrx0YPBdksZJQdCAp0WUsqnNmZpUZszzfYt0M5Dw= @@ -473,8 +448,8 @@ github.com/opencontainers/selinux v1.15.1/go.mod h1:LenyElirjUHszfxrjuFqC85HIeXZ github.com/package-url/packageurl-go v0.1.1 h1:KTRE0bK3sKbFKAk3yy63DpeskU7Cvs/x/Da5l+RtzyU= github.com/package-url/packageurl-go v0.1.1/go.mod h1:uQd4a7Rh3ZsVg5j0lNyAfyxIeGde9yrlhjF78GzeW0c= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc= -github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY= +github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -490,24 +465,23 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -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_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= -github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +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/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= -github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= +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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= @@ -547,8 +521,8 @@ github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.10.8/go.mod h1:6IDF github.com/sigstore/timestamp-authority/v2 v2.1.2 h1:7DDhnknLL4w8VwomyvW2W8qblOS9LDR8oihna+jc7Ls= github.com/sigstore/timestamp-authority/v2 v2.1.2/go.mod h1:o6rAVZceFyejClIj/uStRNIemP16bVMZtbMmhk6pr0U= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= -github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q= +github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk= github.com/spdx/tools-golang v0.5.7 h1:+sWcKGnhwp3vLdMqPcLdA6QK679vd86cK9hQWH3AwCg= github.com/spdx/tools-golang v0.5.7/go.mod h1:jg7w0LOpoNAw6OxKEzCoqPC2GCTj45LyTlVmXubDsYw= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= @@ -558,14 +532,12 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= @@ -620,44 +592,42 @@ github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97 github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= go.etcd.io/bbolt v1.5.0 h1:S7GAl7Fxv12yohbwFfIbQCGDWbQbtDGPET4P/bD4lxU= go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 h1:2yEATaop1/a1I4psnSLgWVPLWwCzkqWakgJy7xTDVy0= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0 h1:MCcYL7J6Vt/X0kjqbMZkekCmwsurbQRbL69vkiye2lk= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0/go.mod h1:3jnStNwSufK+f5ktjL4EPcwtig4rtd81NS70lqHuXl8= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +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.70.0 h1:aVgLpGksz0vjoe6OynycqX8daNOAxJx5ZEhJXIXOVIU= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.70.0/go.mod h1:kmJlX6WuTrAH1fOCSbPJFrSnUagB8c3SY3E87It3JD8= +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/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 h1:SUplec5dp06reu1zaXmOXdvqH398taqrDXqUl99jxSc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0/go.mod h1:ho2g4N+ane+swq5I/VBkKWnRDY4kUINH3FuqyZqX/Ug= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 h1:RuynHbfU8JUEw7DyONgkVYg2SVtsoF28y0LGIr69jgA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0/go.mod h1:qZF+/lBs71APw8mlnEZcqZHMzqrYrsFiJOv83lX1OGo= -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/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s= -go.opentelemetry.io/otel/exporters/prometheus v0.66.0 h1:vkrK8PAznv2NKt2r+kdu252ccGzkEqLc2aSXbQIALYQ= -go.opentelemetry.io/otel/exporters/prometheus v0.66.0/go.mod h1:V/UB6D3vMF/UBOL5igAsAYnk1nG/bzYYTzvsB16cy7o= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= -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.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= -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/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 h1:klTViGcsvLCd1xN3rZzfZ12NslC/OimbmR+k+A006RI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0/go.mod h1:jRsK04CWmXuY8A0O+wMpSf+t90RHZ53o5Qmxn2PQPfk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0 h1:pnxy6c/kvNBWdNNFzqpjuJLm9Hjhgk/Q0nY221rwuk0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0/go.mod h1:qw6YsFapotRwoDhXRZvljzaOvCQB7UfnafEJagpN2TA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0 h1:QBajQ2SrwQijzHyZbQlPsuIzpl/ll8DY6wPWsajeGcI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0/go.mod h1:08ZQLjrPLQ6R4kAXvuOvODEer5Yh4CoFvll5qB2BCI8= +go.opentelemetry.io/otel/exporters/prometheus v0.67.0 h1:7IefDa35e6V3NoiqIeLDMDxMFyZDk5qcoC0Ax4cC16E= +go.opentelemetry.io/otel/exporters/prometheus v0.67.0/go.mod h1:nsPI1awTg5Vmg1YrommL2mVarVGlqc4yXOoKAkPRD0c= +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.67.0 h1:PcicCNZFkZ4bXfSooXdo3WN7RBOVOtjVdo1wD358Uns= +go.opentelemetry.io/otel/metric/x v0.67.0/go.mod h1:FBjCWZe6wgcqxcMtjdGiClDKXb2YxxXii0CXftE4QtI= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= +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/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk= +go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= go.step.sm/crypto v0.77.7 h1:6azC+pD678Vjju8yXnMDHCZJ+HzFaEmL3sCryiezTIA= go.step.sm/crypto v0.77.7/go.mod h1:OW/2sEHwTtDKq70PvSQ5B0JGy/CrLyDKOiVy3YvZMTQ= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -674,43 +644,26 @@ 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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= -golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +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-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q= golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -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/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= +golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -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/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -720,54 +673,28 @@ golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= 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.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.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/api v0.283.0 h1:0lkp8u0MPwJVHqRL+nJlMAoZVVzbmiXmFHXMOTmSPik= google.golang.org/api v0.283.0/go.mod h1:6Wssta4c5n9qHq5CBhmlai5h/PUa1djdDAIhYEHyvcM= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= -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-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 h1:/WILD1UcXj/ujCxgoL/DvRgt2CP3txG8+FwkUbb9110= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1/go.mod h1:YNKnb2OAApgYn2oYY47Rn7alMr1zWjb2U8Q0aoGWiNc= -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= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= -google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc= +google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig= +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/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.6.2 h1:rgSNvqscFZ1JgV/4wH5GOsZFSFkR2Eua9As3KIr2LlM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2/go.mod h1:iMEtFwDlAhjDU9L5mY6U1XLwlIId/G3h+QcBHDIvrJ8= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -779,8 +706,6 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= kernel.org/pub/linux/libs/security/libcap/cap v1.2.78 h1:jgqg4gyu2BaYW9L6uzEtGLf8GNREwk/z4UFdwt5F3pE= diff --git a/vendor/cyphar.com/go-pathrs/.golangci.yml b/vendor/cyphar.com/go-pathrs/.golangci.yml index 2778a3268..a28cbd2a4 100644 --- a/vendor/cyphar.com/go-pathrs/.golangci.yml +++ b/vendor/cyphar.com/go-pathrs/.golangci.yml @@ -1,8 +1,8 @@ # SPDX-License-Identifier: MPL-2.0 # # libpathrs: safe path resolution on Linux -# Copyright (C) 2019-2025 Aleksa Sarai # Copyright (C) 2019-2025 SUSE LLC +# Copyright (C) 2026 Aleksa Sarai # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/vendor/cyphar.com/go-pathrs/doc.go b/vendor/cyphar.com/go-pathrs/doc.go index a7ee4bc48..c3b4eedd0 100644 --- a/vendor/cyphar.com/go-pathrs/doc.go +++ b/vendor/cyphar.com/go-pathrs/doc.go @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/vendor/cyphar.com/go-pathrs/handle_linux.go b/vendor/cyphar.com/go-pathrs/handle_linux.go index 3221ef673..78225e006 100644 --- a/vendor/cyphar.com/go-pathrs/handle_linux.go +++ b/vendor/cyphar.com/go-pathrs/handle_linux.go @@ -3,8 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -17,6 +17,8 @@ import ( "fmt" "os" + "golang.org/x/sys/unix" + "cyphar.com/go-pathrs/internal/fdutils" "cyphar.com/go-pathrs/internal/libpathrs" ) @@ -30,11 +32,9 @@ import ( // you can try to use [Root.Open] or [Root.OpenFile]. // // It is critical that perform all relevant operations through this [Handle] -// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]), +// (rather than fetching the underlying [os.File] yourself with [Handle.IntoFile]), // because the security properties of libpathrs depend on users doing all // relevant filesystem operations through libpathrs. -// -// [os.File]: https://pkg.go.dev/os#File type Handle struct { inner *os.File } @@ -43,7 +43,7 @@ type Handle struct { // handle will be copied by this method, so the original handle should still be // freed by the caller. // -// This is effectively the inverse operation of [Handle.IntoRaw], and is used +// This is effectively the inverse operation of [Handle.IntoFile], and is used // for "deserialising" pathrs root handles. func HandleFromFile(file *os.File) (*Handle, error) { newFile, err := fdutils.DupFile(file) @@ -58,11 +58,11 @@ func HandleFromFile(file *os.File) (*Handle, error) { // and can be opened multiple times. // // The handle returned is only usable for reading, and this is method is -// shorthand for [Handle.OpenFile] with os.O_RDONLY. +// shorthand for [Handle.OpenFile] with [unix.O_RDONLY]. // // TODO: Rename these to "Reopen" or something. func (h *Handle) Open() (*os.File, error) { - return h.OpenFile(os.O_RDONLY) + return h.OpenFile(unix.O_RDONLY) } // OpenFile creates an "upgraded" file handle to the file referenced by the @@ -73,7 +73,7 @@ func (h *Handle) Open() (*os.File, error) { // handle. // // TODO: Rename these to "Reopen" or something. -func (h *Handle) OpenFile(flags int) (*os.File, error) { +func (h *Handle) OpenFile(flags uint64) (*os.File, error) { return fdutils.WithFileFd(h.inner, func(fd uintptr) (*os.File, error) { newFd, err := libpathrs.Reopen(fd, flags) if err != nil { @@ -92,8 +92,6 @@ func (h *Handle) OpenFile(flags int) (*os.File, error) { // calling [Handle.Close] will also close any copies of the returned [os.File]. // If you want to get an independent copy, use [Handle.Clone] followed by // [Handle.IntoFile] on the cloned [Handle]. -// -// [os.File]: https://pkg.go.dev/os#File func (h *Handle) IntoFile() *os.File { // TODO: Figure out if we really don't want to make a copy. // TODO: We almost certainly want to clear r.inner here, but we can't do diff --git a/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go b/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go index 41aea3e4b..418b29814 100644 --- a/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go +++ b/vendor/cyphar.com/go-pathrs/internal/fdutils/fd_linux.go @@ -3,8 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go b/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go index c9f416de0..8f610ca56 100644 --- a/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go +++ b/vendor/cyphar.com/go-pathrs/internal/libpathrs/error_unix.go @@ -5,8 +5,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go b/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go index c07b80e30..d610a3be4 100644 --- a/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go +++ b/vendor/cyphar.com/go-pathrs/internal/libpathrs/libpathrs_linux.go @@ -3,8 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -60,8 +60,8 @@ func OpenRoot(path string) (uintptr, error) { } // Reopen wraps pathrs_reopen. -func Reopen(fd uintptr, flags int) (uintptr, error) { - newFd := C.pathrs_reopen(C.int(fd), C.int(flags)) +func Reopen(fd uintptr, flags uint64) (uintptr, error) { + newFd := C.pathrs_reopen(C.int(fd), C.uint64_t(flags)) return uintptr(newFd), fetchError(newFd) } @@ -84,11 +84,11 @@ func InRootResolveNoFollow(rootFd uintptr, path string) (uintptr, error) { } // InRootOpen wraps pathrs_inroot_open. -func InRootOpen(rootFd uintptr, path string, flags int) (uintptr, error) { +func InRootOpen(rootFd uintptr, path string, flags uint64) (uintptr, error) { cPath := C.CString(path) defer C.free(unsafe.Pointer(cPath)) - fd := C.pathrs_inroot_open(C.int(rootFd), cPath, C.int(flags)) + fd := C.pathrs_inroot_open(C.int(rootFd), cPath, C.uint64_t(flags)) return uintptr(fd), fetchError(fd) } @@ -100,7 +100,7 @@ func InRootReadlink(rootFd uintptr, path string) (string, error) { size := 128 for { linkBuf := make([]byte, size) - n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf))) + n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.size_t(len(linkBuf))) switch { case int(n) < C.__PATHRS_MAX_ERR_VALUE: return "", fetchError(n) @@ -145,23 +145,23 @@ func InRootRemoveAll(rootFd uintptr, path string) error { } // InRootCreat wraps pathrs_inroot_creat. -func InRootCreat(rootFd uintptr, path string, flags int, mode uint32) (uintptr, error) { +func InRootCreat(rootFd uintptr, path string, flags uint64, mode uint32) (uintptr, error) { cPath := C.CString(path) defer C.free(unsafe.Pointer(cPath)) - fd := C.pathrs_inroot_creat(C.int(rootFd), cPath, C.int(flags), C.uint(mode)) + fd := C.pathrs_inroot_creat(C.int(rootFd), cPath, C.uint64_t(flags), C.uint(mode)) return uintptr(fd), fetchError(fd) } // InRootRename wraps pathrs_inroot_rename. -func InRootRename(rootFd uintptr, src, dst string, flags uint) error { - cSrc := C.CString(src) - defer C.free(unsafe.Pointer(cSrc)) +func InRootRename(oldRootFd uintptr, oldPath string, newRootFd uintptr, newPath string, flags uint64) error { + cOldPath := C.CString(oldPath) + defer C.free(unsafe.Pointer(cOldPath)) - cDst := C.CString(dst) - defer C.free(unsafe.Pointer(cDst)) + cNewPath := C.CString(newPath) + defer C.free(unsafe.Pointer(cNewPath)) - err := C.pathrs_inroot_rename(C.int(rootFd), cSrc, cDst, C.uint(flags)) + err := C.pathrs_inroot_rename(C.int(oldRootFd), cOldPath, C.int(newRootFd), cNewPath, C.uint64_t(flags)) return fetchError(err) } @@ -193,26 +193,26 @@ func InRootMknod(rootFd uintptr, path string, mode uint32, dev uint64) error { } // InRootSymlink wraps pathrs_inroot_symlink. -func InRootSymlink(rootFd uintptr, path, target string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) +func InRootSymlink(target string, rootFd uintptr, linkpath string) error { + cLinkpath := C.CString(linkpath) + defer C.free(unsafe.Pointer(cLinkpath)) cTarget := C.CString(target) defer C.free(unsafe.Pointer(cTarget)) - err := C.pathrs_inroot_symlink(C.int(rootFd), cPath, cTarget) + err := C.pathrs_inroot_symlink(cTarget, C.int(rootFd), cLinkpath) return fetchError(err) } // InRootHardlink wraps pathrs_inroot_hardlink. -func InRootHardlink(rootFd uintptr, path, target string) error { - cPath := C.CString(path) - defer C.free(unsafe.Pointer(cPath)) +func InRootHardlink(oldRootFd uintptr, oldPath string, newRootFd uintptr, newPath string, flags uint64) error { + cNewPath := C.CString(newPath) + defer C.free(unsafe.Pointer(cNewPath)) - cTarget := C.CString(target) - defer C.free(unsafe.Pointer(cTarget)) + cOldPath := C.CString(oldPath) + defer C.free(unsafe.Pointer(cOldPath)) - err := C.pathrs_inroot_hardlink(C.int(rootFd), cPath, cTarget) + err := C.pathrs_inroot_hardlink(C.int(oldRootFd), cOldPath, C.int(newRootFd), cNewPath, C.uint64_t(flags)) return fetchError(err) } @@ -277,13 +277,13 @@ func init() { func ProcPid(pid uint32) ProcBase { return ProcBaseTypePid | ProcBase(pid) } // ProcOpenat wraps pathrs_proc_openat. -func ProcOpenat(procRootFd int, base ProcBase, path string, flags int) (uintptr, error) { +func ProcOpenat(procRootFd int, base ProcBase, path string, flags uint64) (uintptr, error) { cBase := C.pathrs_proc_base_t(base) cPath := C.CString(path) defer C.free(unsafe.Pointer(cPath)) - fd := C.pathrs_proc_openat(C.int(procRootFd), cBase, cPath, C.int(flags)) + fd := C.pathrs_proc_openat(C.int(procRootFd), cBase, cPath, C.uint64_t(flags)) return uintptr(fd), fetchError(fd) } @@ -301,7 +301,7 @@ func ProcReadlinkat(procRootFd int, base ProcBase, path string) (string, error) linkBuf := make([]byte, size) n := C.pathrs_proc_readlinkat( C.int(procRootFd), cBase, cPath, - C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf))) + C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.size_t(len(linkBuf))) switch { case int(n) < C.__PATHRS_MAX_ERR_VALUE: return "", fetchError(n) @@ -335,3 +335,31 @@ func ProcfsOpen(how *ProcfsOpenHow) (uintptr, error) { fd := C.pathrs_procfs_open((*C.pathrs_procfs_open_how)(how), C.size_t(unsafe.Sizeof(*how))) return uintptr(fd), fetchError(fd) } + +// VersionInfo is a Go-friendly form of pathrs_version_info_t (struct). +type VersionInfo struct { + VersionString string +} + +// versionInfo is pathrs_version_info_t (struct). +type versionInfo C.pathrs_version_info_t + +// Version is pathrs_version_info_t (sizeof(version) is passed automatically). +func Version() (*VersionInfo, error) { + var rawVersion versionInfo + size := C.pathrs_version((*C.pathrs_version_info_t)(&rawVersion), C.size_t(unsafe.Sizeof(rawVersion))) + switch { + case size < 0: + return nil, fetchError(size) + case size > 0: + // TODO(log): Logging? + fallthrough + default: + // TODO(log): Add a log statement if sizeof(rawVersion) is bigger than + // the number of fields we store in VersionInfo. Otherwise a rebuild + // will mask that Go callers cannot see any new fields. + return &VersionInfo{ + VersionString: C.GoString(rawVersion.version_string), + }, nil + } +} diff --git a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go index 5533c427c..6a3142646 100644 --- a/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go +++ b/vendor/cyphar.com/go-pathrs/procfs/procfs_linux.go @@ -3,8 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -56,16 +56,15 @@ var ( // *before* you call wait(2)or any equivalent method that could reap // zombies). func ProcPid(pid int) ProcBase { - if pid < 0 || pid >= 1<<31 { + if pid < 0 || uint64(pid) >= 1<<31 { panic("invalid ProcBasePid value") // TODO: should this be an error? } - return ProcBase{inner: libpathrs.ProcPid(uint32(pid))} + pid32 := uint32(pid) //nolint:gosec // G115 false positive + return ProcBase{inner: libpathrs.ProcPid(pid32)} } // ThreadCloser is a callback that needs to be called when you are done // operating on an [os.File] fetched using [Handle.OpenThreadSelf]. -// -// [os.File]: https://pkg.go.dev/os#File type ThreadCloser func() // Handle is a wrapper around an *os.File handle to "/proc", which can be @@ -128,7 +127,7 @@ func (proc *Handle) fd() int { } // TODO: Should we expose open? -func (proc *Handle) open(base ProcBase, path string, flags int) (_ *os.File, Closer ThreadCloser, Err error) { +func (proc *Handle) open(base ProcBase, path string, flags uint64) (_ *os.File, Closer ThreadCloser, Err error) { var closer ThreadCloser if base == ProcThreadSelf { runtime.LockOSThread() @@ -155,7 +154,7 @@ func (proc *Handle) open(base ProcBase, path string, flags int) (_ *os.File, Clo // (such as /proc/cpuinfo) or information about other processes (such as // /proc/1). Accessing your own process information should be done using // [Handle.OpenSelf] or [Handle.OpenThreadSelf]. -func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) { +func (proc *Handle) OpenRoot(path string, flags uint64) (*os.File, error) { file, closer, err := proc.open(ProcRoot, path, flags) if closer != nil { // should not happen @@ -181,9 +180,7 @@ func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) { // Unlike [Handle.OpenThreadSelf], this method does not involve locking // the goroutine to the current OS thread and so is simpler to use and // theoretically has slightly less overhead. -// -// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread -func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) { +func (proc *Handle) OpenSelf(path string, flags uint64) (*os.File, error) { file, closer, err := proc.open(ProcSelf, path, flags) if closer != nil { // should not happen @@ -201,7 +198,7 @@ func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) { // Be aware that due to PID recycling, using this is generally not safe except // in certain circumstances. See the documentation of [ProcPid] for more // details. -func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) { +func (proc *Handle) OpenPid(pid int, path string, flags uint64) (*os.File, error) { file, closer, err := proc.open(ProcPid(pid), path, flags) if closer != nil { // should not happen @@ -228,11 +225,7 @@ func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) { // callback MUST be called AFTER you have finished using the returned // [os.File]. This callback is completely separate to [os.File.Close], so it // must be called regardless of how you close the handle. -// -// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread -// [os.File]: https://pkg.go.dev/os#File -// [os.File.Close]: https://pkg.go.dev/os#File.Close -func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) { +func (proc *Handle) OpenThreadSelf(path string, flags uint64) (*os.File, ThreadCloser, error) { return proc.open(ProcThreadSelf, path, flags) } diff --git a/vendor/cyphar.com/go-pathrs/root_linux.go b/vendor/cyphar.com/go-pathrs/root_linux.go index edc9e4c87..4741a24a4 100644 --- a/vendor/cyphar.com/go-pathrs/root_linux.go +++ b/vendor/cyphar.com/go-pathrs/root_linux.go @@ -3,8 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -19,6 +19,8 @@ import ( "os" "syscall" + "golang.org/x/sys/unix" + "cyphar.com/go-pathrs/internal/fdutils" "cyphar.com/go-pathrs/internal/libpathrs" ) @@ -27,7 +29,7 @@ import ( // purpose of this "root handle" is to perform operations within the directory // tree, or to get a [Handle] to inodes within the directory tree. // -// At time of writing, it is considered a *VERY BAD IDEA* to open a [Root] +// At time of writing, it is considered a *VERY BAD IDEA* to open a Root // inside a possibly-attacker-controlled directory tree. While we do have // protections that should defend against it, it's far more dangerous than just // opening a directory tree which is not inside a potentially-untrusted @@ -54,8 +56,6 @@ func OpenRoot(path string) (*Root, error) { // still be closed by the caller. // // This is effectively the inverse operation of [Root.IntoFile]. -// -// [os.File]: https://pkg.go.dev/os#File func RootFromFile(file *os.File) (*Root, error) { newFile, err := fdutils.DupFile(file) if err != nil { @@ -70,7 +70,7 @@ func RootFromFile(file *os.File) (*Root, error) { // // All symlinks (including trailing symlinks) are followed, but they are // resolved within the rootfs. If you wish to open a handle to the symlink -// itself, use [ResolveNoFollow]. +// itself, use [Root.ResolveNoFollow]. func (r *Root) Resolve(path string) (*Handle, error) { return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { handleFd, err := libpathrs.InRootResolve(rootFd, path) @@ -85,10 +85,10 @@ func (r *Root) Resolve(path string) (*Handle, error) { }) } -// ResolveNoFollow is effectively an O_NOFOLLOW version of [Resolve]. Their -// behaviour is identical, except that *trailing* symlinks will not be -// followed. If the final component is a trailing symlink, an O_PATH|O_NOFOLLOW -// handle to the symlink itself is returned. +// ResolveNoFollow is effectively an [unix.O_NOFOLLOW] version of +// [Root.Resolve]. Their behaviour is identical, except that *trailing* +// symlinks will not be followed. If the final component is a trailing symlink, +// an [unix.O_PATH]|[unix.O_NOFOLLOW] handle to the symlink itself is returned. func (r *Root) ResolveNoFollow(path string) (*Handle, error) { return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) { handleFd, err := libpathrs.InRootResolveNoFollow(rootFd, path) @@ -103,33 +103,29 @@ func (r *Root) ResolveNoFollow(path string) (*Handle, error) { }) } -// Open is effectively shorthand for [Resolve] followed by [Handle.Open], but -// can be slightly more efficient (it reduces CGo overhead and the number of -// syscalls used when using the openat2-based resolver) and is arguably more +// Open is effectively shorthand for [Root.Resolve] followed by [Handle.Open], +// but can be slightly more efficient (it reduces CGo overhead and the number +// of syscalls used when using the openat2-based resolver) and is arguably more // ergonomic to use. // // This is effectively equivalent to [os.Open]. -// -// [os.Open]: https://pkg.go.dev/os#Open func (r *Root) Open(path string) (*os.File, error) { - return r.OpenFile(path, os.O_RDONLY) + return r.OpenFile(path, unix.O_RDONLY) } -// OpenFile is effectively shorthand for [Resolve] followed by +// OpenFile is effectively shorthand for [Root.Resolve] followed by // [Handle.OpenFile], but can be slightly more efficient (it reduces CGo // overhead and the number of syscalls used when using the openat2-based // resolver) and is arguably more ergonomic to use. // -// However, if flags contains os.O_NOFOLLOW and the path is a symlink, then +// However, if flags contains [unix.O_NOFOLLOW] and the path is a symlink, then // OpenFile's behaviour will match that of openat2. In most cases an error will -// be returned, but if os.O_PATH is provided along with os.O_NOFOLLOW then a -// file equivalent to [ResolveNoFollow] will be returned instead. +// be returned, but if [unix.O_PATH] is provided along with [unix.O_NOFOLLOW] +// then a file equivalent to [Root.ResolveNoFollow] will be returned instead. // -// This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is -// not supported. -// -// [os.OpenFile]: https://pkg.go.dev/os#OpenFile -func (r *Root) OpenFile(path string, flags int) (*os.File, error) { +// This is effectively equivalent to [os.OpenFile], except that [unix.O_CREAT] +// is not supported. +func (r *Root) OpenFile(path string, flags uint64) (*os.File, error) { return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) { fd, err := libpathrs.InRootOpen(rootFd, path, flags) if err != nil { @@ -145,9 +141,7 @@ func (r *Root) OpenFile(path string, flags int) (*os.File, error) { // // Unlike [os.Create], if the file already exists an error is created rather // than the file being opened and truncated. -// -// [os.Create]: https://pkg.go.dev/os#Create -func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) { +func (r *Root) Create(path string, flags uint64, mode os.FileMode) (*os.File, error) { unixMode, err := toUnixMode(mode, false) if err != nil { return nil, err @@ -163,9 +157,9 @@ func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error // Rename two paths within a [Root]'s directory tree. The flags argument is // identical to the RENAME_* flags to the renameat2(2) system call. -func (r *Root) Rename(src, dst string, flags uint) error { +func (r *Root) Rename(src, dst string, flags uint64) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootRename(rootFd, src, dst, flags) + err := libpathrs.InRootRename(rootFd, src, rootFd, dst, flags) return struct{}{}, err }) return err @@ -194,8 +188,6 @@ func (r *Root) RemoveFile(path string) error { // directory tree. // // This is effectively equivalent to [os.Remove]. -// -// [os.Remove]: https://pkg.go.dev/os#Remove func (r *Root) Remove(path string) error { // In order to match os.Remove's implementation we need to also do both // syscalls unconditionally and adjust the error based on whether @@ -219,8 +211,6 @@ func (r *Root) Remove(path string) error { // RemoveAll recursively deletes a path and all of its children. // // This is effectively equivalent to [os.RemoveAll]. -// -// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll func (r *Root) RemoveAll(path string) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { err := libpathrs.InRootRemoveAll(rootFd, path) @@ -233,8 +223,6 @@ func (r *Root) RemoveAll(path string) error { // mode is used for the new directory (the process's umask applies). // // This is effectively equivalent to [os.Mkdir]. -// -// [os.Mkdir]: https://pkg.go.dev/os#Mkdir func (r *Root) Mkdir(path string, mode os.FileMode) error { unixMode, err := toUnixMode(mode, false) if err != nil { @@ -253,8 +241,6 @@ func (r *Root) Mkdir(path string, mode os.FileMode) error { // directories created by this function (the process's umask applies). // // This is effectively equivalent to [os.MkdirAll]. -// -// [os.MkdirAll]: https://pkg.go.dev/os#MkdirAll func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { unixMode, err := toUnixMode(mode, false) if err != nil { @@ -278,9 +264,7 @@ func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) { // directory tree. The provided mode is used for the new directory (the // process's umask applies). // -// This is effectively equivalent to [unix.Mknod]. -// -// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod +// This is effectively equivalent to [golang.org/x/sys/unix.Mknod]. func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error { unixMode, err := toUnixMode(mode, true) if err != nil { @@ -295,30 +279,26 @@ func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error { } // Symlink creates a symlink within a [Root]'s directory tree. The symlink is -// created at path and is a link to target. +// created at newname and is a link to oldname. // // This is effectively equivalent to [os.Symlink]. -// -// [os.Symlink]: https://pkg.go.dev/os#Symlink -func (r *Root) Symlink(path, target string) error { +func (r *Root) Symlink(oldname, newname string) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootSymlink(rootFd, path, target) + err := libpathrs.InRootSymlink(oldname, rootFd, newname) return struct{}{}, err }) return err } // Hardlink creates a hardlink within a [Root]'s directory tree. The hardlink -// is created at path and is a link to target. Both paths are within the +// is created at newname and is a link to oldname. Both paths are within the // [Root]'s directory tree (you cannot hardlink to a different [Root] or the // host). // // This is effectively equivalent to [os.Link]. -// -// [os.Link]: https://pkg.go.dev/os#Link -func (r *Root) Hardlink(path, target string) error { +func (r *Root) Hardlink(oldname, newname string) error { _, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) { - err := libpathrs.InRootHardlink(rootFd, path, target) + err := libpathrs.InRootHardlink(rootFd, oldname, rootFd, newname, 0) return struct{}{}, err }) return err @@ -327,8 +307,6 @@ func (r *Root) Hardlink(path, target string) error { // Readlink returns the target of a symlink with a [Root]'s directory tree. // // This is effectively equivalent to [os.Readlink]. -// -// [os.Readlink]: https://pkg.go.dev/os#Readlink func (r *Root) Readlink(path string) (string, error) { return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) { return libpathrs.InRootReadlink(rootFd, path) @@ -345,8 +323,6 @@ func (r *Root) Readlink(path string) (string, error) { // calling [Root.Close] will also close any copies of the returned [os.File]. // If you want to get an independent copy, use [Root.Clone] followed by // [Root.IntoFile] on the cloned [Root]. -// -// [os.File]: https://pkg.go.dev/os#File func (r *Root) IntoFile() *os.File { // TODO: Figure out if we really don't want to make a copy. // TODO: We almost certainly want to clear r.inner here, but we can't do diff --git a/vendor/cyphar.com/go-pathrs/utils_linux.go b/vendor/cyphar.com/go-pathrs/utils_linux.go index 2208d608f..b4e7e08e7 100644 --- a/vendor/cyphar.com/go-pathrs/utils_linux.go +++ b/vendor/cyphar.com/go-pathrs/utils_linux.go @@ -3,8 +3,8 @@ // SPDX-License-Identifier: MPL-2.0 /* * libpathrs: safe path resolution on Linux - * Copyright (C) 2019-2025 Aleksa Sarai * Copyright (C) 2019-2025 SUSE LLC + * Copyright (C) 2026 Aleksa Sarai * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/vendor/cyphar.com/go-pathrs/version_linux.go b/vendor/cyphar.com/go-pathrs/version_linux.go new file mode 100644 index 000000000..9ed2d74ec --- /dev/null +++ b/vendor/cyphar.com/go-pathrs/version_linux.go @@ -0,0 +1,27 @@ +//go:build linux + +// SPDX-License-Identifier: MPL-2.0 +/* + * libpathrs: safe path resolution on Linux + * Copyright (C) 2026 Aleksa Sarai + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package pathrs + +import ( + "cyphar.com/go-pathrs/internal/libpathrs" +) + +// LibraryVersionInfo contains information about the version and features +// supported by the underlying libpathrs.so library at runtime. +type LibraryVersionInfo = libpathrs.VersionInfo + +// LibraryVersion returns information about the version and features supported +// by the underlying libpathrs.so library at runtime. +func LibraryVersion() (*LibraryVersionInfo, error) { + return libpathrs.Version() +} diff --git a/vendor/github.com/Microsoft/hcsshim/.gitignore b/vendor/github.com/Microsoft/hcsshim/.gitignore index 74b68f0ad..2e6968186 100644 --- a/vendor/github.com/Microsoft/hcsshim/.gitignore +++ b/vendor/github.com/Microsoft/hcsshim/.gitignore @@ -4,6 +4,11 @@ *.so *.dylib +# manifest related generated files +*.syso +manifest.xml +*.exe.manifest + # Ignore vscode setting files .vscode/ .idea/ @@ -51,3 +56,5 @@ go.work.sum # keys and related artifacts *.pem *.cose + +rust/target/ \ No newline at end of file diff --git a/vendor/github.com/Microsoft/hcsshim/Makefile b/vendor/github.com/Microsoft/hcsshim/Makefile index 0c4642226..9a7a47fcc 100644 --- a/vendor/github.com/Microsoft/hcsshim/Makefile +++ b/vendor/github.com/Microsoft/hcsshim/Makefile @@ -5,6 +5,11 @@ include Makefile.bootfiles # enable loading kernel modules in init KMOD:=0 +# whether the base rootfs uses a usr-merged layout (i.e. /bin is a symlink to +# /usr/bin). This defaults to disabled; set USR_MERGED_ROOTFS=1 for a +# usr-merged base rootfs such as Azure Linux. +USR_MERGED_ROOTFS:=0 + CFLAGS:=-O2 -Wall LDFLAGS:=-static -s #strip C binaries LDLIBS:= @@ -89,7 +94,12 @@ out/delta-snp.tar.gz: out/delta.tar.gz bin/internal/tools/snp-report boot/startu out/delta.tar.gz: bin/init bin/vsockexec bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths Makefile @mkdir -p out rm -rf rootfs - mkdir -p rootfs/bin/ +ifeq "$(USR_MERGED_ROOTFS)" "1" + mkdir -p rootfs/usr/bin + ln -s usr/bin rootfs/bin +else + mkdir -p rootfs/bin +endif mkdir -p rootfs/info/ cp bin/init rootfs/ cp bin/vsockexec rootfs/bin/ diff --git a/vendor/github.com/Microsoft/hcsshim/Protobuild.toml b/vendor/github.com/Microsoft/hcsshim/Protobuild.toml index 17145bb25..d1fdaa6f1 100644 --- a/vendor/github.com/Microsoft/hcsshim/Protobuild.toml +++ b/vendor/github.com/Microsoft/hcsshim/Protobuild.toml @@ -6,7 +6,7 @@ generators = ["go", "go-grpc"] before = ["./protobuf"] # defaults are "/usr/local/include" and "/usr/include", which don't exist on Windows. - # override defaults to supress errors about non-existant directories. + # override defaults to supress errors about non-existent directories. after = [] # This section maps protobuf imports to Go packages. @@ -19,7 +19,8 @@ prefixes = [ "github.com/Microsoft/hcsshim/internal/shimdiag", "github.com/Microsoft/hcsshim/internal/extendedtask", "github.com/Microsoft/hcsshim/internal/computeagent", + "github.com/Microsoft/hcsshim/internal/controller", "github.com/Microsoft/hcsshim/internal/ncproxyttrpc", - "github.com/Microsoft/hcsshim/internal/vmservice", + "github.com/Microsoft/hcsshim/pkg/migration", ] generators = ["go", "go-ttrpc"] diff --git a/vendor/github.com/Microsoft/hcsshim/README.md b/vendor/github.com/Microsoft/hcsshim/README.md index ae6668263..7610b5602 100644 --- a/vendor/github.com/Microsoft/hcsshim/README.md +++ b/vendor/github.com/Microsoft/hcsshim/README.md @@ -44,7 +44,7 @@ delta.tar.gz initrd.img rootfs.tar.gz ### Containerd Shim -For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md). +For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md). Contrary to the typical Linux architecture of shim -> runc, the runhcs shim is used both to launch and manage the lifetime of containers. @@ -68,6 +68,105 @@ To trial using the shim out with ctr.exe: C:\> ctr.exe run --runtime io.containerd.runhcs.v1 --rm mcr.microsoft.com/windows/nanoserver:2004 windows-test cmd /c "echo Hello World!" ``` +### Containerd Shim V2 + +The V2 shims are the rewrite of the Windows containerd shim. The V1 shim +([`containerd-shim-runhcs-v1`](./cmd/containerd-shim-runhcs-v1)) is a single, monolithic +binary that handles LCOW (Linux Containers on Windows), Hyper-V WCOW (Windows Containers on Windows), process-isolated +WCOW and host-process containers. In the V2 model that monolith is split into focused, +per-platform shims, each backed 1:1 by a sandbox. + +V2 shims are used with containerd in the same way as the V1 shim, but the +API surface they expose is different. The V1 shim implemented only the containerd +[Task API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md), +and used it to manage both the sandbox lifecycle and the container/process (task) +lifecycle through a single service. Each V2 shim instead splits these responsibilities +across the two APIs that containerd now provides for this purpose: the +[Sandbox API](https://github.com/containerd/containerd/blob/main/docs/sandbox-api.md) +is used to manage the sandbox, while the +[Task API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md) +is used to manage containers and processes running inside it. Internally each V2 shim +implements these as separate sandbox and task services, alongside an auxiliary +`shimdiag` service used for diagnostics. + +All three shims honor the same CRI pod model. A task annotated with +`"io.kubernetes.cri.container-type": "sandbox"` is treated as the pause/infra container +that creates the pod; sibling workload tasks set `"io.kubernetes.cri.container-type": +"container"` and reference their pause via `"io.kubernetes.cri.sandbox-id"`. What a +"sandbox" *physically* corresponds to depends on the shim, and is described in each +subsection below. + +#### containerd-shim-lcow-v2 + +- **Purpose:** Runs Linux Containers on Windows (LCOW) — a Linux utility VM hosting Linux + containers. +- **Sandbox:** The Linux UVM. Each shim instance is backed 1:1 by a single UVM. This shim supports running + *multiple pods in the same UVM*, so a single shim instance may host more than one + CRI pods. +- **Tasks:** Linux containers and processes running inside the UVM, identified via the + same CRI annotations described above. +- **Implementation:** [`./cmd/containerd-shim-lcow-v2`](./cmd/containerd-shim-lcow-v2). +- **Build Tag:** lcow +- **Platform requirement:** Windows Server 2025 (build 26100) or later. + +#### containerd-shim-wcow-v2 + +- **Purpose:** Runs Hyper-V isolated Windows containers (WCOW) — a Windows utility VM hosting + Process and/or Host Process Containers inside it. +- **Sandbox:** The Windows utility VM (UVM). Each shim instance is backed 1:1 by a single UVM. +- **Tasks:** the Windows containers and processes running inside the UVM, identified + via the standard CRI annotations described above. +- **Implementation:** coming soon. +- **Build Tag:** wcow + +#### containerd-shim-process-v2 + +- **Purpose:** Runs Process-isolated Windows Server containers and Host + Process Containers — workloads that execute directly on the host with no utility VM. +- **Sandbox:** A *pause container*. The pause container is a minimal, long-lived + container that owns the pod's shared resources (such as the network namespace) and + keeps them alive while sibling workload containers are started, stopped or replaced. + This is the standard Kubernetes pod model: the pause container is the sandbox that + the rest of the pod attaches to. +- **Tasks:** the actual workload containers belonging to the pod, linked back to the + pause via the `io.kubernetes.cri.sandbox-id` annotation. +- **Implementation:** coming soon. +- **Build Tag:** process + +##### Building + +The V2 shim sources are guarded by the build tags as mentioned above, so the tag must be passed +to `go build`. For example the `LCOW` shim has `lcow` tag- + +```powershell +C:\> $env:GOOS="windows" +C:\> go build -tags lcow .\cmd\containerd-shim-lcow-v2 +``` + +Place the resulting `containerd-shim-lcow-v2.exe` in the same directory as `containerd.exe`, +the same as for the V1 shim. + +##### Running unit tests + +The shim's unit tests (and the rest of the tagged packages) are run with the +shim specific build tag: + +```powershell +C:\> go test -tags lcow ./... +``` + +##### Running parity tests + +The repository ships parity tests under [`./test/parity`](./test/parity) that feed +identical inputs through the legacy V1 and the new V2 pipelines and assert that the +resulting HCS ComputeSystem documents are equivalent. They live in the `test` Go +module and are also built with the build tag: + +```powershell +C:\> cd test +C:\> go test -tags lcow ./parity/... +``` + ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a diff --git a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.pb.go b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.pb.go index 57706556e..ca6a0d94e 100644 --- a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.pb.go +++ b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.12 // protoc v5.26.0 // source: github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto @@ -187,8 +187,9 @@ type Options struct { // no_inherit_host_timezone specifies to skip inheriting the hosts time zone for WCOW UVMs and instead default to // UTC. NoInheritHostTimezone bool `protobuf:"varint,19,opt,name=no_inherit_host_timezone,json=noInheritHostTimezone,proto3" json:"no_inherit_host_timezone,omitempty"` - // scrub_logs enables removing environment variables and other potentially sensitive information from logs - ScrubLogs bool `protobuf:"varint,20,opt,name=scrub_logs,json=scrubLogs,proto3" json:"scrub_logs,omitempty"` + // scrub_logs controls removing environment variables and other potentially sensitive information from logs. + // If unset, scrubbing is enabled by default. Set explicitly to false to disable. + ScrubLogs *bool `protobuf:"varint,20,opt,name=scrub_logs,json=scrubLogs,proto3,oneof" json:"scrub_logs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -357,8 +358,8 @@ func (x *Options) GetNoInheritHostTimezone() bool { } func (x *Options) GetScrubLogs() bool { - if x != nil { - return x.ScrubLogs + if x != nil && x.ScrubLogs != nil { + return *x.ScrubLogs } return false } @@ -477,7 +478,7 @@ var File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runh const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runhcs_proto_rawDesc = "" + "\n" + - "Ogithub.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto\x12\x14containerd.runhcs.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xd9\t\n" + + "Ogithub.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto\x12\x14containerd.runhcs.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xed\t\n" + "\aOptions\x12\x14\n" + "\x05debug\x18\x01 \x01(\bR\x05debug\x12F\n" + "\n" + @@ -501,9 +502,9 @@ const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_ru "\tlog_level\x18\x10 \x01(\tR\blogLevel\x124\n" + "\x17io_retry_timeout_in_sec\x18\x11 \x01(\x05R\x13ioRetryTimeoutInSec\x12\x82\x01\n" + "\x1ddefault_container_annotations\x18\x12 \x03(\v2>.containerd.runhcs.v1.Options.DefaultContainerAnnotationsEntryR\x1bdefaultContainerAnnotations\x127\n" + - "\x18no_inherit_host_timezone\x18\x13 \x01(\bR\x15noInheritHostTimezone\x12\x1d\n" + + "\x18no_inherit_host_timezone\x18\x13 \x01(\bR\x15noInheritHostTimezone\x12\"\n" + "\n" + - "scrub_logs\x18\x14 \x01(\bR\tscrubLogs\x1aN\n" + + "scrub_logs\x18\x14 \x01(\bH\x00R\tscrubLogs\x88\x01\x01\x1aN\n" + " DefaultContainerAnnotationsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\")\n" + @@ -514,7 +515,8 @@ const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_ru "\x10SandboxIsolation\x12\v\n" + "\aPROCESS\x10\x00\x12\x0e\n" + "\n" + - "HYPERVISOR\x10\x01\"\xb6\x03\n" + + "HYPERVISOR\x10\x01B\r\n" + + "\v_scrub_logs\"\xb6\x03\n" + "\x0eProcessDetails\x12\x1d\n" + "\n" + "image_name\x18\x01 \x01(\tR\timageName\x129\n" + @@ -570,6 +572,7 @@ func file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_run if File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runhcs_proto != nil { return } + file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runhcs_proto_msgTypes[0].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto index 8546c6150..b913f3c34 100644 --- a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto +++ b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto @@ -105,8 +105,9 @@ message Options { // UTC. bool no_inherit_host_timezone = 19; - // scrub_logs enables removing environment variables and other potentially sensitive information from logs - bool scrub_logs = 20; + // scrub_logs controls removing environment variables and other potentially sensitive information from logs. + // If unset, scrubbing is enabled by default. Set explicitly to false to disable. + optional bool scrub_logs = 20; } // ProcessDetails contains additional information about a process. This is the additional diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go b/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go index 301a10888..499c5727e 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/attach.go @@ -6,9 +6,9 @@ import ( "context" "encoding/json" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" ) // AttachLayerStorageFilter sets up the layer storage filter on a writable @@ -20,11 +20,11 @@ import ( // `layerData` is the parent read-only layer data. func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData LayerData) (err error) { title := "hcsshim::AttachLayerStorageFilter" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("layerPath", layerPath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("layerPath", layerPath), ) bytes, err := json.Marshal(layerData) @@ -48,11 +48,11 @@ func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData L // `layerData` is the parent read-only layer data. func AttachOverlayFilter(ctx context.Context, volumePath string, layerData LayerData) (err error) { title := "hcsshim::AttachOverlayFilter" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("volumePath", volumePath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("volumePath", volumePath), ) bytes, err := json.Marshal(layerData) diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go b/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go index 5058d3b55..93494a1ce 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/destroy.go @@ -4,10 +4,10 @@ package computestorage import ( "context" + "go.opentelemetry.io/otel/attribute" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" - "go.opencensus.io/trace" ) // DestroyLayer deletes a container layer. @@ -15,10 +15,10 @@ import ( // `layerPath` is a path to a directory containing the layer to export. func DestroyLayer(ctx context.Context, layerPath string) (err error) { title := "hcsshim::DestroyLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("layerPath", layerPath)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("layerPath", layerPath)) err = hcsDestroyLayer(layerPath) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go b/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go index 6e00e4a1f..9112e4f8d 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/detach.go @@ -7,9 +7,9 @@ import ( "encoding/json" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" ) // DetachLayerStorageFilter detaches the layer storage filter on a writable container layer. @@ -17,10 +17,10 @@ import ( // `layerPath` is a path to a directory containing the layer to export. func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) { title := "hcsshim::DetachLayerStorageFilter" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("layerPath", layerPath)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("layerPath", layerPath)) err = hcsDetachLayerStorageFilter(layerPath) if err != nil { @@ -34,10 +34,10 @@ func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) // `volumePath` is a path to writable container volume. func DetachOverlayFilter(ctx context.Context, volumePath string, filterType hcsschema.FileSystemFilterType) (err error) { title := "hcsshim::DetachOverlayFilter" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("volumePath", volumePath)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("volumePath", volumePath)) layerData := LayerData{} layerData.FilterType = filterType diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/export.go b/vendor/github.com/Microsoft/hcsshim/computestorage/export.go index c6370a5c9..e8a177b4f 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/export.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/export.go @@ -5,10 +5,10 @@ package computestorage import ( "context" "encoding/json" + "go.opentelemetry.io/otel/attribute" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" - "go.opencensus.io/trace" ) // ExportLayer exports a container layer. @@ -22,12 +22,12 @@ import ( // `options` are the export options applied to the exported layer. func ExportLayer(ctx context.Context, layerPath, exportFolderPath string, layerData LayerData, options ExportLayerOptions) (err error) { title := "hcsshim::ExportLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("layerPath", layerPath), - trace.StringAttribute("exportFolderPath", exportFolderPath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("layerPath", layerPath), + attribute.String("exportFolderPath", exportFolderPath), ) ldBytes, err := json.Marshal(layerData) diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/format.go b/vendor/github.com/Microsoft/hcsshim/computestorage/format.go index 2140e5c9f..cc0678f8c 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/format.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/format.go @@ -5,7 +5,7 @@ package computestorage import ( "context" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" "golang.org/x/sys/windows" ) @@ -20,9 +20,9 @@ import ( // that can be obtained from the virtdisk APIs. func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) { title := "hcsshim::FormatWritableLayerVhd" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + defer func() { ot.SetSpanStatus(span, err) }() err = hcsFormatWritableLayerVhd(vhdHandle) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/import.go b/vendor/github.com/Microsoft/hcsshim/computestorage/import.go index e1c87416a..87c2a7d61 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/import.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/import.go @@ -6,9 +6,9 @@ import ( "context" "encoding/json" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" ) // ImportLayer imports a container layer. @@ -22,12 +22,12 @@ import ( // `layerData` is the parent layer data. func ImportLayer(ctx context.Context, layerPath, sourceFolderPath string, layerData LayerData) (err error) { title := "hcsshim::ImportLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("layerPath", layerPath), - trace.StringAttribute("sourceFolderPath", sourceFolderPath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("layerPath", layerPath), + attribute.String("sourceFolderPath", sourceFolderPath), ) bytes, err := json.Marshal(layerData) diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go b/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go index d0c621605..6878af7d7 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/initialize.go @@ -5,10 +5,10 @@ package computestorage import ( "context" "encoding/json" + "go.opentelemetry.io/otel/attribute" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" - "go.opencensus.io/trace" ) // InitializeWritableLayer initializes a writable layer for a container. @@ -19,11 +19,11 @@ import ( // `layerData` is the parent read-only layer data. func InitializeWritableLayer(ctx context.Context, layerPath string, layerData LayerData) (err error) { title := "hcsshim::InitializeWritableLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("layerPath", layerPath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("layerPath", layerPath), ) bytes, err := json.Marshal(layerData) diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go b/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go index 4f4d8ebf2..56fde0bd0 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/mount.go @@ -6,7 +6,7 @@ import ( "context" "github.com/Microsoft/hcsshim/internal/interop" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/pkg/errors" "golang.org/x/sys/windows" ) @@ -14,9 +14,9 @@ import ( // GetLayerVhdMountPath returns the volume path for a virtual disk of a writable container layer. func GetLayerVhdMountPath(ctx context.Context, vhdHandle windows.Handle) (path string, err error) { title := "hcsshim::GetLayerVhdMountPath" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + defer func() { ot.SetSpanStatus(span, err) }() var mountPath *uint16 err = hcsGetLayerVhdMountPath(vhdHandle, &mountPath) diff --git a/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go b/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go index 1c685aed0..bdbcde858 100644 --- a/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go +++ b/vendor/github.com/Microsoft/hcsshim/computestorage/setup.go @@ -6,10 +6,10 @@ import ( "context" "encoding/json" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/osversion" "github.com/pkg/errors" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" "golang.org/x/sys/windows" ) @@ -24,11 +24,11 @@ import ( // `options` are the options applied while processing the layer. func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.Handle, options OsLayerOptions) (err error) { title := "hcsshim::SetupBaseOSLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("layerPath", layerPath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("layerPath", layerPath), ) bytes, err := json.Marshal(options) @@ -59,12 +59,12 @@ func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, option return errors.New("SetupBaseOSVolume is not present on builds older than 19645") } title := "hcsshim::SetupBaseOSVolume" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("layerPath", layerPath), - trace.StringAttribute("volumePath", volumePath), + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("layerPath", layerPath), + attribute.String("volumePath", volumePath), ) bytes, err := json.Marshal(options) diff --git a/vendor/github.com/Microsoft/hcsshim/hcn/hcnnamespace.go b/vendor/github.com/Microsoft/hcsshim/hcn/hcnnamespace.go index e855f5a3a..5b93c4791 100644 --- a/vendor/github.com/Microsoft/hcsshim/hcn/hcnnamespace.go +++ b/vendor/github.com/Microsoft/hcsshim/hcn/hcnnamespace.go @@ -18,12 +18,12 @@ import ( // NamespaceResourceEndpoint represents an Endpoint attached to a Namespace. type NamespaceResourceEndpoint struct { - Id string `json:"ID,"` + Id string `json:"ID"` } // NamespaceResourceContainer represents a Container attached to a Namespace. type NamespaceResourceContainer struct { - Id string `json:"ID,"` + Id string `json:"ID"` } // NamespaceResourceType determines whether the Namespace resource is a Container or Endpoint. @@ -38,8 +38,8 @@ var ( // NamespaceResource is associated with a namespace type NamespaceResource struct { - Type NamespaceResourceType `json:","` // Container, Endpoint - Data json.RawMessage `json:","` + Type NamespaceResourceType `json:""` // Container, Endpoint + Data json.RawMessage `json:""` } // NamespaceType determines whether the Namespace is for a Host or Guest diff --git a/vendor/github.com/Microsoft/hcsshim/hcn/hcnpolicy.go b/vendor/github.com/Microsoft/hcsshim/hcn/hcnpolicy.go index 87af5e580..9779df02a 100644 --- a/vendor/github.com/Microsoft/hcsshim/hcn/hcnpolicy.go +++ b/vendor/github.com/Microsoft/hcsshim/hcn/hcnpolicy.go @@ -127,8 +127,8 @@ const ( // AclPolicySetting creates firewall rules on an endpoint type AclPolicySetting struct { Protocols string `json:",omitempty"` // EX: 6 (TCP), 17 (UDP), 1 (ICMPv4), 58 (ICMPv6), 2 (IGMP) - Action ActionType `json:","` - Direction DirectionType `json:","` + Action ActionType `json:""` + Direction DirectionType `json:""` LocalAddresses string `json:",omitempty"` RemoteAddresses string `json:",omitempty"` LocalPorts string `json:",omitempty"` @@ -161,8 +161,8 @@ type SDNRoutePolicySetting struct { // NetworkACLPolicySetting creates ACL rules on a network type NetworkACLPolicySetting struct { Protocols string `json:",omitempty"` // EX: 6 (TCP), 17 (UDP), 1 (ICMPv4), 58 (ICMPv6), 2 (IGMP) - Action ActionType `json:","` - Direction DirectionType `json:","` + Action ActionType `json:""` + Direction DirectionType `json:""` LocalAddresses string `json:",omitempty"` RemoteAddresses string `json:",omitempty"` LocalPorts string `json:",omitempty"` @@ -243,6 +243,11 @@ type NetAdapterNameNetworkPolicySetting struct { NetworkAdapterName string `json:",omitempty"` } +// ProviderAddressNetworkPolicySetting sets network adapter of a network based on IP address. +type ProviderAddressNetworkPolicySetting struct { + ProviderAddress string `json:",omitempty"` +} + // VSwitchExtensionNetworkPolicySetting enables/disabled VSwitch extensions for a network. type VSwitchExtensionNetworkPolicySetting struct { ExtensionID string `json:",omitempty"` @@ -267,12 +272,12 @@ type LayerConstraintNetworkPolicySetting struct { // VlanPolicySetting isolates a subnet with VLAN tagging. type VlanPolicySetting struct { - IsolationId uint32 `json:","` + IsolationId uint32 `json:""` } // VsidPolicySetting isolates a subnet with VSID tagging. type VsidPolicySetting struct { - IsolationId uint32 `json:","` + IsolationId uint32 `json:""` } // RemoteSubnetRoutePolicySetting creates remote subnet route rules on a network @@ -330,7 +335,7 @@ type L4ProxyPolicySetting struct { type TierAclRule struct { Id string `json:",omitempty"` Protocols string `json:",omitempty"` - TierAclRuleAction ActionType `json:","` + TierAclRuleAction ActionType `json:""` LocalAddresses string `json:",omitempty"` RemoteAddresses string `json:",omitempty"` LocalPorts string `json:",omitempty"` @@ -340,8 +345,8 @@ type TierAclRule struct { // TierAclPolicySetting represents a Tier containing ACLs type TierAclPolicySetting struct { - Name string `json:","` - Direction DirectionType `json:","` + Name string `json:""` + Direction DirectionType `json:""` Order uint16 `json:""` TierAclRules []TierAclRule `json:",omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go b/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go index b60cd383b..1c115ed99 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/cow/cow.go @@ -8,8 +8,17 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" + "github.com/Microsoft/hcsshim/internal/jobobject" ) +// MigrationState captures the host-side identifiers needed to rebind a +// process during live migration. Zero fields mean the host doesn't use the +// corresponding facility (e.g. vsock or a GCS bridge). +type MigrationState struct { + StdinPort, StdoutPort, StderrPort uint32 + WaitCallID int64 +} + // Process is the interface for an OS process running in a container or utility VM. type Process interface { // Close releases resources associated with the process and closes the @@ -27,6 +36,10 @@ type Process interface { CloseStderr(ctx context.Context) error // Pid returns the process ID. Pid() int + // MigrationState returns the host-side identifiers (vsock stdio ports + // and GCS bridge wait-call id) needed by the live-migration save path. + // Zero fields indicate the host doesn't use those facilities. + MigrationState() MigrationState // Stdio returns the stdio streams for a process. These may be nil if a stream // was not requested during CreateProcess. Stdio() (_ io.Writer, _ io.Reader, _ io.Reader) @@ -96,4 +109,10 @@ type Container interface { WaitError() error // Modify sends a request to modify container resources Modify(ctx context.Context, config interface{}) error + // SetCPUGroupAffinities pins the container's processes to the given CPU + // group affinities. It exists because CPU affinity is not part of the HCS + // container Processor schema and must be applied out of band (on the silo's + // job object for process-isolated Windows containers). Implementations that + // do not support setting CPU affinity return errdefs.ErrNotImplemented. + SetCPUGroupAffinities(ctx context.Context, affinities []jobobject.GroupAffinity) error } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go index 3e10f5c7e..ee225b1f7 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go @@ -59,6 +59,10 @@ var ( // ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container ErrVmcomputeAlreadyStopped = syscall.Errno(0xc0370110) + // ErrVmcomputeSystemAlreadyStopped is returned when an operation targets a compute system that is no longer running + // (e.g. modifying a UVM during migration teardown after it has been stopped). + ErrVmcomputeSystemAlreadyStopped = syscall.Errno(0x80370110) + // ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously ErrVmcomputeOperationPending = syscall.Errno(0xC0370103) @@ -300,7 +304,7 @@ func IsTimeout(err error) bool { // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist // will currently return true when the error is ErrElementNotFound. func IsAlreadyStopped(err error) bool { - return IsAny(err, ErrVmcomputeAlreadyStopped, ErrProcessAlreadyStopped, ErrElementNotFound) + return IsAny(err, ErrVmcomputeAlreadyStopped, ErrVmcomputeSystemAlreadyStopped, ErrProcessAlreadyStopped, ErrElementNotFound) } // IsNotSupported returns a boolean indicating whether the error is caused by diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go index fef2bf546..47ec93261 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go @@ -12,14 +12,13 @@ import ( "syscall" "time" - "go.opencensus.io/trace" - "github.com/Microsoft/hcsshim/internal/cow" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" "github.com/Microsoft/hcsshim/internal/vmcompute" + "go.opentelemetry.io/otel/attribute" ) type Process struct { @@ -57,6 +56,12 @@ func (process *Process) Pid() int { return process.processID } +// MigrationState returns the zero value: HCS processes route stdio over +// named pipes and don't use a GCS bridge. +func (process *Process) MigrationState() cow.MigrationState { + return cow.MigrationState{} +} + // SystemID returns the ID of the process's compute system. func (process *Process) SystemID() string { return process.system.ID() @@ -211,11 +216,11 @@ func (process *Process) Kill(ctx context.Context) (bool, error) { // call multiple times. func (process *Process) waitBackground() { operation := "hcs::Process::waitBackground" - ctx, span := oc.StartSpan(context.Background(), operation) + ctx, span := ot.StartSpan(context.Background(), operation) defer span.End() - span.AddAttributes( - trace.StringAttribute("cid", process.SystemID()), - trace.Int64Attribute("pid", int64(process.processID))) + span.SetAttributes( + attribute.String("cid", process.SystemID()), + attribute.Int64("pid", int64(process.processID))) var ( err error @@ -260,7 +265,7 @@ func (process *Process) waitBackground() { process.waitError = err close(process.waitBlock) }) - oc.SetSpanStatus(span, err) + ot.SetSpanStatus(span, err) } // Wait waits for the process to exit. If the process has already exited returns @@ -329,12 +334,12 @@ func (process *Process) ExitCode() (int, error) { // are the responsibility of the caller to close. func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) { operation := "hcs::Process::StdioLegacy" - ctx, span := oc.StartSpan(context.Background(), operation) + ctx, span := ot.StartSpan(context.Background(), operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", process.SystemID()), - trace.Int64Attribute("pid", int64(process.processID))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("cid", process.SystemID()), + attribute.Int64("pid", int64(process.processID))) process.handleLock.RLock() defer process.handleLock.RUnlock() @@ -378,12 +383,12 @@ func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) { // notified on the read side that there is no more data in stdin. func (process *Process) CloseStdin(ctx context.Context) (err error) { operation := "hcs::Process::CloseStdin" - ctx, span := trace.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", process.SystemID()), - trace.Int64Attribute("pid", int64(process.processID))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("cid", process.SystemID()), + attribute.Int64("pid", int64(process.processID))) process.handleLock.RLock() defer process.handleLock.RUnlock() @@ -424,12 +429,12 @@ func (process *Process) CloseStdin(ctx context.Context) (err error) { } func (process *Process) CloseStdout(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", process.SystemID()), - trace.Int64Attribute("pid", int64(process.processID))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("cid", process.SystemID()), + attribute.Int64("pid", int64(process.processID))) process.handleLock.Lock() defer process.handleLock.Unlock() @@ -448,12 +453,12 @@ func (process *Process) CloseStdout(ctx context.Context) (err error) { } func (process *Process) CloseStderr(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", process.SystemID()), - trace.Int64Attribute("pid", int64(process.processID))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("cid", process.SystemID()), + attribute.Int64("pid", int64(process.processID))) process.handleLock.Lock() defer process.handleLock.Unlock() @@ -475,12 +480,12 @@ func (process *Process) CloseStderr(ctx context.Context) (err error) { // or wait on it. func (process *Process) Close() (err error) { operation := "hcs::Process::Close" - ctx, span := oc.StartSpan(context.Background(), operation) + ctx, span := ot.StartSpan(context.Background(), operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", process.SystemID()), - trace.Int64Attribute("pid", int64(process.processID))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("cid", process.SystemID()), + attribute.Int64("pid", int64(process.processID))) process.handleLock.Lock() defer process.handleLock.Unlock() diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema1/schema1.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema1/schema1.go index e0a3010f8..24162ca15 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema1/schema1.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema1/schema1.go @@ -222,6 +222,7 @@ type GuestDefinedCapabilities struct { DeleteContainerStateSupported bool `json:",omitempty"` UpdateContainerSupported bool `json:",omitempty"` LogForwardingSupported bool `json:",omitempty"` + HostProcessContainerSupported bool `json:",omitempty"` } // GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/com_port.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/com_port.go index 8bf8cab60..e46cae436 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/com_port.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/com_port.go @@ -9,7 +9,7 @@ package hcsschema -// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port. +// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port. type ComPort struct { NamedPipe string `json:"NamedPipe,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container.go index 39a54432c..2272b35fb 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container.go @@ -9,6 +9,15 @@ package hcsschema +// IsolationType describes the isolation mode of a container. +type IsolationType string + +const ( + // IsolationTypeHostProcess is a privileged (Windows) HostProcess + // container that shares the host namespace. + IsolationTypeHostProcess IsolationType = "HostProcess" +) + type Container struct { GuestOs *GuestOs `json:"GuestOs,omitempty"` @@ -33,4 +42,6 @@ type Container struct { AssignedDevices []Device `json:"AssignedDevices,omitempty"` AdditionalDeviceNamespace *ContainerDefinitionDevice `json:"AdditionalDeviceNamespace,omitempty"` + + IsolationType IsolationType `json:"IsolationType,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container_memory_information.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container_memory_information.go index 1fd7ca5d5..a5384ff35 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container_memory_information.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/container_memory_information.go @@ -9,7 +9,7 @@ package hcsschema -// memory usage as viewed from within the container +// memory usage as viewed from within the container type ContainerMemoryInformation struct { TotalPhysicalBytes int32 `json:"TotalPhysicalBytes,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/guest_connection_info.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/guest_connection_info.go index 8a369bab7..4a3851e95 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/guest_connection_info.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/guest_connection_info.go @@ -9,7 +9,7 @@ package hcsschema -// Information about the guest. +// Information about the guest. type GuestConnectionInfo struct { // Each schema version x.y stands for the range of versions a.b where a==x and b<=y. This list comes from the SupportedSchemaVersions field in GcsCapabilities. diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_2.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_2.go index a017691f0..3f8aea5dd 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_2.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_2.go @@ -9,7 +9,7 @@ package hcsschema -// HvSocket configuration for a VM +// HvSocket configuration for a VM type HvSocket2 struct { HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_address.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_address.go index 84c11b93e..9ae843ae0 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_address.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_address.go @@ -9,8 +9,8 @@ package hcsschema -// This class defines address settings applied to a VM -// by the GCS every time a VM starts or restores. +// This class defines address settings applied to a VM +// by the GCS every time a VM starts or restores. type HvSocketAddress struct { LocalAddress string `json:"LocalAddress,omitempty"` ParentAddress string `json:"ParentAddress,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_system_config.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_system_config.go index 69f4f9d39..b1ee1d4a3 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_system_config.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/hv_socket_system_config.go @@ -9,7 +9,7 @@ package hcsschema -// This is the HCS Schema version of the HvSocket configuration. The VMWP version is located in Config.Devices.IC in V1. +// This is the HCS Schema version of the HvSocket configuration. The VMWP version is located in Config.Devices.IC in V1. type HvSocketSystemConfig struct { // SDDL string that HvSocket will check before allowing a host process to bind to an unlisted service for this specific container/VM (not wildcard binds). diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_stats.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_stats.go index 906ba597f..3065f21ac 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_stats.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_stats.go @@ -9,7 +9,7 @@ package hcsschema -// Memory runtime statistics +// Memory runtime statistics type MemoryStats struct { MemoryUsageCommitBytes uint64 `json:"MemoryUsageCommitBytes,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/migration.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/migration.go new file mode 100644 index 000000000..027078c93 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/migration.go @@ -0,0 +1,205 @@ +package hcsschema + +import ( + "encoding/json" + "time" +) + +// MigrationInitializeOptions is a set of options for the migration workflow. +type MigrationInitializeOptions struct { + // Origin is the side of migration the workflow is performed on. + Origin MigrationOrigin `json:"Origin,omitempty"` + // MemoryTransport specifies the settings for memory transfer during migration. On source, this + // setting is required when migration is started. On destination, this setting is required when + // migration is initiated. + MemoryTransport MigrationMemoryTransport `json:"MemoryTransport,omitempty"` + // MemoryTransferThrottleParams specifies settings for throttling during memory transfer. + MemoryTransferThrottleParams *MemoryMigrationTransferThrottleParams `json:"MemoryTransferThrottleParams,omitempty"` + // CompressionSettings specifies additional settings when compression is enabled. + CompressionSettings *MigrationCompressionSettings `json:"CompressionSettings,omitempty"` + // ChecksumVerification enables memory checksum verification. + ChecksumVerification bool `json:"ChecksumVerification,omitempty"` + // PerfTracingEnabled enables performance tracing during migration. + PerfTracingEnabled bool `json:"PerfTracingEnabled,omitempty"` + // CancelIfBlackoutThresholdExceeds cancels the operation if the blackout threshold is exceeded. + CancelIfBlackoutThresholdExceeds bool `json:"CancelIfBlackoutThresholdExceeds,omitempty"` + // PrepareMemoryTransferMode extends timeout for cross-version live migration. + PrepareMemoryTransferMode bool `json:"PrepareMemoryTransferMode,omitempty"` + // CompatibilityData is the compatibility information required for the destination VM. + CompatibilityData *CompatibilityInfo `json:"CompatibilityData,omitempty"` +} + +// MigrationFinalizedOptions is a set of additional options used for HcsLiveMigrationFinalization. +type MigrationFinalizedOptions struct { + // Origin is the side of migration the workflow is performed on. + Origin MigrationOrigin `json:"Origin,omitempty"` + // FinalizedOperation is the final state transition for the VM as part of concluding the LM workflow. + FinalizedOperation MigrationFinalOperation `json:"FinalizedOperation,omitempty"` +} + +// MigrationStartOptions specifies options for starting a migration. +type MigrationStartOptions struct { + // NetworkSettings specifies network settings for the socket provided. + NetworkSettings *MigrationNetworkSettings `json:"NetworkSettings,omitempty"` +} + +// MigrationTransferOptions specifies options for the migration transfer phase. +type MigrationTransferOptions struct { + // Origin is the side of migration the workflow is performed on. + Origin MigrationOrigin `json:"Origin,omitempty"` +} + +// MigrationCancelOptions is a set of options used to cancel a live migration. +type MigrationCancelOptions struct { + // Origin is the side of migration the workflow is performed on. + Origin MigrationOrigin `json:"Origin,omitempty"` +} + +// StartOptions specifies options for starting a compute system. +type StartOptions struct { + // DestinationMigrationOptions specifies settings to use when starting a migration on the destination side. + DestinationMigrationOptions *MigrationStartOptions `json:"DestinationMigrationOptions,omitempty"` +} + +// MigrationOrigin indicates where migration is initiated from. +type MigrationOrigin string + +const ( + // MigrationOriginSource indicates the source side of migration. + MigrationOriginSource MigrationOrigin = "Source" + // MigrationOriginDestination indicates the destination side of migration. + MigrationOriginDestination MigrationOrigin = "Destination" +) + +// MigrationMemoryTransport is the transport protocol used for memory transfer during migration. +type MigrationMemoryTransport string + +const ( + // MigrationMemoryTransportTCP indicates the VM memory is copied over a TCP/IP connection. + MigrationMemoryTransportTCP MigrationMemoryTransport = "TCP" +) + +// MemoryMigrationTransferThrottleParams specifies settings for migration memory transfer throttling. +type MemoryMigrationTransferThrottleParams struct { + // SkipThrottling indicates whether throttling should be skipped. + SkipThrottling *bool `json:"SkipThrottling,omitempty"` + // ThrottlingScale is the scale of the throttling as a percentage (1-100). + ThrottlingScale *float64 `json:"ThrottlingScale,omitempty"` + // MinimumThrottlePercentage is the minimum percentage to which memory transfer can be throttled. + MinimumThrottlePercentage *uint8 `json:"MinimumThrottlePercentage,omitempty"` + // TargetNumberOfBrownoutTransferPasses is the number of passes targeted before the VM enters blackout. + TargetNumberOfBrownoutTransferPasses *uint32 `json:"TargetNumberOfBrownoutTransferPasses,omitempty"` + // StartingBrownoutPassNumberForThrottling is the transfer pass where throttling begins. + StartingBrownoutPassNumberForThrottling *uint32 `json:"StartingBrownoutPassNumberForThrottling,omitempty"` + // MaximumNumberOfBrownoutTransferPasses is the maximum number of passes before forcing blackout. + MaximumNumberOfBrownoutTransferPasses *uint32 `json:"MaximumNumberOfBrownoutTransferPasses,omitempty"` + // TargetBlackoutTransferTime is the expected duration for blackout transfer time. + TargetBlackoutTransferTime *uint32 `json:"TargetBlackoutTransferTime,omitempty"` + // BlackoutTimeThresholdForCancellingMigration is the blackout duration threshold for cancelling migration. + BlackoutTimeThresholdForCancellingMigration *uint32 `json:"BlackoutTimeThresholdForCancellingMigration,omitempty"` +} + +// MigrationCompressionSettings specifies compression settings for migration. +type MigrationCompressionSettings struct { + // ThrottleWorkerCount is the [de]compression thread count. Values higher than what the host + // and VM configuration can support will be adjusted. The value should be non-zero. + ThrottleWorkerCount *uint32 `json:"ThrottleWorkerCount,omitempty"` +} + +// CompatibilityInfo is opaque VM compatibility data, primarily used in migration. +type CompatibilityInfo struct { + // Data is the raw compatibility information. + Data []byte `json:"Data,omitempty"` +} + +// MigrationFinalOperation is the final operation performed on the compute system to finalize the live migration workflow. +type MigrationFinalOperation string + +const ( + // MigrationFinalOperationResume resumes the VM. + MigrationFinalOperationResume MigrationFinalOperation = "Resume" + // MigrationFinalOperationStop stops the VM. + MigrationFinalOperationStop MigrationFinalOperation = "Stop" +) + +// MigrationNetworkSettings specifies the transport protocol for network connection provided by client. +type MigrationNetworkSettings struct { + // SessionID is the session ID associated with the socket connection between source and destination. + SessionID uint32 `json:"SessionId,omitempty"` +} + +// OperationSystemMigrationNotificationInfo is a notification payload describing +// the current state of an in-progress live migration operation. It is emitted +// by HCS over the migration notification channel as the workflow progresses. +type OperationSystemMigrationNotificationInfo struct { + // Origin indicates which side of the live migration this notification + // pertains to (source or destination). + Origin MigrationOrigin `json:"Origin,omitempty"` + // Event is the type of live migration event being reported. + Event MigrationEvent `json:"Event,omitempty"` + // Result is an optional outcome accompanying the event. It is typically + // populated for terminal events. + Result MigrationResult `json:"Result,omitempty"` + // AdditionalDetails carries extra event-specific information whose schema + // depends on the event being reported. HCS models this as the schema `Any` + // type; we keep it as raw JSON so callers can decode it into the concrete + // event-specific struct (e.g. BlackoutExitedEventDetails for + // MigrationEventBlackoutExited) once they have inspected Event. + AdditionalDetails json.RawMessage `json:"AdditionalDetails,omitempty"` +} + +// BlackoutExitedEventDetails carries additional details reported alongside +// MigrationEventBlackoutExited, describing the blackout that just ended. +// Mirrors the HCS MigrationBlackoutExitedEventDetails schema. +type BlackoutExitedEventDetails struct { + // BlackoutDurationMilliseconds is the duration of the blackout phase, in milliseconds. + BlackoutDurationMilliseconds uint64 `json:"BlackoutDurationMilliseconds,omitempty"` + // BlackoutStopTimestamp is the timestamp at which the blackout phase ended. + BlackoutStopTimestamp time.Time `json:"BlackoutStopTimestamp,omitempty"` +} + +// MigrationEvent describes a live migration event reported by HCS. +type MigrationEvent string + +const ( + // MigrationEventUnknown indicates an unspecified or unrecognized event. + MigrationEventUnknown MigrationEvent = "Unknown" + // MigrationEventMigrationDone indicates that migration has completed. + MigrationEventMigrationDone MigrationEvent = "MigrationDone" + // MigrationEventBlackoutStarted indicates that the VM has entered the blackout phase. + MigrationEventBlackoutStarted MigrationEvent = "BlackoutStarted" + // MigrationEventOfflineDone indicates that taking the VM offline has completed. + MigrationEventOfflineDone MigrationEvent = "OfflineDone" + // MigrationEventBlackoutExited indicates that the VM has successfully started + // again after the blackout phase. + MigrationEventBlackoutExited MigrationEvent = "BlackoutExited" + // MigrationEventSetupDone indicates that the live migration setup has completed. + MigrationEventSetupDone MigrationEvent = "SetupDone" + // MigrationEventTransferInProgress indicates that the VM is still transferring + // memory and other necessary state. + MigrationEventTransferInProgress MigrationEvent = "TransferInProgress" + // MigrationEventMigrationRecoveryDone indicates that migration recovery has been performed. + MigrationEventMigrationRecoveryDone MigrationEvent = "MigrationRecoveryDone" + // MigrationEventMigrationFailed indicates that migration failed. + MigrationEventMigrationFailed MigrationEvent = "MigrationFailed" +) + +// MigrationResult describes the possible result of a migration operation. +type MigrationResult string + +const ( + // MigrationResultInvalid indicates an invalid or unspecified result. + MigrationResultInvalid MigrationResult = "Invalid" + // MigrationResultSuccess indicates the migration operation succeeded. + MigrationResultSuccess MigrationResult = "Success" + // MigrationResultMigrationCancelled indicates the migration was cancelled. + MigrationResultMigrationCancelled MigrationResult = "MigrationCancelled" + // MigrationResultGuestInitiatedCancellation indicates the guest initiated the cancellation. + MigrationResultGuestInitiatedCancellation MigrationResult = "GuestInitiatedCancellation" + // MigrationResultSourceMigrationFailed indicates the migration failed on the source side. + MigrationResultSourceMigrationFailed MigrationResult = "SourceMigrationFailed" + // MigrationResultDestinationMigrationFailed indicates the migration failed on the destination side. + MigrationResultDestinationMigrationFailed MigrationResult = "DestinationMigrationFailed" + // MigrationResultMigrationRecoveryFailed indicates the migration recovery failed. + MigrationResultMigrationRecoveryFailed MigrationResult = "MigrationRecoveryFailed" +) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go index 3f27b2ca0..c77b94070 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go @@ -12,10 +12,10 @@ package hcsschema type NumaSetting struct { - VirtualNodeNumber uint32 `json:"VirtualNodeNumber,omitempty"` - PhysicalNodeNumber uint32 `json:"PhysicalNodeNumber,omitempty"` - VirtualSocketNumber uint32 `json:"VirtualSocketNumber,omitempty"` - CountOfProcessors uint32 `json:"CountOfProcessors,omitempty"` - CountOfMemoryBlocks uint64 `json:"CountOfMemoryBlocks,omitempty"` - MemoryBackingType MemoryBackingType `json:"MemoryBackingType,omitempty"` + VirtualNodeNumber uint32 `json:"VirtualNodeNumber,omitempty"` + PhysicalNodeNumber uint32 `json:"PhysicalNodeNumber,omitempty"` + VirtualSocketNumber uint32 `json:"VirtualSocketNumber,omitempty"` + CountOfProcessors uint32 `json:"CountOfProcessors,omitempty"` + CountOfMemoryBlocks uint64 `json:"CountOfMemoryBlocks,omitempty"` + MemoryBackingType MemoryBackingType `json:"MemoryBackingType,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_notification.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_notification.go index d96c9501f..a9769c934 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_notification.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_notification.go @@ -9,7 +9,7 @@ package hcsschema -// Notification data that is indicated to components running in the Virtual Machine. +// Notification data that is indicated to components running in the Virtual Machine. type PauseNotification struct { Reason string `json:"Reason,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_options.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_options.go index 21707a88e..d48e04342 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_options.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/pause_options.go @@ -9,7 +9,7 @@ package hcsschema -// Options for HcsPauseComputeSystem +// Options for HcsPauseComputeSystem type PauseOptions struct { SuspensionLevel string `json:"SuspensionLevel,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share.go index 41f8fdea0..ee7e68bc4 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share.go @@ -19,16 +19,7 @@ type Plan9Share struct { Port int32 `json:"Port,omitempty"` - // Flags are marked private. Until they are exported correctly - // - // ReadOnly 0x00000001 - // LinuxMetadata 0x00000004 - // CaseSensitive 0x00000008 - Flags int32 `json:"Flags,omitempty"` - - ReadOnly bool `json:"ReadOnly,omitempty"` - - UseShareRootIdentity bool `json:"UseShareRootIdentity,omitempty"` + Flags Plan9ShareFlags `json:"Flags,omitempty"` AllowedFiles []string `json:"AllowedFiles,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share_flags.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share_flags.go new file mode 100644 index 000000000..17f75ee99 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/plan9_share_flags.go @@ -0,0 +1,38 @@ +/* + * HCS API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +// Plan9ShareFlags is a bitfield controlling Plan9 share behavior. +type Plan9ShareFlags int32 + +const ( + // Plan9ShareFlagsNone indicates no flags are set. + Plan9ShareFlagsNone Plan9ShareFlags = 0x00000000 + + // Plan9ShareFlagsReadOnly makes the share read-only. + Plan9ShareFlagsReadOnly Plan9ShareFlags = 0x00000001 + + // Plan9ShareFlagsLinuxMetadata enables writing Linux metadata. + Plan9ShareFlagsLinuxMetadata Plan9ShareFlags = 0x00000004 + + // Plan9ShareFlagsCaseSensitive creates directories in case-sensitive mode. + Plan9ShareFlagsCaseSensitive Plan9ShareFlags = 0x00000008 + + // Plan9ShareFlagsUseShareRootIdentity uses the identity of the share root + // when opening. + Plan9ShareFlagsUseShareRootIdentity Plan9ShareFlags = 0x00000010 + + // Plan9ShareFlagsRestrictFileAccess enables single-file mapping mode. + Plan9ShareFlagsRestrictFileAccess Plan9ShareFlags = 0x00000080 + + // Plan9ShareFlagsUnlimitedConnections allows multiple connections to this + // share. + Plan9ShareFlagsUnlimitedConnections Plan9ShareFlags = 0x00000100 +) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_details.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_details.go index e9a662dd5..de56374b2 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_details.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_details.go @@ -13,7 +13,7 @@ import ( "time" ) -// Information about a process running in a container +// Information about a process running in a container type ProcessDetails struct { ProcessId int32 `json:"ProcessId,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor.go index bb24e88da..301e0cb8d 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor.go @@ -3,7 +3,7 @@ * * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) * - * API version: 2.1 + * API version: 2.4 * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) */ diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_stats.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_stats.go index 6157e2522..db42a19ea 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_stats.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_stats.go @@ -9,7 +9,7 @@ package hcsschema -// CPU runtime statistics +// CPU runtime statistics type ProcessorStats struct { TotalRuntime100ns uint64 `json:"TotalRuntime100ns,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go index d4cb95bdd..b5ec26bba 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go @@ -10,6 +10,8 @@ package hcsschema import ( + "encoding/json" + v1 "github.com/containerd/cgroups/v3/cgroup1/stats" ) @@ -50,7 +52,15 @@ type Properties struct { GuestConnectionInfo *GuestConnectionInfo `json:"GuestConnectionInfo,omitempty"` + // PropertyResponses maps requested property names to their associated response objects. + PropertyResponses map[string]PropertyResponse `json:"PropertyResponses,omitempty"` + // Metrics is not part of the API for HCS but this is used for LCOW v2 to // return the full cgroup metrics from the guest. Metrics *v1.Metrics `json:"LCOWMetrics,omitempty"` } + +// PropertyResponse is the response object associated with a property query. +type PropertyResponse struct { + Response json.RawMessage `json:"Response,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_query.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_query.go index d6d80df13..7c0675006 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_query.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_query.go @@ -9,7 +9,11 @@ package hcsschema -// By default the basic properties will be returned. This query provides a way to request specific properties. +// By default the basic properties will be returned. This query provides a way to request specific properties. type PropertyQuery struct { PropertyTypes []PropertyType `json:"PropertyTypes,omitempty"` + + // Queries is a new property request object, introduced in version 2.5, which takes the + // names of the properties and their associated query objects if needed. + Queries map[string]interface{} `json:"Queries,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/silo_properties.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/silo_properties.go index 5eaf6a7f4..eb7338c65 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/silo_properties.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/silo_properties.go @@ -9,7 +9,7 @@ package hcsschema -// Silo job information +// Silo job information type SiloProperties struct { Enabled bool `json:"Enabled,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/statistics.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/statistics.go index ba7a6b396..6e2dce6f4 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/statistics.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/statistics.go @@ -13,7 +13,7 @@ import ( "time" ) -// Runtime statistics for a container +// Runtime statistics for a container type Statistics struct { Timestamp time.Time `json:"Timestamp,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage.go index 2627af913..86cf6fca8 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage.go @@ -18,4 +18,7 @@ type Storage struct { Path string `json:"Path,omitempty"` QoS *StorageQoS `json:"QoS,omitempty"` + + // Path to the root of the container's filesystem. This is useful in case of HostProcess containers where the container rootfs is different from C:\. + PrivilegedContainerRootPath string `json:"PrivilegedContainerRootPath,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage_stats.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage_stats.go index 4f042ffd9..36f190aec 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage_stats.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/storage_stats.go @@ -9,7 +9,7 @@ package hcsschema -// Storage runtime statistics +// Storage runtime statistics type StorageStats struct { ReadCountNormalized uint64 `json:"ReadCountNormalized,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go index 9cca85171..a4dc866eb 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go @@ -12,7 +12,7 @@ package hcsschema type Topology struct { - Memory *VirtualMachineMemory `json:"Memory,omitempty"` - Processor *VirtualMachineProcessor `json:"Processor,omitempty"` - Numa *Numa `json:"Numa,omitempty"` + Memory *VirtualMachineMemory `json:"Memory,omitempty"` + Processor *VirtualMachineProcessor `json:"Processor,omitempty"` + Numa *Numa `json:"Numa,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go index 3f750466f..f76aa5b28 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go @@ -15,15 +15,18 @@ package hcsschema type VirtualMachine struct { Version *Version `json:"Version,omitempty"` // When set to true, the virtual machine will treat a reset as a stop, releasing resources and cleaning up state. - StopOnReset bool `json:"StopOnReset,omitempty"` - Chipset *Chipset `json:"Chipset,omitempty"` - ComputeTopology *Topology `json:"ComputeTopology,omitempty"` - Devices *Devices `json:"Devices,omitempty"` - GuestState *GuestState `json:"GuestState,omitempty"` - RestoreState *RestoreState `json:"RestoreState,omitempty"` - RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"` - StorageQoS *StorageQoS `json:"StorageQoS,omitempty"` - DebugOptions *DebugOptions `json:"DebugOptions,omitempty"` - GuestConnection *GuestConnection `json:"GuestConnection,omitempty"` - SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"` + StopOnReset bool `json:"StopOnReset,omitempty"` + Chipset *Chipset `json:"Chipset,omitempty"` + ComputeTopology *Topology `json:"ComputeTopology,omitempty"` + Devices *Devices `json:"Devices,omitempty"` + GuestState *GuestState `json:"GuestState,omitempty"` + RestoreState *RestoreState `json:"RestoreState,omitempty"` + RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"` + StorageQoS *StorageQoS `json:"StorageQoS,omitempty"` + DebugOptions *DebugOptions `json:"DebugOptions,omitempty"` + GuestConnection *GuestConnection `json:"GuestConnection,omitempty"` + SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"` + ResourcePartitionId string `json:"ResourcePartitionId,omitempty"` + // Live migration options to be used on destination. + MigrationOptions *MigrationInitializeOptions `json:"MigrationOptions,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go index 17573c92a..d11fe37fd 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go @@ -15,7 +15,7 @@ type VirtualMachineMemory struct { SizeInMB uint64 `json:"SizeInMB,omitempty"` Backing *MemoryBackingType `json:"Backing,omitempty"` // If enabled, then the VM's memory is backed by the Windows pagefile rather than physically backed, statically allocated memory. - AllowOvercommit bool `json:"AllowOvercommit,omitempty"` + AllowOvercommit bool `json:"AllowOvercommit,omitempty"` // If enabled, then the memory hot hint feature is exposed to the VM, allowing it to prefetch pages into its working set. (if supported by the guest operating system). EnableHotHint bool `json:"EnableHotHint,omitempty"` // If enabled, then the memory cold hint feature is exposed to the VM, allowing it to trim zeroed pages from its working set (if supported by the guest operating system). @@ -27,7 +27,7 @@ type VirtualMachineMemory struct { // Low MMIO region allocated below 4GB LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"` // High MMIO region allocated above 4GB (base and size) - HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"` - HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"` - SlitType *VirtualSlitType `json:"SlitType,omitempty"` + HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"` + HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"` + SlitType *VirtualSlitType `json:"SlitType,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go index 619cd8340..ea1bd731f 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go @@ -12,10 +12,10 @@ package hcsschema type VirtualMachineProcessor struct { - Count uint32 `json:"Count,omitempty"` - Limit uint64 `json:"Limit,omitempty"` - Weight uint64 `json:"Weight,omitempty"` - Reservation uint64 `json:"Reservation,omitempty"` - CpuGroup *CpuGroup `json:"CpuGroup,omitempty"` - NumaProcessorsSettings *NumaProcessors `json:"NumaProcessorsSettings,omitempty"` + Count uint32 `json:"Count,omitempty"` + Limit uint64 `json:"Limit,omitempty"` + Weight uint64 `json:"Weight,omitempty"` + Reservation uint64 `json:"Reservation,omitempty"` + CpuGroup *CpuGroup `json:"CpuGroup,omitempty"` + NumaProcessorsSettings *NumaProcessors `json:"NumaProcessorsSettings,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go index a4a62da16..202338904 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go @@ -12,6 +12,6 @@ package hcsschema // TODO: PropagateNumaAffinity is pre-release/experimental field in schema 2.11. Need to add build number // docs when a public build with this is out. type VirtualPciDevice struct { - Functions []VirtualPciFunction `json:",omitempty"` - PropagateNumaAffinity *bool `json:"PropagateNumaAffinity,omitempty"` + Functions []VirtualPciFunction `json:",omitempty"` + PropagateNumaAffinity *bool `json:"PropagateNumaAffinity,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go index 823e27b0b..c247d02df 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go @@ -18,11 +18,11 @@ import ( "github.com/Microsoft/hcsshim/internal/jobobject" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/internal/timeout" "github.com/Microsoft/hcsshim/internal/vmcompute" "github.com/sirupsen/logrus" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" ) type System struct { @@ -61,10 +61,10 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in // hcsCreateComputeSystemContext is an async operation. Start the outer span // here to measure the full create time. - ctx, span := oc.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", id)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", id)) computeSystem := newSystem(id) @@ -191,16 +191,16 @@ func GetComputeSystems(ctx context.Context, q schema1.ComputeSystemQuery) ([]sch return computeSystems, nil } -// Start synchronously starts the computeSystem. +// Start synchronously starts the computeSystem using HCS V1 API. func (computeSystem *System) Start(ctx context.Context) (err error) { operation := "hcs::System::Start" // hcsStartComputeSystemContext is an async operation. Start the outer span // here to measure the full start time. - ctx, span := oc.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", computeSystem.id)) computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() @@ -277,9 +277,9 @@ func (computeSystem *System) Terminate(ctx context.Context) error { // safe to call multiple times. func (computeSystem *System) waitBackground() { operation := "hcs::System::waitBackground" - ctx, span := oc.StartSpan(context.Background(), operation) + ctx, span := ot.StartSpan(context.Background(), operation) defer span.End() - span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) + span.SetAttributes(attribute.String("cid", computeSystem.id)) err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil) if err == nil { @@ -296,7 +296,7 @@ func (computeSystem *System) waitBackground() { computeSystem.stopTime = time.Now() close(computeSystem.waitBlock) }) - oc.SetSpanStatus(span, err) + ot.SetSpanStatus(span, err) } func (computeSystem *System) WaitChannel() <-chan struct{} { @@ -379,6 +379,20 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr return properties, nil } +// openSilo opens the container's server silo job object by its well-known name +// (`\Container_`). HCS owns the silo; the only way to open it from the shim is +// by name, and only while running as SYSTEM. The caller owns the returned handle and +// must Close it. +// +// In the future we can make use of some new functionality in HCS that allows you to +// pass a job object for HCS to use for the container. +func (computeSystem *System) openSilo(ctx context.Context) (*jobobject.JobObject, error) { + return jobobject.Open(ctx, &jobobject.Options{ + UseNTVariant: true, + Name: siloNameFmt(computeSystem.id), + }) +} + // queryInProc handles querying for container properties without reaching out to HCS. `props` // will be updated to contain any data returned from the queries present in `types`. If any properties // failed to be queried they will be tallied up and returned in as the first return value. Failures on @@ -389,14 +403,7 @@ func (computeSystem *System) queryInProc( props *hcsschema.Properties, types []hcsschema.PropertyType, ) ([]hcsschema.PropertyType, error) { - // In the future we can make use of some new functionality in the HCS that allows you - // to pass a job object for HCS to use for the container. Currently, the only way we'll - // be able to open the job/silo is if we're running as SYSTEM. - jobOptions := &jobobject.Options{ - UseNTVariant: true, - Name: siloNameFmt(computeSystem.id), - } - job, err := jobobject.Open(ctx, jobOptions) + job, err := computeSystem.openSilo(ctx) if err != nil { return nil, err } @@ -490,6 +497,48 @@ func (computeSystem *System) statisticsInProc(job *jobobject.JobObject) (*hcssch }, nil } +// SetCPUGroupAffinities pins the container's server silo to the given processor +// group affinities. HCS does not expose a CPU-affinity field on the container Processor +// schema, so for process-isolated (Argon) containers we set the affinity directly on the +// silo's job object via SetInformationJobObject(JobObjectGroupInformationEx). +// +// HCS owns the silo; we only open a transient handle (by the silo's well-known job name, +// the same handle queryInProc opens) to record the affinity property. The kernel enforces +// it on every process that joins the silo via AssignProcessToJobObject — including the init +// process at Start and any descendants it spawns. +// +// This must be called after the compute system is created but before it is started, so the +// affinity is already recorded on the job when HCS assigns the init process. Applying it to +// an already-running silo is also safe: the kernel re-applies the mask to current members and +// migrates threads at the next scheduling dispatch. +// +// It implements the cow.Container interface. +func (computeSystem *System) SetCPUGroupAffinities(ctx context.Context, affinities []jobobject.GroupAffinity) error { + computeSystem.handleLock.RLock() + defer computeSystem.handleLock.RUnlock() + + // Guard the compute system's lifecycle while we touch its silo: the RLock blocks + // a concurrent Close(), and handle == 0 means it is already torn down. + if computeSystem.handle == 0 { + return fmt.Errorf("set cpu group affinities on %s silo: %w", computeSystem.ID(), ErrAlreadyClosed) + } + // The silo job object only exists for containers, not VM-based compute systems. + if computeSystem.typ != "container" { + return fmt.Errorf("cpu group affinities are only supported on container compute systems, got %q", computeSystem.typ) + } + + job, err := computeSystem.openSilo(ctx) + if err != nil { + return fmt.Errorf("open %s silo: %w", computeSystem.ID(), err) + } + defer job.Close() + + if err := job.SetCPUGroupAffinities(affinities); err != nil { + return fmt.Errorf("set cpu group affinities on %s silo: %w", computeSystem.ID(), err) + } + return nil +} + // hcsPropertiesV2Query is a helper to make a HcsGetComputeSystemProperties call using the V2 schema property types. func (computeSystem *System) hcsPropertiesV2Query(ctx context.Context, types []hcsschema.PropertyType) (*hcsschema.Properties, error) { operation := "hcs::System::PropertiesV2" @@ -574,16 +623,64 @@ func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschem return hcsProperties, nil } +// PropertiesV3 returns the requested compute system properties using a V2 schema property query. +// Unlike [System.PropertiesV2], this method accepts a full [hcsschema.PropertyQuery] directly, +// giving the caller more control over the query structure. The query is forwarded to HCS as-is +// without any in-proc optimisations such as that is V2. +func (computeSystem *System) PropertiesV3(ctx context.Context, query *hcsschema.PropertyQuery) (_ *hcsschema.Properties, err error) { + operation := "hcs::System::PropertiesV3" + + ctx, span := ot.StartSpan(ctx, operation) + defer span.End() + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", computeSystem.id)) + + computeSystem.handleLock.RLock() + defer computeSystem.handleLock.RUnlock() + + if computeSystem.handle == 0 { + return nil, makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) + } + + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: computeSystem.id, + "propertyTypes": query.PropertyTypes, + "propertyQueries": query.Queries, + }).Debug("querying compute system properties via PropertiesV3") + + queryBytes, err := json.Marshal(query) + if err != nil { + return nil, makeSystemError(computeSystem, operation, err, nil) + } + + propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes)) + events := processHcsResult(ctx, resultJSON) + if err != nil { + return nil, makeSystemError(computeSystem, operation, err, events) + } + + if propertiesJSON == "" { + return nil, ErrUnexpectedValue + } + + props := &hcsschema.Properties{} + if err := json.Unmarshal([]byte(propertiesJSON), props); err != nil { + return nil, makeSystemError(computeSystem, operation, err, nil) + } + + return props, nil +} + // Pause pauses the execution of the computeSystem. This feature is not enabled in TP5. func (computeSystem *System) Pause(ctx context.Context) (err error) { operation := "hcs::System::Pause" // hcsPauseComputeSystemContext is an async operation. Start the outer span // here to measure the full pause time. - ctx, span := oc.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", computeSystem.id)) computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() @@ -608,10 +705,10 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) { // hcsResumeComputeSystemContext is an async operation. Start the outer span // here to measure the full restore time. - ctx, span := oc.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", computeSystem.id)) computeSystem.handleLock.RLock() defer computeSystem.handleLock.RUnlock() @@ -636,10 +733,10 @@ func (computeSystem *System) Save(ctx context.Context, options interface{}) (err // hcsSaveComputeSystemContext is an async operation. Start the outer span // here to measure the full save time. - ctx, span := oc.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", computeSystem.id)) saveOptions, err := json.Marshal(options) if err != nil { @@ -759,10 +856,10 @@ func (computeSystem *System) Close() error { // proper system cleanup. func (computeSystem *System) CloseCtx(ctx context.Context) (err error) { operation := "hcs::System::Close" - ctx, span := oc.StartSpan(ctx, operation) + ctx, span := ot.StartSpan(ctx, operation) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("cid", computeSystem.id)) computeSystem.handleLock.Lock() defer computeSystem.handleLock.Unlock() diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go index 5f062e5c5..3150eec49 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go @@ -28,11 +28,22 @@ type JobObject struct { handleLock sync.RWMutex } +// GroupAffinity specifies a processor group and an affinity mask within that group. +// It corresponds to the Win32 GROUP_AFFINITY structure and is used for multi-group +// CPU affinity on machines with more than 64 logical processors (WS2022+). +type GroupAffinity struct { + // Mask is the bitmask of processors within Group. + Mask uint64 + // Group is the processor group number (0-based). + Group uint16 +} + // JobLimits represents the resource constraints that can be applied to a job object. type JobLimits struct { CPULimit uint32 CPUWeight uint32 - CPUAffinity uint64 + CPUAffinity uint64 // legacy single-group (group 0) affinity mask; use GroupAffinities when non-empty + GroupAffinities []GroupAffinity // multi-processor-group affinity (WS2022+); takes precedence over CPUAffinity MemoryLimitInBytes uint64 MaxIOPS int64 MaxBandwidth int64 diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go index 5bb20df00..a46988dd7 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go @@ -3,10 +3,12 @@ package jobobject import ( + "context" "errors" "fmt" "unsafe" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/winapi" "golang.org/x/sys/windows" ) @@ -20,7 +22,7 @@ func isFlagSet(flag, controlFlags uint32) bool { } // SetResourceLimits sets resource limits on the job object (cpu, memory, storage). -func (job *JobObject) SetResourceLimits(limits *JobLimits) error { +func (job *JobObject) SetResourceLimits(ctx context.Context, limits *JobLimits) error { // Go through and check what limits were specified and apply them to the job. if limits.MemoryLimitInBytes != 0 { if err := job.SetMemoryLimit(limits.MemoryLimitInBytes); err != nil { @@ -38,7 +40,15 @@ func (job *JobObject) SetResourceLimits(limits *JobLimits) error { } } - if limits.CPUAffinity != 0 { + if len(limits.GroupAffinities) > 0 && limits.CPUAffinity != 0 { + log.G(ctx).WithField("limits", log.Format(ctx, limits)).Warn("both group and CPU affinity set; CPU affinity will be overridden") + } + + if len(limits.GroupAffinities) > 0 { + if err := job.SetCPUGroupAffinities(limits.GroupAffinities); err != nil { + return fmt.Errorf("failed to set job object cpu group affinities: %w", err) + } + } else if limits.CPUAffinity != 0 { if err := job.SetCPUAffinity(limits.CPUAffinity); err != nil { return fmt.Errorf("failed to set job object cpu affinity: %w", err) } @@ -141,8 +151,89 @@ func (job *JobObject) GetCPULimit(rateControlType CPURateControlType) (uint32, e return info.Value, nil } +// SetCPUGroupAffinities sets the processor group affinities for the job object using +// JobObjectGroupInformationEx, which supports multi-processor-group machines (WS2022+). +// Each entry in affinities specifies a processor group number and a bitmask of processors +// within that group. affinities must be non-empty. +// https://learn.microsoft.com/en-us/windows/win32/api/jobapi2/nf-jobapi2-setinformationjobobject +func (job *JobObject) SetCPUGroupAffinities(affinities []GroupAffinity) error { + if len(affinities) == 0 { + return errors.New("affinities must be non-empty") + } + winapiAffinities := make([]winapi.GROUP_AFFINITY, len(affinities)) + for i, a := range affinities { + winapiAffinities[i] = winapi.GROUP_AFFINITY{ + Mask: uintptr(a.Mask), + Group: a.Group, + } + } + + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return ErrAlreadyClosed + } + + if _, err := windows.SetInformationJobObject( + job.handle, + windows.JobObjectGroupInformationEx, + uintptr(unsafe.Pointer(&winapiAffinities[0])), + uint32(len(winapiAffinities))*uint32(unsafe.Sizeof(winapiAffinities[0])), + ); err != nil { + return fmt.Errorf("failed to set cpu group affinities on job object: %w", err) + } + return nil +} + +// GetCPUGroupAffinities returns the processor group affinities set on the job object. +// https://learn.microsoft.com/en-us/windows/win32/api/jobapi2/nf-jobapi2-queryinformationjobobject +func (job *JobObject) GetCPUGroupAffinities() ([]GroupAffinity, error) { + job.handleLock.RLock() + defer job.handleLock.RUnlock() + + if job.handle == 0 { + return nil, ErrAlreadyClosed + } + + // QueryInformationJobObject(JobObjectGroupInformationEx) returns one + // GROUP_AFFINITY per processor group assigned to the job. Most machines + // have a single processor group; start with 1 and grow on + // ERROR_INSUFFICIENT_BUFFER. + count := uint32(1) + for { + winapiAffinities := make([]winapi.GROUP_AFFINITY, count) + var returnLen uint32 + err := winapi.QueryInformationJobObject( + job.handle, + windows.JobObjectGroupInformationEx, + unsafe.Pointer(&winapiAffinities[0]), + count*uint32(unsafe.Sizeof(winapiAffinities[0])), + &returnLen, + ) + if err == nil { + actualCount := returnLen / uint32(unsafe.Sizeof(winapiAffinities[0])) + result := make([]GroupAffinity, actualCount) + for i, a := range winapiAffinities[:actualCount] { + result[i] = GroupAffinity{Mask: uint64(a.Mask), Group: a.Group} + } + return result, nil + } + if !errors.Is(err, windows.ERROR_INSUFFICIENT_BUFFER) { + return nil, fmt.Errorf("failed to query cpu group affinities on job object: %w", err) + } + newCount := returnLen / uint32(unsafe.Sizeof(winapiAffinities[0])) + if newCount <= count { + return nil, fmt.Errorf("failed to query cpu group affinities on job object: buffer size did not grow (%d -> %d entries)", count, newCount) + } + count = newCount + } +} + // SetCPUAffinity sets the processor affinity for the job object. // The affinity is passed in as a bitmask. +// Note: this uses JOB_OBJECT_LIMIT_AFFINITY which is restricted to processor group 0. +// For machines with more than 64 logical processors, use SetCPUGroupAffinities instead. func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error { info, err := job.getExtendedInformation() if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/log/format.go b/vendor/github.com/Microsoft/hcsshim/internal/log/format.go index f26316fab..90fe45d7b 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/log/format.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/log/format.go @@ -61,7 +61,7 @@ func formatAddr(a net.Addr) string { // HTML escapes. // Context is used to output a log waring if the conversion fails. // -// This is intended primarily for `trace.StringAttribute()` +// This is intended primarily for `attribute.String()` func Format(ctx context.Context, v interface{}) string { b, err := encode(v) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/log/hook.go b/vendor/github.com/Microsoft/hcsshim/internal/log/hook.go index da81023b6..e326189cc 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/log/hook.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/log/hook.go @@ -2,12 +2,12 @@ package log import ( "bytes" + "go.opentelemetry.io/otel/trace" "reflect" "time" "github.com/Microsoft/hcsshim/internal/logfields" "github.com/sirupsen/logrus" - "go.opencensus.io/trace" ) const nullString = "null" @@ -107,8 +107,8 @@ func (h *Hook) encode(e *logrus.Entry) { switch vv := v.(type) { // built in types - // "json" marshals errors as "{}", so leave alone here - case bool, string, error, uintptr, + case bool, string, uintptr, + error, // "json" marshals errors as "{}", so leave alone here int8, int16, int32, int64, int, uint8, uint32, uint64, uint, float32, float64: @@ -163,11 +163,11 @@ func (h *Hook) addSpanContext(e *logrus.Entry) { if !h.AddSpanContext || ctx == nil { return } - span := trace.FromContext(ctx) + span := trace.SpanFromContext(ctx) if span == nil { return } sctx := span.SpanContext() - e.Data[logfields.TraceID] = sctx.TraceID.String() - e.Data[logfields.SpanID] = sctx.SpanID.String() + e.Data[logfields.TraceID] = sctx.TraceID().String() + e.Data[logfields.SpanID] = sctx.SpanID().String() } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go b/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go index 83ee97f85..455bc5262 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go @@ -29,7 +29,13 @@ var ( _scrub atomic.Bool ) -// SetScrubbing enables scrubbing +func init() { + // Scrubbing is enabled by default to prevent sensitive information + // (such as environment variables containing secrets) from leaking to logs. + _scrub.Store(true) +} + +// SetScrubbing enables or disables scrubbing of potentially sensitive information from logging. func SetScrubbing(enable bool) { _scrub.Store(enable) } // IsScrubbingEnabled checks if scrubbing is enabled @@ -174,6 +180,19 @@ func isRequestBase(m genMap) bool { return a && c } +// ScrubCreateOptions scrubs a JSON-encoded CreateOptions struct, +// removing sensitive fields (env vars, annotations) from the embedded OCI Spec. +func ScrubCreateOptions(b []byte) ([]byte, error) { + return scrubBytes(b, scrubCreateOptions) +} + +func scrubCreateOptions(m genMap) error { + if spec, ok := index(m, "Spec"); ok { + return scrubOCISpec(spec) + } + return nil +} + // combination `m, ok := m[s]` and `m, ok := m.(genMap)` func index(m genMap, s string) (genMap, bool) { if m, ok := m[s]; ok { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go b/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go index dac5a708e..78eeca8a2 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go @@ -7,13 +7,23 @@ const ( Namespace = "namespace" Operation = "operation" - ID = "id" - ContainerID = "cid" - ExecID = "eid" - ProcessID = "pid" - TaskID = "tid" - UVMID = "uvm-id" - SandboxID = "sandbox-id" + ID = "id" + SourceContainerID = "src_cid" + DestinationContainerID = "dst_cid" + ContainerID = "cid" + GCSContainerID = "gcs_container_id" + ExecID = "eid" + GuestNetworkNamespaceID = "guest_netns_id" + MigratedNamespaceID = "migrated_netns_id" + NamespaceID = "namespace-id" + SourcePodID = "src_pod_id" + DestinationPodID = "dst_pod_id" + PodID = "pod-id" + ProcessID = "pid" + SandboxID = "sandbox-id" + TaskID = "tid" + UVMID = "uvm-id" + VirtualSandboxID = "virtual-sandbox-id" // networking and IO @@ -22,6 +32,13 @@ const ( Bytes = "bytes" Pipe = "pipe" + // SCSI Constants + + Controller = "controller" + LUN = "lun" + DiskType = "disk-type" + Partition = "partition" + // Common Misc Attempt = "attemptNo" @@ -70,6 +87,12 @@ const ( ShimPid = "shim-pid" TaskPid = "task-pid" + // vpci device + + VMBusGUID = "vmBusGUID" + DeviceID = "deviceInstanceID" + VFIndex = "virtualFunctionIndex" + // sandbox NetNsPath = "net-ns-path" @@ -88,6 +111,11 @@ const ( VMShimOperation = "vmshim-op" + // migration + + SessionID = "session-id" + Action = "action" + // logging and tracing TraceID = "traceID" diff --git a/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go b/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go deleted file mode 100644 index bf8186401..000000000 --- a/vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go +++ /dev/null @@ -1,69 +0,0 @@ -package oc - -import ( - "errors" - "io" - "net" - "os" - - errdefs "github.com/containerd/errdefs/pkg/errgrpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -// todo: break import cycle with "internal/hcs/errors.go" and reference errors defined there -// todo: add errors defined in "internal/guest/gcserror" (Hresult does not implement error) - -func toStatusCode(err error) codes.Code { - // checks if err implements GRPCStatus() *"google.golang.org/grpc/status".Status, - // wraps an error defined in "github.com/containerd/errdefs", or is a - // context timeout or cancelled error - if s, ok := status.FromError(errdefs.ToGRPC(err)); ok { - return s.Code() - } - - switch { - // case isAny(err): - // return codes.Cancelled - case isAny(err, os.ErrInvalid): - return codes.InvalidArgument - case isAny(err, os.ErrDeadlineExceeded): - return codes.DeadlineExceeded - case isAny(err, os.ErrNotExist): - return codes.NotFound - case isAny(err, os.ErrExist): - return codes.AlreadyExists - case isAny(err, os.ErrPermission): - return codes.PermissionDenied - // case isAny(err): - // return codes.ResourceExhausted - case isAny(err, os.ErrClosed, net.ErrClosed, io.ErrClosedPipe, io.ErrShortBuffer): - return codes.FailedPrecondition - // case isAny(err): - // return codes.Aborted - // case isAny(err): - // return codes.OutOfRange - // case isAny(err): - // return codes.Unimplemented - case isAny(err, io.ErrNoProgress): - return codes.Internal - // case isAny(err): - // return codes.Unavailable - case isAny(err, io.ErrShortWrite, io.ErrUnexpectedEOF): - return codes.DataLoss - // case isAny(err): - // return codes.Unauthenticated - default: - return codes.Unknown - } -} - -// isAny returns true if errors.Is is true for any of the provided errors, errs. -func isAny(err error, errs ...error) bool { - for _, e := range errs { - if errors.Is(err, e) { - return true - } - } - return false -} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go b/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go deleted file mode 100644 index ffa02f1c1..000000000 --- a/vendor/github.com/Microsoft/hcsshim/internal/oc/exporter.go +++ /dev/null @@ -1,86 +0,0 @@ -package oc - -import ( - "github.com/sirupsen/logrus" - "go.opencensus.io/trace" - "google.golang.org/grpc/codes" - - "github.com/Microsoft/hcsshim/internal/log" - "github.com/Microsoft/hcsshim/internal/logfields" -) - -const spanMessage = "Span %s" - -var _errorCodeKey = logrus.ErrorKey + "Code" - -// LogrusExporter is an OpenCensus `trace.Exporter` that exports -// `trace.SpanData` to logrus output. -type LogrusExporter struct{} - -var _ trace.Exporter = &LogrusExporter{} - -// ExportSpan exports `s` based on the the following rules: -// -// 1. All output will contain `s.Attributes`, `s.SpanKind`, `s.TraceID`, -// `s.SpanID`, and `s.ParentSpanID` for correlation -// -// 2. Any calls to .Annotate will not be supported. -// -// 3. The span itself will be written at `logrus.InfoLevel` unless -// `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel` -// providing `s.Status.Message` as the error value. -func (le *LogrusExporter) ExportSpan(s *trace.SpanData) { - if s.DroppedAnnotationCount > 0 { - logrus.WithFields(logrus.Fields{ - "name": s.Name, - logfields.TraceID: s.TraceID.String(), - logfields.SpanID: s.SpanID.String(), - "dropped": s.DroppedAttributeCount, - "maxAttributes": len(s.Attributes), - }).Warning("span had dropped attributes") - } - - entry := log.L.Dup() - // Combine all span annotations with span data (eg, trace ID, span ID, parent span ID, - // error, status code) - // (OC) Span attributes are guaranteed to be strings, bools, or int64s, so we can - // can skip overhead in entry.WithFields() and add them directly to entry.Data. - // Preallocate ahead of time, since we should add, at most, 10 additional entries - data := make(logrus.Fields, len(entry.Data)+len(s.Attributes)+10) - - // Default log entry may have prexisting/application-wide data - for k, v := range entry.Data { - data[k] = v - } - for k, v := range s.Attributes { - data[k] = v - } - - data[logfields.Name] = s.Name - data[logfields.TraceID] = s.TraceID.String() - data[logfields.SpanID] = s.SpanID.String() - data[logfields.ParentSpanID] = s.ParentSpanID.String() - data[logfields.StartTime] = s.StartTime - data[logfields.EndTime] = s.EndTime - data[logfields.Duration] = s.EndTime.Sub(s.StartTime) - if sk := spanKindToString(s.SpanKind); sk != "" { - data["spanKind"] = sk - } - - level := logrus.InfoLevel - if s.Code != 0 { - level = logrus.ErrorLevel - - // don't overwrite an existing "error" or "errorCode" attributes - if _, ok := data[logrus.ErrorKey]; !ok { - data[logrus.ErrorKey] = s.Message - } - if _, ok := data[_errorCodeKey]; !ok { - data[_errorCodeKey] = codes.Code(s.Code).String() - } - } - - entry.Data = data - entry.Time = s.StartTime - entry.Logf(level, spanMessage, s.Name) -} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go b/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go deleted file mode 100644 index 726078432..000000000 --- a/vendor/github.com/Microsoft/hcsshim/internal/oc/span.go +++ /dev/null @@ -1,58 +0,0 @@ -package oc - -import ( - "context" - - "github.com/Microsoft/hcsshim/internal/log" - "go.opencensus.io/trace" -) - -var DefaultSampler = trace.AlwaysSample() - -// SetSpanStatus sets `span.SetStatus` to the proper status depending on `err`. If -// `err` is `nil` assumes `trace.StatusCodeOk`. -func SetSpanStatus(span *trace.Span, err error) { - status := trace.Status{} - if err != nil { - status.Code = int32(toStatusCode(err)) - status.Message = err.Error() - } - span.SetStatus(status) -} - -// StartSpan wraps "go.opencensus.io/trace".StartSpan, but, if the span is sampling, -// adds a log entry to the context that points to the newly created span. -func StartSpan(ctx context.Context, name string, o ...trace.StartOption) (context.Context, *trace.Span) { - ctx, s := trace.StartSpan(ctx, name, o...) - return update(ctx, s) -} - -// StartSpanWithRemoteParent wraps "go.opencensus.io/trace".StartSpanWithRemoteParent. -// -// See StartSpan for more information. -func StartSpanWithRemoteParent(ctx context.Context, name string, parent trace.SpanContext, o ...trace.StartOption) (context.Context, *trace.Span) { - ctx, s := trace.StartSpanWithRemoteParent(ctx, name, parent, o...) - return update(ctx, s) -} - -func update(ctx context.Context, s *trace.Span) (context.Context, *trace.Span) { - if s.IsRecordingEvents() { - ctx = log.UpdateContext(ctx) - } - - return ctx, s -} - -var WithServerSpanKind = trace.WithSpanKind(trace.SpanKindServer) -var WithClientSpanKind = trace.WithSpanKind(trace.SpanKindClient) - -func spanKindToString(sk int) string { - switch sk { - case trace.SpanKindClient: - return "client" - case trace.SpanKindServer: - return "server" - default: - return "" - } -} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/ot/exporter.go b/vendor/github.com/Microsoft/hcsshim/internal/ot/exporter.go new file mode 100644 index 000000000..0387c1837 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/ot/exporter.go @@ -0,0 +1,98 @@ +package ot + +import ( + "context" + "maps" + + "github.com/sirupsen/logrus" + + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" + otelcodes "go.opentelemetry.io/otel/codes" + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +const spanMessage = "Span" + +var _errorCodeKey = logrus.ErrorKey + "Code" + +// LogrusExporter is an OpenTelemetry `sdktrace.SpanExporter` that exports +// `trace.ReadOnlySpan` to logrus output. +type LogrusExporter struct{} + +var _ sdktrace.SpanExporter = &LogrusExporter{} + +// ExportSpans exports each `spans` based on the following rules: +// +// 1. All output will contain `s.Attributes`, `s.SpanKind`, `s.TraceID`, +// `s.SpanID`, and `s.ParentSpanID` for correlation +// +// 2. Any calls to .Annotate will not be supported. +// +// 3. The span itself will be written at `logrus.InfoLevel` unless +// `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel` +// providing `s.Status.Message` as the error value. +func (le *LogrusExporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error { + for _, s := range spans { + if s.DroppedAttributes() > 0 { + logrus.WithFields(logrus.Fields{ + "name": s.Name(), + logfields.TraceID: s.SpanContext().TraceID().String(), + logfields.SpanID: s.SpanContext().SpanID().String(), + "dropped": s.DroppedAttributes(), + "maxAttributes": len(s.Attributes()), + }).Warning("span had dropped attributes") + } + + entry := log.L.Dup() + // Combine all span annotations with span data (eg, trace ID, span ID, parent span ID, + // error, status code) + // Span attributes are guaranteed to be strings, bools, or int64s, so we can + // skip overhead in entry.WithFields() and add them directly to entry.Data. + // Preallocate ahead of time, since we should add, at most, 10 additional entries + data := make(logrus.Fields, len(entry.Data)+len(s.Attributes())+10) + + // Default log entry may have prexisting/application-wide data + maps.Copy(data, entry.Data) + for _, attr := range s.Attributes() { + data[string(attr.Key)] = attr.Value.AsInterface() + } + + sc := s.SpanContext() + data[logfields.Name] = s.Name() + data[logfields.TraceID] = sc.TraceID().String() + data[logfields.SpanID] = sc.SpanID().String() + if s.Parent().IsValid() { + data[logfields.ParentSpanID] = s.Parent().SpanID().String() + } + data[logfields.StartTime] = s.StartTime() + data[logfields.EndTime] = s.EndTime() + data[logfields.Duration] = s.EndTime().Sub(s.StartTime()) + if sk := spanKindToString(s.SpanKind()); sk != "" { + data["spanKind"] = sk + } + + level := logrus.InfoLevel + if s.Status().Code == otelcodes.Error { + level = logrus.ErrorLevel + + // don't overwrite an existing "error" or "errorCode" attributes + if _, ok := data[logrus.ErrorKey]; !ok { + data[logrus.ErrorKey] = s.Status().Description + } + if _, ok := data[_errorCodeKey]; !ok { + data[_errorCodeKey] = s.Status().Code.String() + } + } + + entry.Data = data + entry.Time = s.StartTime() + entry.Log(level, spanMessage) + } + return nil +} + +func (le *LogrusExporter) Shutdown(ctx context.Context) error { + log.G(ctx).Trace("LogrusExporter shutting down") + return nil +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/ot/span.go b/vendor/github.com/Microsoft/hcsshim/internal/ot/span.go new file mode 100644 index 000000000..0f8efc9cc --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/ot/span.go @@ -0,0 +1,76 @@ +package ot + +import ( + "context" + + "github.com/Microsoft/hcsshim/internal/log" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/codes" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" +) + +const ( + TracerName = "containerd-shim-runhcs-v1" +) + +var DefaultSampler = sdktrace.AlwaysSample() + +// SetSpanStatus sets the span's OpenTelemetry status based on `err`. +// +// If `err` is non-nil the error is recorded on the span and the status is +// set to `codes.Error`. +// +// If `err` is nil the span is left in its default (Unset) status. The +// exporter treats Unset the same as Ok for level selection (Info), so +// downstream log level does not change. Leaving the status Unset instead of +// calling SetStatus(Ok, "") avoids the OpenTelemetry spec's "Ok is terminal" +// rule, under which a subsequent SetStatus(Error, ...) would be silently +// dropped. +func SetSpanStatus(span trace.Span, err error) { + if err == nil { + return + } + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) +} + +// StartSpan wraps otel.Start(), but, if the span is sampling, +// adds a log entry to the context that points to the newly created span. +func StartSpan(ctx context.Context, name string, o ...trace.SpanStartOption) (context.Context, trace.Span) { + tracer := otel.Tracer(TracerName) + ctx, s := tracer.Start(ctx, name, o...) + return update(ctx, s) +} + +// StartSpanWithRemoteParent wraps "go.opentelemetry.io/otel/trace".ContextWithRemoteSpanContext +// +// See StartSpan for more information. +func StartSpanWithRemoteParent(ctx context.Context, name string, parent trace.SpanContext, o ...trace.SpanStartOption) (context.Context, trace.Span) { + tracer := otel.Tracer(TracerName) + ctx = trace.ContextWithRemoteSpanContext(ctx, parent) + ctx, s := tracer.Start(ctx, name, o...) + return update(ctx, s) +} + +func update(ctx context.Context, s trace.Span) (context.Context, trace.Span) { + if s.IsRecording() { + ctx = log.UpdateContext(ctx) + } + + return ctx, s +} + +var WithServerSpanKind = trace.WithSpanKind(trace.SpanKindServer) +var WithClientSpanKind = trace.WithSpanKind(trace.SpanKindClient) + +func spanKindToString(sk trace.SpanKind) string { + switch sk { + case trace.SpanKindClient: + return "client" + case trace.SpanKindServer: + return "server" + default: + return "" + } +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go b/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go index 5819dc6df..c556249e8 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go @@ -7,14 +7,13 @@ import ( "syscall" "time" - "github.com/sirupsen/logrus" - "go.opencensus.io/trace" - "github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/logfields" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/internal/timeout" + "github.com/sirupsen/logrus" + "go.opentelemetry.io/otel/attribute" ) //go:generate go tool github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go vmcompute.go @@ -117,15 +116,15 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error } func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSystems, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsEnumerateComputeSystems") + ctx, span := ot.StartSpan(ctx, "HcsEnumerateComputeSystems") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("query", query)) + span.SetAttributes(attribute.String("query", query)) return computeSystems, result, execute(ctx, timeout.SyscallWatcher, func() error { var ( @@ -144,19 +143,19 @@ func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSyst } func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration string, identity syscall.Handle) (computeSystem HcsSystem, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsCreateComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsCreateComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() - span.AddAttributes( - trace.StringAttribute("id", id), - trace.StringAttribute("configuration", configuration)) + span.SetAttributes( + attribute.String("id", id), + attribute.String("configuration", configuration)) return computeSystem, result, execute(ctx, timeout.SystemCreate, func() error { var resultp *uint16 @@ -169,13 +168,13 @@ func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration strin } func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSystem, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsOpenComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsOpenComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() return computeSystem, result, execute(ctx, timeout.SyscallWatcher, func() error { @@ -189,9 +188,9 @@ func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSys } func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr error) { - ctx, span := oc.StartSpan(ctx, "HcsCloseComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsCloseComputeSystem") defer span.End() - defer func() { oc.SetSpanStatus(span, hr) }() + defer func() { ot.SetSpanStatus(span, hr) }() return execute(ctx, timeout.SyscallWatcher, func() error { return hcsCloseComputeSystem(computeSystem) @@ -199,17 +198,17 @@ func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr er } func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsStartComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsStartComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() - span.AddAttributes(trace.StringAttribute("options", options)) + span.SetAttributes(attribute.String("options", options)) return result, execute(ctx, timeout.SystemStart, func() error { var resultp *uint16 @@ -222,17 +221,17 @@ func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option } func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsShutdownComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsShutdownComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() - span.AddAttributes(trace.StringAttribute("options", options)) + span.SetAttributes(attribute.String("options", options)) return result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -245,17 +244,17 @@ func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, opt } func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsTerminateComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsTerminateComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() - span.AddAttributes(trace.StringAttribute("options", options)) + span.SetAttributes(attribute.String("options", options)) return result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -268,17 +267,17 @@ func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, op } func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsPauseComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsPauseComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() - span.AddAttributes(trace.StringAttribute("options", options)) + span.SetAttributes(attribute.String("options", options)) return result, execute(ctx, timeout.SystemPause, func() error { var resultp *uint16 @@ -291,17 +290,17 @@ func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option } func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsResumeComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsResumeComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() - span.AddAttributes(trace.StringAttribute("options", options)) + span.SetAttributes(attribute.String("options", options)) return result, execute(ctx, timeout.SystemResume, func() error { var resultp *uint16 @@ -314,15 +313,15 @@ func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, optio } func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem, propertyQuery string) (properties, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsGetComputeSystemProperties") + ctx, span := ot.StartSpan(ctx, "HcsGetComputeSystemProperties") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("propertyQuery", propertyQuery)) + span.SetAttributes(attribute.String("propertyQuery", propertyQuery)) return properties, result, execute(ctx, timeout.SyscallWatcher, func() error { var ( @@ -341,15 +340,15 @@ func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem } func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, configuration string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsModifyComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsModifyComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("configuration", configuration)) + span.SetAttributes(attribute.String("configuration", configuration)) return result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -362,15 +361,15 @@ func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, confi } func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsModifyServiceSettings") + ctx, span := ot.StartSpan(ctx, "HcsModifyServiceSettings") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("settings", settings)) + span.SetAttributes(attribute.String("settings", settings)) return result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -383,9 +382,9 @@ func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result str } func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSystem, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsRegisterComputeSystemCallback") + ctx, span := ot.StartSpan(ctx, "HcsRegisterComputeSystemCallback") defer span.End() - defer func() { oc.SetSpanStatus(span, hr) }() + defer func() { ot.SetSpanStatus(span, hr) }() return callbackHandle, execute(ctx, timeout.SyscallWatcher, func() error { return hcsRegisterComputeSystemCallback(computeSystem, callback, context, &callbackHandle) @@ -393,9 +392,9 @@ func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSys } func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) { - ctx, span := oc.StartSpan(ctx, "HcsUnregisterComputeSystemCallback") + ctx, span := ot.StartSpan(ctx, "HcsUnregisterComputeSystemCallback") defer span.End() - defer func() { oc.SetSpanStatus(span, hr) }() + defer func() { ot.SetSpanStatus(span, hr) }() return execute(ctx, timeout.SyscallWatcher, func() error { return hcsUnregisterComputeSystemCallback(callbackHandle) @@ -403,18 +402,18 @@ func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle Hcs } func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processParameters string) (processInformation HcsProcessInformation, process HcsProcess, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsCreateProcess") + ctx, span := ot.StartSpan(ctx, "HcsCreateProcess") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - if span.IsRecordingEvents() { + if span.IsRecording() { // wont handle v1 process parameters if s, err := log.ScrubProcessParameters(processParameters); err == nil { - span.AddAttributes(trace.StringAttribute("processParameters", s)) + span.SetAttributes(attribute.String("processParameters", s)) } } @@ -429,15 +428,15 @@ func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processPara } func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) (process HcsProcess, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsOpenProcess") + ctx, span := ot.StartSpan(ctx, "HcsOpenProcess") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.Int64Attribute("pid", int64(pid))) + span.SetAttributes(attribute.Int64("pid", int64(pid))) return process, result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -450,9 +449,9 @@ func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) ( } func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) { - ctx, span := oc.StartSpan(ctx, "HcsCloseProcess") + ctx, span := ot.StartSpan(ctx, "HcsCloseProcess") defer span.End() - defer func() { oc.SetSpanStatus(span, hr) }() + defer func() { ot.SetSpanStatus(span, hr) }() return execute(ctx, timeout.SyscallWatcher, func() error { return hcsCloseProcess(process) @@ -460,13 +459,13 @@ func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) { } func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsTerminateProcess") + ctx, span := ot.StartSpan(ctx, "HcsTerminateProcess") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() return result, execute(ctx, timeout.SyscallWatcher, func() error { @@ -480,15 +479,15 @@ func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result strin } func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsSignalProcess") + ctx, span := ot.StartSpan(ctx, "HcsSignalProcess") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("options", options)) + span.SetAttributes(attribute.String("options", options)) return result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -501,13 +500,13 @@ func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) } func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInformation HcsProcessInformation, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsGetProcessInfo") + ctx, span := ot.StartSpan(ctx, "HcsGetProcessInfo") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() return processInformation, result, execute(ctx, timeout.SyscallWatcher, func() error { @@ -521,13 +520,13 @@ func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInforma } func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processProperties, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsGetProcessProperties") + ctx, span := ot.StartSpan(ctx, "HcsGetProcessProperties") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() return processProperties, result, execute(ctx, timeout.SyscallWatcher, func() error { @@ -547,15 +546,15 @@ func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processP } func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsModifyProcess") + ctx, span := ot.StartSpan(ctx, "HcsModifyProcess") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("settings", settings)) + span.SetAttributes(attribute.String("settings", settings)) return result, execute(ctx, timeout.SyscallWatcher, func() error { var resultp *uint16 @@ -568,15 +567,15 @@ func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) } func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (properties, result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsGetServiceProperties") + ctx, span := ot.StartSpan(ctx, "HcsGetServiceProperties") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) }() - span.AddAttributes(trace.StringAttribute("propertyQuery", propertyQuery)) + span.SetAttributes(attribute.String("propertyQuery", propertyQuery)) return properties, result, execute(ctx, timeout.SyscallWatcher, func() error { var ( @@ -595,9 +594,9 @@ func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (proper } func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsRegisterProcessCallback") + ctx, span := ot.StartSpan(ctx, "HcsRegisterProcessCallback") defer span.End() - defer func() { oc.SetSpanStatus(span, hr) }() + defer func() { ot.SetSpanStatus(span, hr) }() return callbackHandle, execute(ctx, timeout.SyscallWatcher, func() error { return hcsRegisterProcessCallback(process, callback, context, &callbackHandle) @@ -605,9 +604,9 @@ func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callba } func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) { - ctx, span := oc.StartSpan(ctx, "HcsUnregisterProcessCallback") + ctx, span := ot.StartSpan(ctx, "HcsUnregisterProcessCallback") defer span.End() - defer func() { oc.SetSpanStatus(span, hr) }() + defer func() { ot.SetSpanStatus(span, hr) }() return execute(ctx, timeout.SyscallWatcher, func() error { return hcsUnregisterProcessCallback(callbackHandle) @@ -615,14 +614,14 @@ func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallba } func HcsSaveComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) { - ctx, span := oc.StartSpan(ctx, "HcsSaveComputeSystem") + ctx, span := ot.StartSpan(ctx, "HcsSaveComputeSystem") defer span.End() defer func() { if result != "" { - span.AddAttributes(trace.StringAttribute("result", result)) + span.SetAttributes(attribute.String("result", result)) } if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned - oc.SetSpanStatus(span, hr) + ot.SetSpanStatus(span, hr) } }() diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go index e12253c94..a258bb071 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go @@ -6,8 +6,8 @@ import ( "context" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // ActivateLayer will find the layer with the given id and mount it's filesystem. @@ -16,10 +16,10 @@ import ( // An activated layer must later be deactivated via DeactivateLayer. func ActivateLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ActivateLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) err = activateLayer(&stdDriverInfo, path) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerreader.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerreader.go index 807b7de1f..2d0903ff3 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerreader.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerreader.go @@ -12,12 +12,12 @@ import ( "github.com/Microsoft/go-winio" "github.com/Microsoft/hcsshim/internal/longpath" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/trace" ) type baseLayerReader struct { - s *trace.Span + s trace.Span root string result chan *fileEntry proceed chan bool @@ -25,7 +25,7 @@ type baseLayerReader struct { backupReader *winio.BackupFileReader } -func newBaseLayerReader(root string, s *trace.Span) (r *baseLayerReader) { +func newBaseLayerReader(root string, s trace.Span) (r *baseLayerReader) { r = &baseLayerReader{ s: s, root: root, @@ -207,7 +207,7 @@ func (r *baseLayerReader) Read(b []byte) (int, error) { func (r *baseLayerReader) Close() (err error) { defer r.s.End() defer func() { - oc.SetSpanStatus(r.s, err) + ot.SetSpanStatus(r.s, err) close(r.proceed) }() r.proceed <- false diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerwriter.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerwriter.go index aea8b421e..c68bba6aa 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerwriter.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayerwriter.go @@ -11,15 +11,15 @@ import ( "github.com/Microsoft/go-winio" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/internal/safefile" "github.com/Microsoft/hcsshim/internal/winapi" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/trace" ) type baseLayerWriter struct { ctx context.Context - s *trace.Span + s trace.Span root *os.File f *os.File @@ -145,7 +145,7 @@ func (w *baseLayerWriter) Write(b []byte) (int, error) { func (w *baseLayerWriter) Close() (err error) { defer w.s.End() - defer func() { oc.SetSpanStatus(w.s, err) }() + defer func() { ot.SetSpanStatus(w.s, err) }() defer func() { w.root.Close() w.root = nil diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/converttobaselayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/converttobaselayer.go index d25c3c520..133f16fe4 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/converttobaselayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/converttobaselayer.go @@ -10,11 +10,11 @@ import ( "github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/longpath" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/internal/safefile" "github.com/Microsoft/hcsshim/internal/winapi" "github.com/pkg/errors" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" "golang.org/x/sys/windows" ) @@ -137,10 +137,10 @@ func convertToBaseLayer(ctx context.Context, root *os.File) error { // desired file content for a UtilityVM under UtilityVM/Files/ func ConvertToBaseLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ConvertToBaseLayer" - ctx, span := trace.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) root, err := safefile.OpenRoot(path) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go index 932475723..43d1c4d41 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go @@ -6,20 +6,20 @@ import ( "context" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // CreateLayer creates a new, empty, read-only layer on the filesystem based on // the parent layer provided. func CreateLayer(ctx context.Context, path, parent string) (err error) { title := "hcsshim::CreateLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("parent", parent)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("path", path), + attribute.String("parent", parent)) err = createLayer(&stdDriverInfo, path, parent) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go index 5c9d5d250..d44c6922e 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go @@ -7,20 +7,20 @@ import ( "strings" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // CreateScratchLayer creates and populates new read-write layer for use by a container. // This requires the full list of paths to all parent layers up to the base func CreateScratchLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) { title := "hcsshim::CreateScratchLayer" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("path", path), + attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) // Generate layer descriptors layers, err := layerPathsToDescriptors(ctx, parentLayerPaths) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go index e3bc77cbc..2db0556a2 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go @@ -6,17 +6,17 @@ import ( "context" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // DeactivateLayer will dismount a layer that was mounted via ActivateLayer. func DeactivateLayer(ctx context.Context, path string) (err error) { title := "hcsshim::DeactivateLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) err = deactivateLayer(&stdDriverInfo, path) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go index d0a59efe1..1b3711e6c 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go @@ -6,18 +6,18 @@ import ( "context" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // DestroyLayer will remove the on-disk files representing the layer with the given // path, including that layer's containing folder, if any. func DestroyLayer(ctx context.Context, path string) (err error) { title := "hcsshim::DestroyLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) err = destroyLayer(&stdDriverInfo, path) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go index 35fcbedb3..f576fe27b 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go @@ -4,25 +4,26 @@ package wclayer import ( "context" + "go.opentelemetry.io/otel/attribute" "os" "path/filepath" "syscall" "unsafe" + "github.com/Microsoft/go-winio/vhd" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" ) // ExpandScratchSize expands the size of a layer to at least size bytes. func ExpandScratchSize(ctx context.Context, path string, size uint64) (err error) { title := "hcsshim::ExpandScratchSize" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.Int64Attribute("size", int64(size))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("path", path), + attribute.Int64("size", int64(size))) err = expandSandboxSize(&stdDriverInfo, path, size) if err != nil { @@ -75,7 +76,7 @@ func attachVhd(path string) (syscall.Handle, error) { if err != nil { return 0, &os.PathError{Op: "OpenVirtualDisk", Path: path, Err: err} } - err = attachVirtualDisk(handle, 0, 0, 0, 0, 0) + err = vhd.AttachVirtualDisk(handle, vhd.AttachVirtualDiskFlagBypassDefaultEncryptionPolicy, nil) if err != nil { syscall.Close(handle) return 0, &os.PathError{Op: "AttachVirtualDisk", Path: path, Err: err} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go index d4c677aab..49600b589 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go @@ -9,8 +9,9 @@ import ( "github.com/Microsoft/go-winio" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // ExportLayer will create a folder at exportFolderPath and fill that folder with @@ -20,13 +21,13 @@ import ( // perform the export. func ExportLayer(ctx context.Context, path string, exportFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ExportLayer" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("exportFolderPath", exportFolderPath), - trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("path", path), + attribute.String("exportFolderPath", exportFolderPath), + attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) // Generate layer descriptors layers, err := layerPathsToDescriptors(ctx, parentLayerPaths) @@ -58,16 +59,16 @@ type LayerReader interface { // The caller must have taken the SeBackupPrivilege privilege // to call this and any methods on the resulting LayerReader. func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) (_ LayerReader, err error) { - ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerReader") + ctx, span := ot.StartSpan(ctx, "hcsshim::NewLayerReader") defer func() { if err != nil { - oc.SetSpanStatus(span, err) + ot.SetSpanStatus(span, err) span.End() } }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) + span.SetAttributes( + attribute.String("path", path), + attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) if len(parentLayerPaths) == 0 { // This is a base layer. It gets exported differently. @@ -92,14 +93,14 @@ func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) type legacyLayerReaderWrapper struct { ctx context.Context - s *trace.Span + s trace.Span *legacyLayerReader } func (r *legacyLayerReaderWrapper) Close() (err error) { defer r.s.End() - defer func() { oc.SetSpanStatus(r.s, err) }() + defer func() { ot.SetSpanStatus(r.s, err) }() err = r.legacyLayerReader.Close() os.RemoveAll(r.root) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go index 715e06e37..675a6b7fa 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go @@ -4,12 +4,12 @@ package wclayer import ( "context" + "go.opentelemetry.io/otel/attribute" "syscall" "github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/log" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" ) // GetLayerMountPath will look for a mounted layer with the given path and return @@ -18,10 +18,10 @@ import ( // folder path at which the layer is stored. func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) { title := "hcsshim::GetLayerMountPath" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) var mountPathLength uintptr = 0 @@ -47,6 +47,6 @@ func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) { } mountPath := syscall.UTF16ToString(mountPathp[0:]) - span.AddAttributes(trace.StringAttribute("mountPath", mountPath)) + span.SetAttributes(attribute.String("mountPath", mountPath)) return mountPath, nil } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go index 5e400fb20..d13965be7 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go @@ -7,8 +7,8 @@ import ( "github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/interop" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // GetSharedBaseImages will enumerate the images stored in the common central @@ -16,9 +16,9 @@ import ( // of registering them with the graphdriver, graph, and tagstore. func GetSharedBaseImages(ctx context.Context) (_ string, err error) { title := "hcsshim::GetSharedBaseImages" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + defer func() { ot.SetSpanStatus(span, err) }() var buffer *uint16 err = getBaseImages(&buffer) @@ -26,6 +26,6 @@ func GetSharedBaseImages(ctx context.Context) (_ string, err error) { return "", hcserror.New(err, title, "") } imageData := interop.ConvertAndFreeCoTaskMemString(buffer) - span.AddAttributes(trace.StringAttribute("imageData", imageData)) + span.SetAttributes(attribute.String("imageData", imageData)) return imageData, nil } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go index 20217ed81..6b9098f2e 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go @@ -4,21 +4,21 @@ package wclayer import ( "context" + "go.opentelemetry.io/otel/attribute" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" ) // GrantVmAccess adds access to a file for a given VM func GrantVmAccess(ctx context.Context, vmid string, filepath string) (err error) { title := "hcsshim::GrantVmAccess" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("vm-id", vmid), - trace.StringAttribute("path", filepath)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("vm-id", vmid), + attribute.String("path", filepath)) err = grantVmAccess(vmid, filepath) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go index 8dab72bb2..186c9186f 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go @@ -10,9 +10,10 @@ import ( "github.com/Microsoft/go-winio" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/ot" "github.com/Microsoft/hcsshim/internal/safefile" - "go.opencensus.io/trace" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // ImportLayer will take the contents of the folder at importFolderPath and import @@ -21,13 +22,13 @@ import ( // be present on the system at the paths provided in parentLayerPaths. func ImportLayer(ctx context.Context, path string, importFolderPath string, parentLayerPaths []string) (err error) { title := "hcsshim::ImportLayer" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("importFolderPath", importFolderPath), - trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("path", path), + attribute.String("importFolderPath", importFolderPath), + attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) // Generate layer descriptors layers, err := layerPathsToDescriptors(ctx, parentLayerPaths) @@ -59,7 +60,7 @@ type LayerWriter interface { type legacyLayerWriterWrapper struct { ctx context.Context - s *trace.Span + s trace.Span *legacyLayerWriter path string @@ -68,7 +69,7 @@ type legacyLayerWriterWrapper struct { func (r *legacyLayerWriterWrapper) Close() (err error) { defer r.s.End() - defer func() { oc.SetSpanStatus(r.s, err) }() + defer func() { ot.SetSpanStatus(r.s, err) }() defer os.RemoveAll(r.root.Name()) defer r.CloseRoots() @@ -125,16 +126,16 @@ func (r *legacyLayerWriterWrapper) Close() (err error) { // The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges // to call this and any methods on the resulting LayerWriter. func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string) (_ LayerWriter, err error) { - ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerWriter") + ctx, span := ot.StartSpan(ctx, "hcsshim::NewLayerWriter") defer func() { if err != nil { - oc.SetSpanStatus(span, err) + ot.SetSpanStatus(span, err) span.End() } }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) + span.SetAttributes( + attribute.String("path", path), + attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) if len(parentLayerPaths) == 0 { // This is a base layer. It gets imported differently. @@ -155,6 +156,10 @@ func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string) } w, err := newLegacyLayerWriter(importPath, parentLayerPaths, path) if err != nil { + // Clean up the temporary import directory so it is not leaked when + // the writer fails to initialize (matches NewLayerReader's handling + // of exportPath). + os.RemoveAll(importPath) return nil, err } return &legacyLayerWriterWrapper{ diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go index 4d82977ea..806774ea7 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go @@ -4,20 +4,20 @@ package wclayer import ( "context" + "go.opentelemetry.io/otel/attribute" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" ) // LayerExists will return true if a layer with the given id exists and is known // to the system. func LayerExists(ctx context.Context, path string) (_ bool, err error) { title := "hcsshim::LayerExists" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) // Call the procedure itself. var exists uint32 @@ -25,6 +25,6 @@ func LayerExists(ctx context.Context, path string) (_ bool, err error) { if err != nil { return false, hcserror.New(err, title, "") } - span.AddAttributes(trace.BoolAttribute("layer-exists", exists != 0)) + span.SetAttributes(attribute.Bool("layer-exists", exists != 0)) return exists != 0, nil } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go index d4805f144..68107ce1d 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go @@ -4,20 +4,20 @@ package wclayer import ( "context" + "go.opentelemetry.io/otel/attribute" "path/filepath" "github.com/Microsoft/go-winio/pkg/guid" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" ) // LayerID returns the layer ID of a layer on disk. func LayerID(ctx context.Context, path string) (_ guid.GUID, err error) { title := "hcsshim::LayerID" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) _, file := filepath.Split(path) return NameToGuid(ctx, file) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go index 627060cee..e73de48b0 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go @@ -436,13 +436,32 @@ func (w *legacyLayerWriter) initUtilityVM() error { return nil } -func (w *legacyLayerWriter) reset() error { - err := w.bufWriter.Flush() - if err != nil { +func (w *legacyLayerWriter) reset() (err error) { + // Always close the current backup writer and file handle, even if an error + // occurs below (e.g. bufWriter.Flush fails with ENOSPC when the disk is + // full). Leaving these handles open on Windows prevents the temporary + // import directory (defaults to SystemTemp, i.e. C:\Windows\SystemTemp\hcs*) + // from being removed by the deferred os.RemoveAll in legacyLayerWriterWrapper.Close, + // which leaks the directory and compounds disk-space exhaustion. + defer func() { + if w.backupWriter != nil { + w.backupWriter.Close() + w.backupWriter = nil + } + if w.currentFile != nil { + w.currentFile.Close() + w.currentFile = nil + w.currentFileName = "" + w.currentFileRoot = nil + } + w.currentIsDir = false + }() + + if err = w.bufWriter.Flush(); err != nil { return err } w.bufWriter.Reset(io.Discard) - if w.currentIsDir { + if w.currentIsDir && w.currentFile != nil { r := w.currentFile br := winio.NewBackupStreamReader(r) // Seek to the beginning of the backup stream, skipping the fileattrs @@ -475,16 +494,6 @@ func (w *legacyLayerWriter) reset() error { } w.currentIsDir = false } - if w.backupWriter != nil { - w.backupWriter.Close() - w.backupWriter = nil - } - if w.currentFile != nil { - w.currentFile.Close() - w.currentFile = nil - w.currentFileName = "" - w.currentFileRoot = nil - } return nil } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go index c45fa2750..6072630f7 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go @@ -4,11 +4,11 @@ package wclayer import ( "context" + "go.opentelemetry.io/otel/attribute" "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" ) // NameToGuid converts the given string into a GUID using the algorithm in the @@ -16,16 +16,16 @@ import ( // across all clients. func NameToGuid(ctx context.Context, name string) (_ guid.GUID, err error) { title := "hcsshim::NameToGuid" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("objectName", name)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("objectName", name)) var id guid.GUID err = nameToGuid(name, &id) if err != nil { return guid.GUID{}, hcserror.New(err, title, "") } - span.AddAttributes(trace.StringAttribute("guid", id.String())) + span.SetAttributes(attribute.String("guid", id.String())) return id, nil } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go index b66e07124..1fbbba99c 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go @@ -8,8 +8,8 @@ import ( "sync" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) var prepareLayerLock sync.Mutex @@ -21,12 +21,12 @@ var prepareLayerLock sync.Mutex // Disabling the filter must be done via UnprepareLayer. func PrepareLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) { title := "hcsshim::PrepareLayer" - ctx, span := oc.StartSpan(ctx, title) + ctx, span := ot.StartSpan(ctx, title) defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("path", path), - trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes( + attribute.String("path", path), + attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", "))) // Generate layer descriptors layers, err := layerPathsToDescriptors(ctx, parentLayerPaths) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go index 7c49cbda4..ba2e8660a 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go @@ -6,18 +6,18 @@ import ( "context" "os" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // ProcessBaseLayer post-processes a base layer that has had its files extracted. // The files should have been extracted to \Files. func ProcessBaseLayer(ctx context.Context, path string) (err error) { title := "hcsshim::ProcessBaseLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) err = processBaseImage(path) if err != nil { @@ -30,10 +30,10 @@ func ProcessBaseLayer(ctx context.Context, path string) (err error) { // The files should have been extracted to \Files. func ProcessUtilityVMImage(ctx context.Context, path string) (err error) { title := "hcsshim::ProcessUtilityVMImage" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) err = processUtilityImage(path) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go index fe20702c1..91d2c0a1f 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go @@ -6,18 +6,18 @@ import ( "context" "github.com/Microsoft/hcsshim/internal/hcserror" - "github.com/Microsoft/hcsshim/internal/oc" - "go.opencensus.io/trace" + "github.com/Microsoft/hcsshim/internal/ot" + "go.opentelemetry.io/otel/attribute" ) // UnprepareLayer disables the filesystem filter for the read-write layer with // the given id. func UnprepareLayer(ctx context.Context, path string) (err error) { title := "hcsshim::UnprepareLayer" - ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck + ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("path", path)) + defer func() { ot.SetSpanStatus(span, err) }() + span.SetAttributes(attribute.String("path", path)) err = unprepareLayer(&stdDriverInfo, path) if err != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimwriter/cimwriter.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimwriter/cimwriter.go index 5d58e487d..d8f4d4dc1 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimwriter/cimwriter.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimwriter/cimwriter.go @@ -3,7 +3,9 @@ package cimwriter import ( + "fmt" "sync" + "unsafe" "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -53,7 +55,12 @@ var load = sync.OnceValue(func() error { var buf [windows.MAX_PATH]uint16 n, _ := windows.GetModuleFileName(windows.Handle(modcimwriter.Handle()), &buf[0], uint32(len(buf))) if n > 0 { - logrus.WithField("path", windows.UTF16ToString(buf[:n])).Info("loaded cimwriter.dll") + path := windows.UTF16ToString(buf[:n]) + fields := logrus.Fields{"path": path} + if ver, err := getFileVersion(path); err == nil { + fields["version"] = ver + } + logrus.WithFields(fields).Info("loaded cimwriter.dll") } return nil }) @@ -62,3 +69,31 @@ var load = sync.OnceValue(func() error { func Supported() bool { return load() == nil } + +// getFileVersion returns the file version string (e.g. "10.0.26100.1") for the given path. +func getFileVersion(path string) (string, error) { + size, err := windows.GetFileVersionInfoSize(path, nil) + if err != nil { + return "", err + } + data := make([]byte, size) + if err := windows.GetFileVersionInfo(path, 0, size, unsafe.Pointer(&data[0])); err != nil { + return "", err + } + var info *windows.VS_FIXEDFILEINFO + var infoLen uint32 + if err := windows.VerQueryValue(unsafe.Pointer(&data[0]), `\`, unsafe.Pointer(&info), &infoLen); err != nil { + return "", err + } + return formatFileVersion(info), nil +} + +// formatFileVersion formats the file version from a VS_FIXEDFILEINFO as "major.minor.build.revision". +// See https://learn.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo +func formatFileVersion(info *windows.VS_FIXEDFILEINFO) string { + major := info.FileVersionMS >> 16 + minor := info.FileVersionMS & 0xffff + build := info.FileVersionLS >> 16 + revision := info.FileVersionLS & 0xffff + return fmt.Sprintf("%d.%d.%d.%d", major, minor, build, revision) +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/cpuaffinity.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/cpuaffinity.go new file mode 100644 index 000000000..a7d6281fe --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/cpuaffinity.go @@ -0,0 +1,21 @@ +package winapi + +// BOOL GetProcessGroupAffinity( +// [in] HANDLE hProcess, +// [in, out] PUSHORT GroupCount, +// [out] PUSHORT GroupArray +// ); +// +//sys GetProcessGroupAffinity(process windows.Handle, groupCount *uint16, groupArray *uint16) (err error) = kernel32.GetProcessGroupAffinity + +// BOOL GetProcessAffinityMask( +// [in] HANDLE hProcess, +// [out] PDWORD_PTR lpProcessAffinityMask, +// [out] PDWORD_PTR lpSystemAffinityMask +// ); +// +//sys GetProcessAffinityMask(process windows.Handle, processAffinityMask *uintptr, systemAffinityMask *uintptr) (err error) = kernel32.GetProcessAffinityMask + +// WORD GetActiveProcessorGroupCount(); +// +//sys GetActiveProcessorGroupCount() (amount uint16) = kernel32.GetActiveProcessorGroupCount diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go index 4c04dd3f8..290cbbf7a 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go @@ -98,6 +98,26 @@ type JOBOBJECT_BASIC_PROCESS_ID_LIST struct { ProcessIdList [1]uintptr } +// GROUP_AFFINITY specifies a processor group and an affinity mask for that group. +// Mirrors the Win32 _GROUP_AFFINITY structure. +// +// Processor group support was introduced in Windows 7 / Windows Server 2008 R2 +// to handle machines with more than 64 logical processors. The structure is used +// with SetInformationJobObject(JobObjectGroupInformationEx) and +// QueryInformationJobObject(JobObjectGroupInformationEx), both available since +// Windows 7 / Windows Server 2008 R2. +// +// For job object silos (containers), multi-processor-group affinity requires +// Windows Server 2022 (build 20348) or later. +// +// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/miniport/ns-miniport-_group_affinity +// https://learn.microsoft.com/en-us/windows/win32/procthread/processor-groups +type GROUP_AFFINITY struct { + Mask uintptr // KAFFINITY = ULONG_PTR: bitmask of processors in Group + Group uint16 // Processor group number + Reserved [3]uint16 // Must be zero +} + // AllPids returns all the process Ids in the job object. func (p *JOBOBJECT_BASIC_PROCESS_ID_LIST) AllPids() []uintptr { return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList:p.NumberOfProcessIdsInList] diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go index 28b28d1c6..4a32bcacd 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go @@ -63,6 +63,9 @@ var ( procCreatePseudoConsole = modkernel32.NewProc("CreatePseudoConsole") procCreateRemoteThread = modkernel32.NewProc("CreateRemoteThread") procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount") + procGetActiveProcessorGroupCount = modkernel32.NewProc("GetActiveProcessorGroupCount") + procGetProcessAffinityMask = modkernel32.NewProc("GetProcessAffinityMask") + procGetProcessGroupAffinity = modkernel32.NewProc("GetProcessGroupAffinity") procIsProcessInJob = modkernel32.NewProc("IsProcessInJob") procLocalAlloc = modkernel32.NewProc("LocalAlloc") procLocalFree = modkernel32.NewProc("LocalFree") @@ -270,6 +273,28 @@ func GetActiveProcessorCount(groupNumber uint16) (amount uint32) { return } +func GetActiveProcessorGroupCount() (amount uint16) { + r0, _, _ := syscall.SyscallN(procGetActiveProcessorGroupCount.Addr()) + amount = uint16(r0) + return +} + +func GetProcessAffinityMask(process windows.Handle, processAffinityMask *uintptr, systemAffinityMask *uintptr) (err error) { + r1, _, e1 := syscall.SyscallN(procGetProcessAffinityMask.Addr(), uintptr(process), uintptr(unsafe.Pointer(processAffinityMask)), uintptr(unsafe.Pointer(systemAffinityMask))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetProcessGroupAffinity(process windows.Handle, groupCount *uint16, groupArray *uint16) (err error) { + r1, _, e1 := syscall.SyscallN(procGetProcessGroupAffinity.Addr(), uintptr(process), uintptr(unsafe.Pointer(groupCount)), uintptr(unsafe.Pointer(groupArray))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *int32) (err error) { r1, _, e1 := syscall.SyscallN(procIsProcessInJob.Addr(), uintptr(procHandle), uintptr(jobHandle), uintptr(unsafe.Pointer(result))) if r1 == 0 { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md index 4f4258741..bc900567e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/CHANGELOG.md @@ -1,3 +1,11 @@ +# v1.7.18 (2026-08-14) + +* **Dependency Update**: Update to smithy-go v1.27.8. + +# v1.7.17 (2026-08-10) + +* **Dependency Update**: Update to smithy-go v1.27.7. + # v1.7.16 (2026-07-31.2) * **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go index e2fe8a2ec..57556a8eb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/go_module_metadata.go @@ -3,4 +3,4 @@ package eventstream // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.7.16" +const goModuleVersion = "1.7.18" diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go index 3e937fe3c..63863647d 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/fd/openat2_linux.go @@ -39,7 +39,9 @@ const scopedLookupMaxRetries = 128 // Openat2 is an [Fd]-based wrapper around unix.Openat2, but with some retry // logic in case of EAGAIN errors. -func Openat2(dir Fd, path string, how *unix.OpenHow) (*os.File, error) { +// +// NOTE: This is a variable so that the lookup tests can force openat2 to fail. +var Openat2 = func(dir Fd, path string, how *unix.OpenHow) (*os.File, error) { dirFd, fullPath := prepareAt(dir, path) // Make sure we always set O_CLOEXEC. how.Flags |= unix.O_CLOEXEC diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go new file mode 100644 index 000000000..ac93cb045 --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_go119.go @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BSD-3-Clause + +//go:build linux && go1.19 + +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gocompat + +import ( + "sync/atomic" +) + +// A Bool is an atomic boolean value. +// The zero value is false. +// +// Bool must not be copied after first use. +type Bool = atomic.Bool diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go new file mode 100644 index 000000000..21b5b29ad --- /dev/null +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat/gocompat_atomic_unsupported.go @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: BSD-3-Clause + +//go:build linux && !go1.19 + +// Copyright (C) 2024-2025 SUSE LLC. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gocompat + +import ( + "sync/atomic" +) + +// noCopy may be added to structs which must not be copied +// after the first use. +// +// See https://golang.org/issues/8005#issuecomment-190753527 +// for details. +// +// Note that it must not be embedded, due to the Lock and Unlock methods. +type noCopy struct{} + +// Lock is a no-op used by -copylocks checker from `go vet`. +func (*noCopy) Lock() {} + +// b32 returns a uint32 0 or 1 representing b. +func b32(b bool) uint32 { + if b { + return 1 + } + return 0 +} + +// A Bool is an atomic boolean value. +// The zero value is false. +// +// Bool must not be copied after first use. +type Bool struct { + _ noCopy + v uint32 +} + +// Load atomically loads and returns the value stored in x. +func (x *Bool) Load() bool { return atomic.LoadUint32(&x.v) != 0 } + +// Store atomically stores val into x. +func (x *Bool) Store(val bool) { atomic.StoreUint32(&x.v, b32(val)) } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go index 56480f0ce..ad233f140 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/lookup_linux.go @@ -193,8 +193,13 @@ func lookupInRoot(root fd.Fd, unsafePath string, partial bool) (Handle *os.File, // managed open, along with the remaining path components not opened. // Try to use openat2 if possible. - if linux.HasOpenat2() { - return lookupOpenat2(root, unsafePath, partial) + // + // NOTE: If openat2(2) works normally but fails for this lookup, it is + // probably not a good idea to fall-back to the O_PATH resolver. An + // attacker could find a bug in the O_PATH resolver and uncontionally + // falling back to the O_PATH resolver would form a downgrade attack. + if handle, remainingPath, err := lookupOpenat2(root, unsafePath, partial); err == nil || linux.HasOpenat2() { + return handle, remainingPath, err } // Get the "actual" root path from /proc/self/fd. This is necessary if the diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go index b80ecd089..9c5c268f6 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gopathrs/openat2_linux.go @@ -41,6 +41,7 @@ func openat2(dir fd.Fd, path string, how *unix.OpenHow) (*os.File, error) { if err != nil { return nil, err } + _ = file.Close() file = newFile } } diff --git a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go index 399609dc3..dc5f65cef 100644 --- a/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go +++ b/vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/linux/openat2_linux.go @@ -17,15 +17,27 @@ import ( "github.com/cyphar/filepath-securejoin/pathrs-lite/internal/gocompat" ) +// sawOpenat2Error stores whether we have seen an error from HasOpenat2. This +// is a one-way toggle, so as soon as we see an error we "lock" into that mode. +// We cannot use sync.OnceValue to store the success/fail state once because it +// is possible for the program we are running in to apply a seccomp-bpf filter +// and thus disable openat2 during execution. +var sawOpenat2Error gocompat.Bool + // HasOpenat2 returns whether openat2(2) is supported on the running kernel. -var HasOpenat2 = gocompat.SyncOnceValue(func() bool { +var HasOpenat2 = func() bool { + if sawOpenat2Error.Load() { + return false + } + fd, err := unix.Openat2(unix.AT_FDCWD, ".", &unix.OpenHow{ Flags: unix.O_PATH | unix.O_CLOEXEC, Resolve: unix.RESOLVE_NO_SYMLINKS | unix.RESOLVE_IN_ROOT, }) if err != nil { + sawOpenat2Error.Store(true) // doesn't matter if we race here return false } _ = unix.Close(fd) return true -}) +} diff --git a/vendor/github.com/felixge/httpsnoop/capture_metrics.go b/vendor/github.com/felixge/httpsnoop/capture_metrics.go index bec7b71b3..97f0a51de 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 000000000..b6549ba98 --- /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 101cedde6..000000000 --- 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 e0951df15..000000000 --- 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-logr/logr/context_noslog.go b/vendor/github.com/go-logr/logr/context_noslog.go index f012f9a18..0a3d1a125 100644 --- a/vendor/github.com/go-logr/logr/context_noslog.go +++ b/vendor/github.com/go-logr/logr/context_noslog.go @@ -1,5 +1,4 @@ //go:build !go1.21 -// +build !go1.21 /* Copyright 2019 The logr Authors. diff --git a/vendor/github.com/go-logr/logr/context_slog.go b/vendor/github.com/go-logr/logr/context_slog.go index 065ef0b82..c69eb01ba 100644 --- a/vendor/github.com/go-logr/logr/context_slog.go +++ b/vendor/github.com/go-logr/logr/context_slog.go @@ -1,5 +1,4 @@ //go:build go1.21 -// +build go1.21 /* Copyright 2019 The logr Authors. diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go index b22c57d71..7f4996e9e 100644 --- a/vendor/github.com/go-logr/logr/funcr/funcr.go +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -426,7 +426,7 @@ func (f Formatter) colon() byte { } func (f Formatter) pretty(value any) string { - return f.prettyWithFlags(value, 0, 0) + return f.prettyWithFlags(value, 0, 0, 0, nil) } const ( @@ -434,7 +434,13 @@ const ( ) // TODO: This is not fast. Most of the overhead goes here. -func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { +// value: The value to render +// flags: Bitmask of flags (see above) +// depth: The current depth of nested structs, slices, arrays, and maps +// ptrDepth: The current depth of including pointer dereferences +// ptrMap: A map of pointers already seen, to avoid infinite recursion (usually +// nil unless ptrDepth is large) +func (f Formatter) prettyWithFlags(value any, flags uint32, depth int, ptrDepth int, ptrMap map[uintptr]bool) string { if depth > f.opts.MaxLogDepth { return `""` } @@ -504,7 +510,7 @@ func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { // arbitrary keys might need escaping buf.WriteString(prettyString(k)) buf.WriteByte(f.colon()) - buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1)) + buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1, ptrDepth+1, ptrMap)) } if flags&flagRawStruct == 0 { buf.WriteByte('}') @@ -576,7 +582,7 @@ func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { } printComma = true // if we got here, we are rendering a field if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" { - buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1)) + buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1, ptrDepth+1, ptrMap)) continue } if name == "" { @@ -585,7 +591,7 @@ func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { // field names can't contain characters which need escaping buf.WriteString(f.quoted(name, false)) buf.WriteByte(f.colon()) - buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1)) + buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1, ptrDepth+1, ptrMap)) } if flags&flagRawStruct == 0 { buf.WriteByte('}') @@ -612,7 +618,7 @@ func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { buf.WriteByte(f.comma()) } e := v.Index(i) - buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1)) + buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1, ptrDepth+1, ptrMap)) } buf.WriteByte(']') return buf.String() @@ -637,7 +643,8 @@ func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { keystr = prettyString(keystr) } else { // prettyWithFlags will produce already-escaped values - keystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1) + // key depth is unrelated to overall depth + keystr = f.prettyWithFlags(it.Key().Interface(), 0, 0, ptrDepth, ptrMap) if t.Key().Kind() != reflect.String { // JSON only does string keys. Unlike Go's standard JSON, we'll // convert just about anything to a string. @@ -646,16 +653,34 @@ func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { } buf.WriteString(keystr) buf.WriteByte(f.colon()) - buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1)) + buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1, ptrDepth+1, ptrMap)) i++ } buf.WriteByte('}') return buf.String() - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: if v.IsNil() { return "null" } - return f.prettyWithFlags(v.Elem().Interface(), 0, depth) + // Special case: recursive pointers. For normal use we do not want to + // count pointer dereferences as depth, but if we see the same pointer + // again we have a recursion and need to stop. After a large number of + // pointer dereferences we will start tracking pointers to avoid the + // perf hit of doing it in the normal path. + // + // This should not happen accidentally (e.g. json decoding should never + // do this) but we can handle it gracefully. + if ptrMap != nil && ptrMap[uintptr(v.Pointer())] { + depth = f.opts.MaxLogDepth + 1 // force a depth error + } + const maxDepthFactor = 4 // arbitrary, but we want it large enough to not false-alert + if ptrDepth > f.opts.MaxLogDepth*maxDepthFactor && ptrMap == nil { + ptrMap = map[uintptr]bool{} + } + if ptrMap != nil { + ptrMap[(uintptr)(v.Pointer())] = true + } + return f.prettyWithFlags(v.Elem().Interface(), 0, depth, ptrDepth+1, ptrMap) } return fmt.Sprintf(`""`, t.Kind().String()) } @@ -697,7 +722,7 @@ func isEmpty(v reflect.Value) bool { return v.Float() == 0 case reflect.Complex64, reflect.Complex128: return v.Complex() == 0 - case reflect.Interface, reflect.Ptr: + case reflect.Interface, reflect.Pointer: return v.IsNil() } return false diff --git a/vendor/github.com/go-logr/logr/funcr/slogsink.go b/vendor/github.com/go-logr/logr/funcr/slogsink.go index 7bd84761e..8b519c91e 100644 --- a/vendor/github.com/go-logr/logr/funcr/slogsink.go +++ b/vendor/github.com/go-logr/logr/funcr/slogsink.go @@ -1,5 +1,4 @@ //go:build go1.21 -// +build go1.21 /* Copyright 2023 The logr Authors. @@ -33,7 +32,7 @@ const extraSlogSinkDepth = 3 // 2 for slog, 1 for SlogSink func (l fnlogger) Handle(_ context.Context, record slog.Record) error { kvList := make([]any, 0, 2*record.NumAttrs()) record.Attrs(func(attr slog.Attr) bool { - kvList = attrToKVs(attr, kvList) + kvList = attrToKVs(attr, kvList, l.opts.MaxLogDepth) return true }) @@ -49,7 +48,7 @@ func (l fnlogger) Handle(_ context.Context, record slog.Record) error { func (l fnlogger) WithAttrs(attrs []slog.Attr) logr.SlogSink { kvList := make([]any, 0, 2*len(attrs)) for _, attr := range attrs { - kvList = attrToKVs(attr, kvList) + kvList = attrToKVs(attr, kvList, l.opts.MaxLogDepth) } l.AddValues(kvList) return &l @@ -61,14 +60,25 @@ func (l fnlogger) WithGroup(name string) logr.SlogSink { } // attrToKVs appends a slog.Attr to a logr-style kvList. It handle slog Groups -// and other details of slog. -func attrToKVs(attr slog.Attr, kvList []any) []any { +// and other details of slog. maxDepth bounds recursion into nested groups so a +// deeply-nested slog.Group cannot exhaust the stack; it is decremented per group +// level and starts at the Formatter's MaxLogDepth (past which the formatter would +// truncate the rendering anyway). +func attrToKVs(attr slog.Attr, kvList []any, maxDepth int) []any { attrVal := attr.Value.Resolve() if attrVal.Kind() == slog.KindGroup { + if maxDepth <= 0 { + // Nesting is too deep to build without risking a stack overflow. + // Stop here; the formatter truncates below MaxLogDepth regardless. + if attr.Key != "" { + kvList = append(kvList, attr.Key, "") + } + return kvList + } groupVal := attrVal.Group() grpKVs := make([]any, 0, 2*len(groupVal)) for _, attr := range groupVal { - grpKVs = attrToKVs(attr, grpKVs) + grpKVs = attrToKVs(attr, grpKVs, maxDepth-1) } if attr.Key == "" { // slog says we have to inline these diff --git a/vendor/github.com/go-logr/logr/sloghandler.go b/vendor/github.com/go-logr/logr/sloghandler.go index 82d1ba494..befaf5510 100644 --- a/vendor/github.com/go-logr/logr/sloghandler.go +++ b/vendor/github.com/go-logr/logr/sloghandler.go @@ -1,5 +1,4 @@ //go:build go1.21 -// +build go1.21 /* Copyright 2023 The logr Authors. diff --git a/vendor/github.com/go-logr/logr/slogr.go b/vendor/github.com/go-logr/logr/slogr.go index 28a83d024..bfe80eb8d 100644 --- a/vendor/github.com/go-logr/logr/slogr.go +++ b/vendor/github.com/go-logr/logr/slogr.go @@ -1,5 +1,4 @@ //go:build go1.21 -// +build go1.21 /* Copyright 2023 The logr Authors. diff --git a/vendor/github.com/go-logr/logr/slogsink.go b/vendor/github.com/go-logr/logr/slogsink.go index 4060fcbc2..ab76ea99f 100644 --- a/vendor/github.com/go-logr/logr/slogsink.go +++ b/vendor/github.com/go-logr/logr/slogsink.go @@ -1,5 +1,4 @@ //go:build go1.21 -// +build go1.21 /* Copyright 2023 The logr Authors. diff --git a/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml b/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml index 3e19ea710..3208f721b 100644 --- a/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml +++ b/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml @@ -74,39 +74,43 @@ universal_binaries: name_template: jsontoml archives: - id: jsontoml - format: tar.xz - builds: + formats: + - tar.xz + ids: - jsontoml files: - none* name_template: "{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}" - id: tomljson - format: tar.xz - builds: + formats: + - tar.xz + ids: - tomljson files: - none* name_template: "{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}" - id: tomll - format: tar.xz - builds: + formats: + - tar.xz + ids: - tomll files: - none* name_template: "{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}" -dockers: +dockers_v2: - id: tools - goos: linux - goarch: amd64 ids: - jsontoml - tomljson - tomll - image_templates: - - "ghcr.io/pelletier/go-toml:latest" - - "ghcr.io/pelletier/go-toml:{{ .Tag }}" - - "ghcr.io/pelletier/go-toml:v{{ .Major }}" - skip_push: false + images: + - "ghcr.io/pelletier/go-toml" + tags: + - "latest" + - "{{ .Tag }}" + - "v{{ .Major }}" + platforms: + - linux/amd64 checksum: name_template: 'sha256sums.txt' snapshot: diff --git a/vendor/github.com/pelletier/go-toml/v2/AGENTS.md b/vendor/github.com/pelletier/go-toml/v2/AGENTS.md index dafe44d76..f495afd87 100644 --- a/vendor/github.com/pelletier/go-toml/v2/AGENTS.md +++ b/vendor/github.com/pelletier/go-toml/v2/AGENTS.md @@ -53,6 +53,14 @@ go-toml is a TOML library for Go. The goal is to provide an easy-to-use and effi - Commit messages must explain **why** the change is needed - Keep messages clear and informative even if details are in the PR description +### Capabilities + +go-toml tracks system-level capabilities using [capslock](https://github.com/google/capslock). The baseline is in `capability_baseline.txt` and CI enforces that it does not grow. + +- **Do not introduce new capabilities.** PRs that increase the capability set (e.g., adding network access, subprocess execution, syscalls) are unlikely to be accepted. +- If a change causes the capabilities check to fail, do not update the baseline to make it pass. Instead, rethink the approach to avoid requiring new capabilities. +- To check locally: `./caps.sh check` (requires `capslock` installed via `go install github.com/google/capslock/cmd/capslock@latest`) + ## Pull Request Checklist Before submitting: @@ -61,4 +69,5 @@ Before submitting: 2. No backward-incompatible changes (unless discussed) 3. Relevant documentation added/updated 4. No performance regression (verify with benchmarks) -5. Title is clear and understandable for changelog +5. Capabilities are not increasing (`./caps.sh check`) +6. Title is clear and understandable for changelog diff --git a/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md b/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md index 28b88ec33..65a3ff494 100644 --- a/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md +++ b/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md @@ -180,6 +180,25 @@ description. Pull requests that lower performance will receive more scrutiny. [benchstat]: https://pkg.go.dev/golang.org/x/perf/cmd/benchstat +### Capabilities + +We use [capslock](https://github.com/google/capslock) to track what +system-level capabilities (file access, network, syscalls, etc.) each package +requires. The current baseline is in `capability_baseline.txt`. CI will fail if +a change introduces a new capability. + +**Pull requests that increase the set of capabilities are unlikely to be +accepted.** go-toml is a parsing library and should not need network access, +subprocess execution, or other capabilities beyond what it already uses. + +If you believe a new capability is genuinely needed, discuss it in an issue +first. To update the baseline after approval: + +```bash +go install github.com/google/capslock/cmd/capslock@latest +./caps.sh generate +``` + ### Style Try to look around and follow the same format and structure as the rest of the diff --git a/vendor/github.com/pelletier/go-toml/v2/Dockerfile b/vendor/github.com/pelletier/go-toml/v2/Dockerfile index b9e933237..ebd9babac 100644 --- a/vendor/github.com/pelletier/go-toml/v2/Dockerfile +++ b/vendor/github.com/pelletier/go-toml/v2/Dockerfile @@ -1,5 +1,6 @@ FROM scratch ENV PATH "$PATH:/bin" -COPY tomll /bin/tomll -COPY tomljson /bin/tomljson -COPY jsontoml /bin/jsontoml +ARG TARGETPLATFORM +COPY $TARGETPLATFORM/tomll /bin/tomll +COPY $TARGETPLATFORM/tomljson /bin/tomljson +COPY $TARGETPLATFORM/jsontoml /bin/jsontoml diff --git a/vendor/github.com/pelletier/go-toml/v2/README.md b/vendor/github.com/pelletier/go-toml/v2/README.md index 14e656449..067ba3fd7 100644 --- a/vendor/github.com/pelletier/go-toml/v2/README.md +++ b/vendor/github.com/pelletier/go-toml/v2/README.md @@ -2,7 +2,7 @@ Go library for the [TOML](https://toml.io/en/) format. -This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0). +This library supports [TOML v1.1.0](https://toml.io/en/v1.1.0). [🐞 Bug Reports](https://github.com/pelletier/go-toml/issues) @@ -28,6 +28,11 @@ import "github.com/pelletier/go-toml/v2" As much as possible, this library is designed to behave similarly as the standard library's `encoding/json`. +When encoding structs, fields tagged with `omitempty` are omitted if they are +empty. For `time.Time`, the zero value is considered empty, so timestamps such +as `created_at` or `updated_at` are not written unless you remove `omitempty` +from the struct tag or use a pointer type (`*time.Time`). + ### Performance While go-toml favors usability, it is written with performance in mind. Most @@ -65,7 +70,7 @@ this use-case, go-toml provides [`LocalDate`][tld], [`LocalTime`][tlt], and making them convenient yet unambiguous structures for their respective TOML representation. -[ldt]: https://toml.io/en/v1.0.0#local-date-time +[ldt]: https://toml.io/en/v1.1.0#local-date-time [tld]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#LocalDate [tlt]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#LocalTime [tldt]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#LocalDateTime @@ -237,12 +242,12 @@ Execution time speedup compared to other Go TOML libraries: Benchmarkgo-toml v1BurntSushi/toml - Marshal/HugoFrontMatter-22.1x2.0x - Marshal/ReferenceFile/map-22.0x2.0x - Marshal/ReferenceFile/struct-22.3x2.5x - Unmarshal/HugoFrontMatter-23.3x2.8x - Unmarshal/ReferenceFile/map-22.9x3.0x - Unmarshal/ReferenceFile/struct-24.8x5.0x + Marshal/HugoFrontMatter-22.3x2.4x + Marshal/ReferenceFile/map-22.2x2.6x + Marshal/ReferenceFile/struct-24.9x5.0x + Unmarshal/HugoFrontMatter-27.8x5.9x + Unmarshal/ReferenceFile/map-26.8x6.4x + Unmarshal/ReferenceFile/struct-26.8x6.3x
See more @@ -255,17 +260,17 @@ provided for completeness.

Benchmarkgo-toml v1BurntSushi/toml - Marshal/SimpleDocument/map-22.0x2.9x - Marshal/SimpleDocument/struct-22.5x3.6x - Unmarshal/SimpleDocument/map-24.2x3.4x - Unmarshal/SimpleDocument/struct-25.9x4.4x - UnmarshalDataset/example-23.2x2.9x - UnmarshalDataset/code-22.4x2.8x - UnmarshalDataset/twitter-22.7x2.5x - UnmarshalDataset/citm_catalog-22.3x2.3x - UnmarshalDataset/canada-21.9x1.5x - UnmarshalDataset/config-25.4x3.0x - geomean2.9x2.8x + Marshal/SimpleDocument/map-22.1x3.1x + Marshal/SimpleDocument/struct-23.4x4.8x + Unmarshal/SimpleDocument/map-210.1x7.0x + Unmarshal/SimpleDocument/struct-212.4x8.0x + UnmarshalDataset/example-28.2x6.9x + UnmarshalDataset/code-27.5x8.3x + UnmarshalDataset/twitter-29.0x7.6x + UnmarshalDataset/citm_catalog-25.0x4.5x + UnmarshalDataset/canada-26.4x4.7x + UnmarshalDataset/config-210.2x6.1x + geomean5.8x5.3x

This table can be generated with ./ci.sh benchmark -a -html.

@@ -309,304 +314,6 @@ Multiple versions are available on [ghcr.io][docker]. [docker]: https://github.com/pelletier/go-toml/pkgs/container/go-toml -## Migrating from v1 - -This section describes the differences between v1 and v2, with some pointers on -how to get the original behavior when possible. - -### Decoding / Unmarshal - -#### Automatic field name guessing - -When unmarshaling to a struct, if a key in the TOML document does not exactly -match the name of a struct field or any of the `toml`-tagged field, v1 tries -multiple variations of the key ([code][v1-keys]). - -V2 instead does a case-insensitive matching, like `encoding/json`. - -This could impact you if you are relying on casing to differentiate two fields, -and one of them is a not using the `toml` struct tag. The recommended solution -is to be specific about tag names for those fields using the `toml` struct tag. - -[v1-keys]: https://github.com/pelletier/go-toml/blob/a2e52561804c6cd9392ebf0048ca64fe4af67a43/marshal.go#L775-L781 - -#### Ignore preexisting value in interface - -When decoding into a non-nil `interface{}`, go-toml v1 uses the type of the -element in the interface to decode the object. For example: - -```go -type inner struct { - B interface{} -} -type doc struct { - A interface{} -} - -d := doc{ - A: inner{ - B: "Before", - }, -} - -data := ` -[A] -B = "After" -` - -toml.Unmarshal([]byte(data), &d) -fmt.Printf("toml v1: %#v\n", d) - -// toml v1: main.doc{A:main.inner{B:"After"}} -``` - -In this case, field `A` is of type `interface{}`, containing a `inner` struct. -V1 sees that type and uses it when decoding the object. - -When decoding an object into an `interface{}`, V2 instead disregards whatever -value the `interface{}` may contain and replaces it with a -`map[string]interface{}`. With the same data structure as above, here is what -the result looks like: - -```go -toml.Unmarshal([]byte(data), &d) -fmt.Printf("toml v2: %#v\n", d) - -// toml v2: main.doc{A:map[string]interface {}{"B":"After"}} -``` - -This is to match `encoding/json`'s behavior. There is no way to make the v2 -decoder behave like v1. - -#### Values out of array bounds ignored - -When decoding into an array, v1 returns an error when the number of elements -contained in the doc is superior to the capacity of the array. For example: - -```go -type doc struct { - A [2]string -} -d := doc{} -err := toml.Unmarshal([]byte(`A = ["one", "two", "many"]`), &d) -fmt.Println(err) - -// (1, 1): unmarshal: TOML array length (3) exceeds destination array length (2) -``` - -In the same situation, v2 ignores the last value: - -```go -err := toml.Unmarshal([]byte(`A = ["one", "two", "many"]`), &d) -fmt.Println("err:", err, "d:", d) -// err: d: {[one two]} -``` - -This is to match `encoding/json`'s behavior. There is no way to make the v2 -decoder behave like v1. - -#### Support for `toml.Unmarshaler` has been dropped - -This method was not widely used, poorly defined, and added a lot of complexity. -A similar effect can be achieved by implementing the `encoding.TextUnmarshaler` -interface and use strings. - -#### Support for `default` struct tag has been dropped - -This feature adds complexity and a poorly defined API for an effect that can be -accomplished outside of the library. - -It does not seem like other format parsers in Go support that feature (the -project referenced in the original ticket #202 has not been updated since 2017). -Given that go-toml v2 should not touch values not in the document, the same -effect can be achieved by pre-filling the struct with defaults (libraries like -[go-defaults][go-defaults] can help). Also, string representation is not well -defined for all types: it creates issues like #278. - -The recommended replacement is pre-filling the struct before unmarshaling. - -[go-defaults]: https://github.com/mcuadros/go-defaults - -#### `toml.Tree` replacement - -This structure was the initial attempt at providing a document model for -go-toml. It allows manipulating the structure of any document, encoding and -decoding from their TOML representation. While a more robust feature was -initially planned in go-toml v2, this has been ultimately [removed from -scope][nodoc] of this library, with no plan to add it back at the moment. The -closest equivalent at the moment would be to unmarshal into an `interface{}` and -use type assertions and/or reflection to manipulate the arbitrary -structure. However this would fall short of providing all of the TOML features -such as adding comments and be specific about whitespace. - - -#### `toml.Position` are not retrievable anymore - -The API for retrieving the position (line, column) of a specific TOML element do -not exist anymore. This was done to minimize the amount of concepts introduced -by the library (query path), and avoid the performance hit related to storing -positions in the absence of a document model, for a feature that seemed to have -little use. Errors however have gained more detailed position -information. Position retrieval seems better fitted for a document model, which -has been [removed from the scope][nodoc] of go-toml v2 at the moment. - -### Encoding / Marshal - -#### Default struct fields order - -V1 emits struct fields order alphabetically by default. V2 struct fields are -emitted in order they are defined. For example: - -```go -type S struct { - B string - A string -} - -data := S{ - B: "B", - A: "A", -} - -b, _ := tomlv1.Marshal(data) -fmt.Println("v1:\n" + string(b)) - -b, _ = tomlv2.Marshal(data) -fmt.Println("v2:\n" + string(b)) - -// Output: -// v1: -// A = "A" -// B = "B" - -// v2: -// B = 'B' -// A = 'A' -``` - -There is no way to make v2 encoder behave like v1. A workaround could be to -manually sort the fields alphabetically in the struct definition, or generate -struct types using `reflect.StructOf`. - -#### No indentation by default - -V1 automatically indents content of tables by default. V2 does not. However the -same behavior can be obtained using [`Encoder.SetIndentTables`][sit]. For example: - -```go -data := map[string]interface{}{ - "table": map[string]string{ - "key": "value", - }, -} - -b, _ := tomlv1.Marshal(data) -fmt.Println("v1:\n" + string(b)) - -b, _ = tomlv2.Marshal(data) -fmt.Println("v2:\n" + string(b)) - -buf := bytes.Buffer{} -enc := tomlv2.NewEncoder(&buf) -enc.SetIndentTables(true) -enc.Encode(data) -fmt.Println("v2 Encoder:\n" + string(buf.Bytes())) - -// Output: -// v1: -// -// [table] -// key = "value" -// -// v2: -// [table] -// key = 'value' -// -// -// v2 Encoder: -// [table] -// key = 'value' -``` - -[sit]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#Encoder.SetIndentTables - -#### Keys and strings are single quoted - -V1 always uses double quotes (`"`) around strings and keys that cannot be -represented bare (unquoted). V2 uses single quotes instead by default (`'`), -unless a character cannot be represented, then falls back to double quotes. As a -result of this change, `Encoder.QuoteMapKeys` has been removed, as it is not -useful anymore. - -There is no way to make v2 encoder behave like v1. - -#### `TextMarshaler` emits as a string, not TOML - -Types that implement [`encoding.TextMarshaler`][tm] can emit arbitrary TOML in -v1. The encoder would append the result to the output directly. In v2 the result -is wrapped in a string. As a result, this interface cannot be implemented by the -root object. - -There is no way to make v2 encoder behave like v1. - -[tm]: https://golang.org/pkg/encoding/#TextMarshaler - -#### `Encoder.CompactComments` has been removed - -Emitting compact comments is now the default behavior of go-toml. This option -is not necessary anymore. - -#### Struct tags have been merged - -V1 used to provide multiple struct tags: `comment`, `commented`, `multiline`, -`toml`, and `omitempty`. To behave more like the standard library, v2 has merged -`toml`, `multiline`, `commented`, and `omitempty`. For example: - -```go -type doc struct { - // v1 - F string `toml:"field" multiline:"true" omitempty:"true" commented:"true"` - // v2 - F string `toml:"field,multiline,omitempty,commented"` -} -``` - -Has a result, the `Encoder.SetTag*` methods have been removed, as there is just -one tag now. - -#### `Encoder.ArraysWithOneElementPerLine` has been renamed - -The new name is `Encoder.SetArraysMultiline`. The behavior should be the same. - -#### `Encoder.Indentation` has been renamed - -The new name is `Encoder.SetIndentSymbol`. The behavior should be the same. - - -#### Embedded structs behave like stdlib - -V1 defaults to merging embedded struct fields into the embedding struct. This -behavior was unexpected because it does not follow the standard library. To -avoid breaking backward compatibility, the `Encoder.PromoteAnonymous` method was -added to make the encoder behave correctly. Given backward compatibility is not -a problem anymore, v2 does the right thing by default: it follows the behavior -of `encoding/json`. `Encoder.PromoteAnonymous` has been removed. - -[nodoc]: https://github.com/pelletier/go-toml/discussions/506#discussioncomment-1526038 - -### `query` - -go-toml v1 provided the [`go-toml/query`][query] package. It allowed to run -JSONPath-style queries on TOML files. This feature is not available in v2. For a -replacement, check out [dasel][dasel]. - -This package has been removed because it was essentially not supported anymore -(last commit May 2020), increased the complexity of the code base, and more -complete solutions exist out there. - -[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query -[dasel]: https://github.com/TomWright/dasel - ## Versioning Expect for parts explicitly marked otherwise, go-toml follows [Semantic diff --git a/vendor/github.com/pelletier/go-toml/v2/capability_baseline.txt b/vendor/github.com/pelletier/go-toml/v2/capability_baseline.txt new file mode 100644 index 000000000..c556456c9 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/v2/capability_baseline.txt @@ -0,0 +1 @@ +github.com/pelletier/go-toml/v2: CAPABILITY_REFLECT, CAPABILITY_UNANALYZED, CAPABILITY_UNSAFE_POINTER diff --git a/vendor/github.com/pelletier/go-toml/v2/caps.sh b/vendor/github.com/pelletier/go-toml/v2/caps.sh new file mode 100644 index 000000000..31fec2b96 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/v2/caps.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# Generates or checks the capability baseline for go-toml. +# +# Usage: +# ./caps.sh generate # regenerate capability_baseline.txt +# ./caps.sh check # check that capabilities haven't grown +# +# Requires: go, capslock (go install github.com/google/capslock/cmd/capslock@latest) + +set -euo pipefail + +BASELINE="capability_baseline.txt" +CAPSLOCK="${CAPSLOCK:-capslock}" + +# Capabilities that must never appear in any package. +FORBIDDEN_CAPS=( + CAPABILITY_NETWORK + CAPABILITY_CGO + CAPABILITY_EXEC +) + +capslock_to_baseline() { + "$CAPSLOCK" -packages=. -output=package -granularity=package \ + | jq -r 'to_entries | sort_by(.key) | .[] | .key + ": " + (.value | sort | join(", "))' +} + +generate() { + capslock_to_baseline > "$BASELINE" + echo "Wrote $BASELINE" +} + +check() { + if [ ! -f "$BASELINE" ]; then + echo "ERROR: $BASELINE not found. Run '$0 generate' first." + exit 1 + fi + + current=$(mktemp) + trap 'rm -f "$current"' EXIT + + capslock_to_baseline > "$current" + + failed=0 + + # Check for forbidden capabilities in current output. + for cap in "${FORBIDDEN_CAPS[@]}"; do + if grep -q "$cap" "$current"; then + echo "FORBIDDEN capability found: $cap" + grep "$cap" "$current" + failed=1 + fi + done + + # Extract all unique capability names from baseline and current. + baseline_caps=$(grep -oE 'CAPABILITY_[A-Z_]+' "$BASELINE" | sort -u) + current_caps=$(grep -oE 'CAPABILITY_[A-Z_]+' "$current" | sort -u) + + # Check for new capability names not in the baseline. + new_caps=$(comm -13 <(echo "$baseline_caps") <(echo "$current_caps")) + if [ -n "$new_caps" ]; then + echo "NEW capabilities detected (not in baseline):" + echo "$new_caps" + failed=1 + fi + + # Check for new per-package capabilities (a package gained a capability it didn't have before). + while IFS=': ' read -r pkg caps; do + baseline_pkg_caps=$(grep "^${pkg}:" "$BASELINE" 2>/dev/null | sed 's/^[^:]*: //' || true) + if [ -z "$baseline_pkg_caps" ]; then + echo "NEW package with capabilities: $pkg: $caps" + failed=1 + continue + fi + # Check each capability in current for this package + for cap in $(echo "$caps" | tr ', ' '\n' | grep -v '^$'); do + if ! echo "$baseline_pkg_caps" | grep -q "$cap"; then + echo "NEW capability for $pkg: $cap" + failed=1 + fi + done + done < "$current" + + if [ "$failed" -eq 1 ]; then + echo "" + echo "FAILED: capabilities have grown." + echo "If this is intentional, run '$0 generate' and commit the updated $BASELINE." + exit 1 + fi + + echo "OK: no new capabilities detected." +} + +case "${1:-}" in + generate) generate ;; + check) check ;; + *) + echo "Usage: $0 {generate|check}" + exit 1 + ;; +esac diff --git a/vendor/github.com/pelletier/go-toml/v2/ci.sh b/vendor/github.com/pelletier/go-toml/v2/ci.sh index 30c23d1a1..6b9723bf4 100644 --- a/vendor/github.com/pelletier/go-toml/v2/ci.sh +++ b/vendor/github.com/pelletier/go-toml/v2/ci.sh @@ -146,13 +146,17 @@ bench() { pushd "$dir" + tags="" if [ "${replace}" != "" ]; then find ./benchmark/ -iname '*.go' -exec sed -i -E "s|github.com/pelletier/go-toml/v2\"|${replace}\"|g" {} \; go get "${replace}" + # The realworld benchmarks use v2-only API and cannot compile against + # the other libraries; exclude them from cross-library comparisons. + tags="-tags cross_library_benchmark" fi export GOMAXPROCS=2 - go test '-bench=^Benchmark(Un)?[mM]arshal' -count=10 -run=Nothing ./... | tee "${out}" + go test ${tags} '-bench=^Benchmark(Un)?[mM]arshal' -count=10 -run=Nothing ./... | tee "${out}" popd if [ "${branch}" != "HEAD" ]; then diff --git a/vendor/github.com/pelletier/go-toml/v2/decode.go b/vendor/github.com/pelletier/go-toml/v2/decode.go index f3f14eff1..46de2fb44 100644 --- a/vendor/github.com/pelletier/go-toml/v2/decode.go +++ b/vendor/github.com/pelletier/go-toml/v2/decode.go @@ -1,6 +1,7 @@ package toml import ( + "bytes" "fmt" "math" "strconv" @@ -22,15 +23,259 @@ func parseInteger(b []byte) (int64, error) { panic(fmt.Errorf("invalid base '%c', should have been checked by scanIntOrFloat", b[1])) } } - return parseIntDec(b) } +func parseIntHex(b []byte) (int64, error) { + var v uint64 + for _, c := range b[2:] { + if c == '_' { + continue + } + var d byte + switch { + case c >= '0' && c <= '9': + d = c - '0' + case c >= 'a' && c <= 'f': + d = c - 'a' + 10 + case c >= 'A' && c <= 'F': + d = c - 'A' + 10 + } + if v > math.MaxInt64>>4 { + return 0, unstable.NewParserError(b, "hexadecimal number is too large to fit in a 64-bit signed integer") + } + v = v<<4 | uint64(d) + } + return int64(v), nil +} + +func parseIntOct(b []byte) (int64, error) { + var v uint64 + for _, c := range b[2:] { + if c == '_' { + continue + } + if v > math.MaxInt64>>3 { + return 0, unstable.NewParserError(b, "octal number is too large to fit in a 64-bit signed integer") + } + v = v<<3 | uint64(c-'0') + } + return int64(v), nil +} + +func parseIntBin(b []byte) (int64, error) { + var v uint64 + for _, c := range b[2:] { + if c == '_' { + continue + } + if v > math.MaxInt64>>1 { + return 0, unstable.NewParserError(b, "binary number is too large to fit in a 64-bit signed integer") + } + v = v<<1 | uint64(c-'0') + } + return int64(v), nil +} + +func parseIntDec(b []byte) (int64, error) { + i := 0 + neg := false + switch b[0] { + case '-': + neg = true + i++ + case '+': + i++ + } + + var limit uint64 = math.MaxInt64 + if neg { + limit = math.MaxInt64 + 1 + } + + var v uint64 + for ; i < len(b); i++ { + c := b[i] + if c == '_' { + continue + } + if v > limit/10 { + return 0, unstable.NewParserError(b, "decimal number is too large to fit in a 64-bit signed integer") + } + v = v*10 + uint64(c-'0') + if v > limit { + return 0, unstable.NewParserError(b, "decimal number is too large to fit in a 64-bit signed integer") + } + } + if neg { + return -int64(v), nil //nolint:gosec // v <= MaxInt64+1, the conversion wraps to the intended negative value + } + return int64(v), nil //nolint:gosec // v <= MaxInt64 +} + +func parseFloat(b []byte) (float64, error) { + i := 0 + if len(b) > 0 && (b[0] == '+' || b[0] == '-') { + i = 1 + } + if len(b) == i+3 { + switch b[i] { + case 'i': + // inf + if b[0] == '-' { + return math.Inf(-1), nil + } + return math.Inf(1), nil + case 'n': + // nan + return math.NaN(), nil + } + } + + // Fast path: a plain decimal whose significand fits in 53 bits and whose + // base-10 exponent is within [-22, 22] is parsed exactly with a single + // rounding (Clinger's method) straight from the bytes, with no string + // allocation and no full strconv parse. This is the common shape for + // numeric data (e.g. coordinate lists). Anything outside those bounds, or + // with underscores, falls through to strconv, which is the reference. + if f, ok := fastParseFloat(b); ok { + return f, nil + } + + // strconv.ParseFloat is the reference implementation for parsing + // floating point numbers. The position of underscores has already been + // validated by the parser; strip them so that they do not interfere with + // Go's own underscore rules. + cleaned := b + if bytes.IndexByte(b, '_') >= 0 { + cleaned = make([]byte, 0, len(b)) + for _, c := range b { + if c != '_' { + cleaned = append(cleaned, c) + } + } + } + + f, err := strconv.ParseFloat(string(cleaned), 64) + if err != nil { + return 0, unstable.NewParserError(b, "unable to parse float: %s", err) + } + return f, nil +} + +// float64pow10 holds the powers of ten that are exactly representable as a +// float64 (10^0 .. 10^22). +var float64pow10 = [...]float64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, +} + +// fastParseFloat parses b as a float64 using Clinger's exact method and reports +// whether it applied. It accepts only plain decimal numbers (optional sign, +// digits, one optional '.', optional 'e'/'E' exponent) whose significand fits +// in 53 bits and whose effective base-10 exponent is within [-22, 22]; under +// those conditions float64(significand) * 10^exp (or / 10^-exp) is the exact, +// correctly-rounded result, identical to strconv.ParseFloat. It returns +// ok=false (deferring to strconv) for underscores, hexadecimal floats, large +// significands or exponents, and any other shape. +func fastParseFloat(b []byte) (float64, bool) { + i := 0 + neg := false + if i < len(b) && (b[i] == '+' || b[i] == '-') { + neg = b[i] == '-' + i++ + } + + var mantissa uint64 + digits := 0 + fracDigits := 0 + sawDot := false + sawDigit := false + for ; i < len(b); i++ { + c := b[i] + switch { + case c >= '0' && c <= '9': + if digits >= 19 { + // Too many significant digits to accumulate without risking a + // uint64 overflow (and well past the 53-bit exact range). + return 0, false + } + mantissa = mantissa*10 + uint64(c-'0') + digits++ + if sawDot { + fracDigits++ + } + sawDigit = true + case c == '.': + if sawDot { + return 0, false + } + sawDot = true + default: + goto exponent + } + } +exponent: + if !sawDigit { + return 0, false + } + exp := -fracDigits + if i < len(b) && (b[i] == 'e' || b[i] == 'E') { + i++ + esign := 1 + if i < len(b) && (b[i] == '+' || b[i] == '-') { + if b[i] == '-' { + esign = -1 + } + i++ + } + if i >= len(b) { + return 0, false + } + eval := 0 + for ; i < len(b); i++ { + c := b[i] + if c < '0' || c > '9' { + return 0, false + } + eval = eval*10 + int(c-'0') + if eval > 1000 { + return 0, false + } + } + exp += esign * eval + } + if i != len(b) { + // Trailing bytes (an underscore, a hexadecimal marker, ...). + return 0, false + } + if mantissa > 1<<53 { + return 0, false + } + + f := float64(mantissa) + switch { + case exp == 0: + case exp > 0 && exp <= 22: + f *= float64pow10[exp] + case exp < 0 && exp >= -22: + f /= float64pow10[-exp] + default: + return 0, false + } + if neg { + f = -f + } + return f, true +} + +func isDecimalDigit(c byte) bool { + return c >= '0' && c <= '9' +} + +// parseLocalDate parses a date of the exact form YYYY-MM-DD and validates +// its components. func parseLocalDate(b []byte) (LocalDate, error) { - // full-date = date-fullyear "-" date-month "-" date-mday - // date-fullyear = 4DIGIT - // date-month = 2DIGIT ; 01-12 - // date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year var date LocalDate if len(b) != 10 || b[4] != '-' || b[7] != '-' { @@ -38,49 +283,184 @@ func parseLocalDate(b []byte) (LocalDate, error) { } var err error - date.Year, err = parseDecimalDigits(b[0:4]) if err != nil { - return LocalDate{}, err + return date, err } - date.Month, err = parseDecimalDigits(b[5:7]) if err != nil { - return LocalDate{}, err + return date, err } - date.Day, err = parseDecimalDigits(b[8:10]) if err != nil { - return LocalDate{}, err + return date, err } - if !isValidDate(date.Year, date.Month, date.Day) { - return LocalDate{}, unstable.NewParserError(b, "impossible date") + if date.Month < 1 || date.Month > 12 { + return date, unstable.NewParserError(b[5:7], "impossible date") + } + maxDay := daysIn(date.Month, date.Year) + if date.Day < 1 || date.Day > maxDay { + return date, unstable.NewParserError(b[8:10], "impossible date") } return date, nil } +func daysIn(month int, year int) int { + switch month { + case 2: + if isLeapYear(year) { + return 29 + } + return 28 + case 4, 6, 9, 11: + return 30 + default: + return 31 + } +} + +func isLeapYear(year int) bool { + return year%4 == 0 && (year%100 != 0 || year%400 == 0) +} + +// parseDecimalDigits parses a sequence of digits as a decimal number. func parseDecimalDigits(b []byte) (int, error) { v := 0 - for i, c := range b { - if c < '0' || c > '9' { + if !isDecimalDigit(c) { return 0, unstable.NewParserError(b[i:i+1], "expected digit (0-9)") } - v *= 10 - v += int(c - '0') + v = v*10 + int(c-'0') } - return v, nil } -func parseDateTime(b []byte) (time.Time, error) { - // offset-date-time = full-date time-delim full-time - // full-time = partial-time time-offset - // time-offset = "Z" / time-numoffset - // time-numoffset = ( "+" / "-" ) time-hour ":" time-minute +// parseLocalTime parses a time of the form HH:MM with optional seconds and an +// optional fractional part (TOML v1.1.0). It returns the remaining bytes after +// the time. +func parseLocalTime(b []byte) (LocalTime, []byte, error) { + var ( + nspow = [10]int{0, 1e8, 1e7, 1e6, 1e5, 1e4, 1e3, 1e2, 1e1, 1e0} + t LocalTime + ) + // check if b matches to have expected format HH:MM[:SS[.NNNNNN]] + const localTimeByteMinLen = 5 + if len(b) < localTimeByteMinLen { + return t, nil, unstable.NewParserError(b, "times are expected to have the format HH:MM[:SS[.NNNNNN]]") + } + + var err error + t.Hour, err = parseDecimalDigits(b[0:2]) + if err != nil { + return t, nil, err + } + if t.Hour > 23 { + return t, nil, unstable.NewParserError(b[0:2], "hour cannot be greater 23") + } + if b[2] != ':' { + return t, nil, unstable.NewParserError(b[2:3], "expecting colon between hours and minutes") + } + + t.Minute, err = parseDecimalDigits(b[3:5]) + if err != nil { + return t, nil, err + } + if t.Minute > 59 { + return t, nil, unstable.NewParserError(b[3:5], "minutes cannot be greater 59") + } + + b = b[5:] + + // Seconds are optional (TOML v1.1.0). Fractional seconds may only appear + // when seconds are present: + // partial-time = time-hour ":" time-minute [ ":" time-second [ time-secfrac ] ] + secondsPresent := false + + if len(b) >= 1 && b[0] == ':' { + if len(b) < 3 { + return t, nil, unstable.NewParserError(b, "incomplete seconds") + } + + t.Second, err = parseDecimalDigits(b[1:3]) + if err != nil { + return t, nil, err + } + + if t.Second > 59 { + return t, nil, unstable.NewParserError(b[1:3], "seconds cannot be greater than 59") + } + + b = b[3:] + secondsPresent = true + } + + if secondsPresent && len(b) >= 1 && b[0] == '.' { + frac := 0 + precision := 0 + digits := 0 + + for i, c := range b[1:] { + if !isDecimalDigit(c) { + if i == 0 { + return t, nil, unstable.NewParserError(b[0:1], "need at least one digit after fraction point") + } + break + } + digits++ + if i < 9 { + frac = frac*10 + int(c-'0') + precision++ + } + } + + if digits == 0 { + return t, nil, unstable.NewParserError(b[0:1], "need at least one digit after fraction point") + } + + t.Nanosecond = frac * nspow[precision] + t.Precision = precision + + return t, b[1+digits:], nil + } + return t, b, nil +} + +// parseLocalDateTime parses a local date time of the form +// YYYY-MM-DD(T| )HH:MM:SS[.NNNNNN]. It returns the remaining bytes after the +// date-time. +func parseLocalDateTime(b []byte) (LocalDateTime, []byte, error) { + var dt LocalDateTime + + const localDateTimeByteMinLen = 11 + if len(b) < localDateTimeByteMinLen { + return dt, nil, unstable.NewParserError(b, "local datetimes are expected to have the format YYYY-MM-DDTHH:MM[:SS[.NNNNNNNNN]]") + } + + date, err := parseLocalDate(b[:10]) + if err != nil { + return dt, nil, err + } + dt.LocalDate = date + + sep := b[10] + if sep != 'T' && sep != ' ' && sep != 't' { + return dt, nil, unstable.NewParserError(b[10:11], "datetime separator is expected to be T or a space") + } + + t, rest, err := parseLocalTime(b[11:]) + if err != nil { + return dt, nil, err + } + dt.LocalTime = t + + return dt, rest, nil +} + +// parseDateTime parses a date-time with a timezone offset (Z or +/-HH:MM). +func parseDateTime(b []byte) (time.Time, error) { dt, b, err := parseLocalDateTime(b) if err != nil { return time.Time{}, err @@ -89,8 +469,8 @@ func parseDateTime(b []byte) (time.Time, error) { var zone *time.Location if len(b) == 0 { - // parser should have checked that when assigning the date time node - panic("date time should have a timezone") + // parser should have checked that there is a timezone + return time.Time{}, unstable.NewParserError(b, "date-time is missing timezone") } if b[0] == 'Z' || b[0] == 'z' { @@ -120,7 +500,7 @@ func parseDateTime(b []byte) (time.Time, error) { return time.Time{}, err } if hours > 23 { - return time.Time{}, unstable.NewParserError(b[:1], "invalid timezone offset hours") + return time.Time{}, unstable.NewParserError(b[1:3], "invalid timezone offset hours") } minutes, err := parseDecimalDigits(b[4:6]) @@ -128,7 +508,7 @@ func parseDateTime(b []byte) (time.Time, error) { return time.Time{}, err } if minutes > 59 { - return time.Time{}, unstable.NewParserError(b[:1], "invalid timezone offset minutes") + return time.Time{}, unstable.NewParserError(b[4:6], "invalid timezone offset minutes") } seconds := direction * (hours*3600 + minutes*60) @@ -156,394 +536,3 @@ func parseDateTime(b []byte) (time.Time, error) { return t, nil } - -func parseLocalDateTime(b []byte) (LocalDateTime, []byte, error) { - var dt LocalDateTime - - const localDateTimeByteMinLen = 11 - if len(b) < localDateTimeByteMinLen { - return dt, nil, unstable.NewParserError(b, "local datetimes are expected to have the format YYYY-MM-DDTHH:MM:SS[.NNNNNNNNN]") - } - - date, err := parseLocalDate(b[:10]) - if err != nil { - return dt, nil, err - } - dt.LocalDate = date - - sep := b[10] - if sep != 'T' && sep != ' ' && sep != 't' { - return dt, nil, unstable.NewParserError(b[10:11], "datetime separator is expected to be T or a space") - } - - t, rest, err := parseLocalTime(b[11:]) - if err != nil { - return dt, nil, err - } - dt.LocalTime = t - - return dt, rest, nil -} - -// parseLocalTime is a bit different because it also returns the remaining -// []byte that is didn't need. This is to allow parseDateTime to parse those -// remaining bytes as a timezone. -func parseLocalTime(b []byte) (LocalTime, []byte, error) { - var ( - nspow = [10]int{0, 1e8, 1e7, 1e6, 1e5, 1e4, 1e3, 1e2, 1e1, 1e0} - t LocalTime - ) - - // check if b matches to have expected format HH:MM:SS[.NNNNNN] - const localTimeByteLen = 8 - if len(b) < localTimeByteLen { - return t, nil, unstable.NewParserError(b, "times are expected to have the format HH:MM:SS[.NNNNNN]") - } - - var err error - - t.Hour, err = parseDecimalDigits(b[0:2]) - if err != nil { - return t, nil, err - } - - if t.Hour > 23 { - return t, nil, unstable.NewParserError(b[0:2], "hour cannot be greater 23") - } - if b[2] != ':' { - return t, nil, unstable.NewParserError(b[2:3], "expecting colon between hours and minutes") - } - - t.Minute, err = parseDecimalDigits(b[3:5]) - if err != nil { - return t, nil, err - } - if t.Minute > 59 { - return t, nil, unstable.NewParserError(b[3:5], "minutes cannot be greater 59") - } - if b[5] != ':' { - return t, nil, unstable.NewParserError(b[5:6], "expecting colon between minutes and seconds") - } - - t.Second, err = parseDecimalDigits(b[6:8]) - if err != nil { - return t, nil, err - } - - if t.Second > 59 { - return t, nil, unstable.NewParserError(b[6:8], "seconds cannot be greater than 59") - } - - b = b[8:] - - if len(b) >= 1 && b[0] == '.' { - frac := 0 - precision := 0 - digits := 0 - - for i, c := range b[1:] { - if !isDigit(c) { - if i == 0 { - return t, nil, unstable.NewParserError(b[0:1], "need at least one digit after fraction point") - } - break - } - digits++ - - const maxFracPrecision = 9 - if i >= maxFracPrecision { - // go-toml allows decoding fractional seconds - // beyond the supported precision of 9 - // digits. It truncates the fractional component - // to the supported precision and ignores the - // remaining digits. - // - // https://github.com/pelletier/go-toml/discussions/707 - continue - } - - frac *= 10 - frac += int(c - '0') - precision++ - } - - if precision == 0 { - return t, nil, unstable.NewParserError(b[:1], "nanoseconds need at least one digit") - } - - t.Nanosecond = frac * nspow[precision] - t.Precision = precision - - return t, b[1+digits:], nil - } - return t, b, nil -} - -func parseFloat(b []byte) (float64, error) { - if len(b) == 4 && (b[0] == '+' || b[0] == '-') && b[1] == 'n' && b[2] == 'a' && b[3] == 'n' { - return math.NaN(), nil - } - - cleaned, err := checkAndRemoveUnderscoresFloats(b) - if err != nil { - return 0, err - } - - if cleaned[0] == '.' { - return 0, unstable.NewParserError(b, "float cannot start with a dot") - } - - if cleaned[len(cleaned)-1] == '.' { - return 0, unstable.NewParserError(b, "float cannot end with a dot") - } - - dotAlreadySeen := false - for i, c := range cleaned { - if c == '.' { - if dotAlreadySeen { - return 0, unstable.NewParserError(b[i:i+1], "float can have at most one decimal point") - } - if !isDigit(cleaned[i-1]) { - return 0, unstable.NewParserError(b[i-1:i+1], "float decimal point must be preceded by a digit") - } - if !isDigit(cleaned[i+1]) { - return 0, unstable.NewParserError(b[i:i+2], "float decimal point must be followed by a digit") - } - dotAlreadySeen = true - } - } - - start := 0 - if cleaned[0] == '+' || cleaned[0] == '-' { - start = 1 - } - if cleaned[start] == '0' && len(cleaned) > start+1 && isDigit(cleaned[start+1]) { - return 0, unstable.NewParserError(b, "float integer part cannot have leading zeroes") - } - - f, err := strconv.ParseFloat(string(cleaned), 64) - if err != nil { - return 0, unstable.NewParserError(b, "unable to parse float: %w", err) - } - - return f, nil -} - -func parseIntHex(b []byte) (int64, error) { - cleaned, err := checkAndRemoveUnderscoresIntegers(b[2:]) - if err != nil { - return 0, err - } - - i, err := strconv.ParseInt(string(cleaned), 16, 64) - if err != nil { - return 0, unstable.NewParserError(b, "couldn't parse hexadecimal number: %w", err) - } - - return i, nil -} - -func parseIntOct(b []byte) (int64, error) { - cleaned, err := checkAndRemoveUnderscoresIntegers(b[2:]) - if err != nil { - return 0, err - } - - i, err := strconv.ParseInt(string(cleaned), 8, 64) - if err != nil { - return 0, unstable.NewParserError(b, "couldn't parse octal number: %w", err) - } - - return i, nil -} - -func parseIntBin(b []byte) (int64, error) { - cleaned, err := checkAndRemoveUnderscoresIntegers(b[2:]) - if err != nil { - return 0, err - } - - i, err := strconv.ParseInt(string(cleaned), 2, 64) - if err != nil { - return 0, unstable.NewParserError(b, "couldn't parse binary number: %w", err) - } - - return i, nil -} - -func isSign(b byte) bool { - return b == '+' || b == '-' -} - -func parseIntDec(b []byte) (int64, error) { - cleaned, err := checkAndRemoveUnderscoresIntegers(b) - if err != nil { - return 0, err - } - - startIdx := 0 - - if isSign(cleaned[0]) { - startIdx++ - } - - if len(cleaned) > startIdx+1 && cleaned[startIdx] == '0' { - return 0, unstable.NewParserError(b, "leading zero not allowed on decimal number") - } - - i, err := strconv.ParseInt(string(cleaned), 10, 64) - if err != nil { - return 0, unstable.NewParserError(b, "couldn't parse decimal number: %w", err) - } - - return i, nil -} - -func checkAndRemoveUnderscoresIntegers(b []byte) ([]byte, error) { - start := 0 - if b[start] == '+' || b[start] == '-' { - start++ - } - - if len(b) == start { - return b, nil - } - - if b[start] == '_' { - return nil, unstable.NewParserError(b[start:start+1], "number cannot start with underscore") - } - - if b[len(b)-1] == '_' { - return nil, unstable.NewParserError(b[len(b)-1:], "number cannot end with underscore") - } - - // fast path - i := 0 - for ; i < len(b); i++ { - if b[i] == '_' { - break - } - } - if i == len(b) { - return b, nil - } - - before := false - cleaned := make([]byte, i, len(b)) - copy(cleaned, b) - - for i++; i < len(b); i++ { - c := b[i] - if c == '_' { - if !before { - return nil, unstable.NewParserError(b[i-1:i+1], "number must have at least one digit between underscores") - } - before = false - } else { - before = true - cleaned = append(cleaned, c) - } - } - - return cleaned, nil -} - -func checkAndRemoveUnderscoresFloats(b []byte) ([]byte, error) { - if b[0] == '_' { - return nil, unstable.NewParserError(b[0:1], "number cannot start with underscore") - } - - if b[len(b)-1] == '_' { - return nil, unstable.NewParserError(b[len(b)-1:], "number cannot end with underscore") - } - - // fast path - i := 0 - for ; i < len(b); i++ { - if b[i] == '_' { - break - } - } - if i == len(b) { - return b, nil - } - - before := false - cleaned := make([]byte, 0, len(b)) - - for i := 0; i < len(b); i++ { - c := b[i] - - switch c { - case '_': - if !before { - return nil, unstable.NewParserError(b[i-1:i+1], "number must have at least one digit between underscores") - } - if i < len(b)-1 && (b[i+1] == 'e' || b[i+1] == 'E') { - return nil, unstable.NewParserError(b[i+1:i+2], "cannot have underscore before exponent") - } - before = false - case '+', '-': - // signed exponents - cleaned = append(cleaned, c) - before = false - case 'e', 'E': - if i < len(b)-1 && b[i+1] == '_' { - return nil, unstable.NewParserError(b[i+1:i+2], "cannot have underscore after exponent") - } - cleaned = append(cleaned, c) - case '.': - if i < len(b)-1 && b[i+1] == '_' { - return nil, unstable.NewParserError(b[i+1:i+2], "cannot have underscore after decimal point") - } - if i > 0 && b[i-1] == '_' { - return nil, unstable.NewParserError(b[i-1:i], "cannot have underscore before decimal point") - } - cleaned = append(cleaned, c) - default: - before = true - cleaned = append(cleaned, c) - } - } - - return cleaned, nil -} - -// isValidDate checks if a provided date is a date that exists. -func isValidDate(year int, month int, day int) bool { - return month > 0 && month < 13 && day > 0 && day <= daysIn(month, year) -} - -// daysBefore[m] counts the number of days in a non-leap year -// before month m begins. There is an entry for m=12, counting -// the number of days before January of next year (365). -var daysBefore = [...]int32{ - 0, - 31, - 31 + 28, - 31 + 28 + 31, - 31 + 28 + 31 + 30, - 31 + 28 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31, -} - -func daysIn(m int, year int) int { - if m == 2 && isLeap(year) { - return 29 - } - return int(daysBefore[m] - daysBefore[m-1]) -} - -func isLeap(year int) bool { - return year%4 == 0 && (year%100 != 0 || year%400 == 0) -} - -func isDigit(r byte) bool { - return r >= '0' && r <= '9' -} diff --git a/vendor/github.com/pelletier/go-toml/v2/decode_fused.go b/vendor/github.com/pelletier/go-toml/v2/decode_fused.go new file mode 100644 index 000000000..9de2d6522 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/v2/decode_fused.go @@ -0,0 +1,362 @@ +package toml + +import ( + "errors" + "reflect" + "strings" + + "github.com/pelletier/go-toml/v2/internal/parserbridge" + "github.com/pelletier/go-toml/v2/unstable" +) + +// unmarshalFused decodes a whole document into a native map[string]interface{} +// tree with no reflection on the document structure, and without building an +// AST for table headers and scalar key-values. Only container values (arrays +// and inline tables) are parsed into the parser arena, so that the seen-tracker +// can validate them and decodeAny can presize the resulting slices and maps — +// the AST is what makes that cheap O(1) presizing possible. +// +// It is used when the target is a fully generic value (interface{} or +// map[string]interface{}) and the unmarshaler interface is disabled. The +// seen-tracker validates the document (duplicate keys, type consistency), so +// the builder creates and merges containers without revalidating. Strict mode +// never applies to a generic target (a map has no "unknown fields"), and +// captures never apply (a generic value implements no Unmarshaler). +func (d *decoder) unmarshalFused(root reflect.Value, data []byte) error { + var m map[string]interface{} + if !root.IsNil() { + // Decode into (merge with) an existing generic map when present. + if em, ok := root.Interface().(map[string]interface{}); ok { + m = em + } + } + if m == nil { + m = map[string]interface{}{} + } + + if err := d.fusedDocument(m, data); err != nil { + return d.wrapFusedError(data, err) + } + + if root.CanSet() { + root.Set(reflect.ValueOf(m)) + } + return nil +} + +// fusedDocument runs the top-level expression loop, mirroring +// Parser.NextExpression but storing values directly into native maps. +func (d *decoder) fusedDocument(m map[string]interface{}, b []byte) error { + cur := m + for { + b = fusedSkipWS(b) + if len(b) == 0 { + return nil + } + switch b[0] { + case '\n': + b = b[1:] + case '\r': + if len(b) > 1 && b[1] == '\n' { + b = b[2:] + continue + } + return unstable.NewParserError(b[:1], "expected newline but got %#U", b[0]) + case '#': + _, rest, err := parserbridge.ScanComment(b) + if err != nil { + return err + } + rest, err = fusedConsumeEOL(rest) + if err != nil { + return err + } + b = rest + case '[': + rest, err := d.fusedTable(b, m, &cur) + if err != nil { + return err + } + b = rest + default: + rest, err := d.fusedKeyVal(b, cur) + if err != nil { + return err + } + b = rest + } + } +} + +// fusedTable handles a [table] or [[array table]] header. b starts at '['. It +// updates *cur to the table the following key-values belong to. +func (d *decoder) fusedTable(b []byte, root map[string]interface{}, cur *map[string]interface{}) ([]byte, error) { + arrayTable := len(b) > 1 && b[1] == '[' + + var start []byte + if arrayTable { + start = fusedSkipWS(b[2:]) + } else { + start = fusedSkipWS(b[1:]) + } + + var err error + var rawKey []byte + d.keyParts, rawKey, b, err = parserbridge.ScanKey(&d.p, start, d.keyParts[:0]) + if err != nil { + return nil, err + } + + if arrayTable { + if len(b) < 2 || b[0] != ']' || b[1] != ']' { + return nil, unstable.NewParserError(fusedHL1(b), "expected ']]' to close array table name") + } + b = b[2:] + } else { + if len(b) == 0 || b[0] != ']' { + return nil, unstable.NewParserError(fusedHL1(b), "expected ']' to close table name") + } + b = b[1:] + } + + // The whole expression (including its line termination) is parsed before + // it is validated, to keep error precedence identical to the AST path. + b, err = d.fusedFinishLine(b) + if err != nil { + return nil, err + } + + if arrayTable { + first, err := d.seen.CheckArrayTable(d.keyParts) + if err != nil { + return nil, d.fusedSeenError(rawKey, d.keyParts, err) + } + *cur = d.anyArrayTableParts(root, d.keyParts, first) + } else { + if _, err := d.seen.CheckTable(d.keyParts); err != nil { + return nil, d.fusedSeenError(rawKey, d.keyParts, err) + } + *cur = d.anyTableParts(root, d.keyParts) + } + return b, nil +} + +// fusedKeyVal handles a `key = value` expression relative to the current table +// cur. b starts at the first character of the key. +func (d *decoder) fusedKeyVal(b []byte, cur map[string]interface{}) ([]byte, error) { + var err error + var rawKey []byte + d.keyParts, rawKey, b, err = parserbridge.ScanKey(&d.p, b, d.keyParts[:0]) + if err != nil { + return nil, err + } + if len(b) == 0 || b[0] != '=' { + return nil, unstable.NewParserError(fusedHL1(b), "expected '=' after key") + } + b = fusedSkipWS(b[1:]) + if len(b) == 0 { + return nil, unstable.NewParserError(b, "expected value, not end of input") + } + + if c := b[0]; c == '[' || c == '{' { + // Container value: build its AST so the seen-tracker can validate it + // and decodeAny can presize the resulting slices and maps. + nodeAny, rest, err := parserbridge.ParseValue(&d.p, b) + if err != nil { + return nil, err + } + node := nodeAny.(*unstable.Node) + rest, err = d.fusedFinishLine(rest) + if err != nil { + return nil, err + } + leafID, err := d.seen.CheckKeyValue(d.keyParts) + if err != nil { + return nil, d.fusedSeenError(rawKey, d.keyParts, err) + } + if err := d.seen.CheckValueUnder(leafID, node); err != nil { + return nil, d.fusedSeenError(rawKey, d.keyParts, err) + } + av, err := d.decodeAny(node) + if err != nil { + return nil, err + } + d.setFusedLeaf(cur, d.keyParts, av) + return rest, nil + } + + // Scalar value: scan it without building a node, then validate and convert + // it natively. + k, _, value, rest, err := parserbridge.ScanScalar(&d.p, b) + if err != nil { + return nil, err + } + kind := unstable.Kind(k) + rest, err = d.fusedFinishLine(rest) + if err != nil { + return nil, err + } + if _, err := d.seen.CheckKeyValue(d.keyParts); err != nil { + return nil, d.fusedSeenError(rawKey, d.keyParts, err) + } + av, err := d.fusedScalar(kind, value) + if err != nil { + return nil, err + } + d.setFusedLeaf(cur, d.keyParts, av) + return rest, nil +} + +// fusedSeenError turns a bare error returned by a SeenTracker parts-method +// into a ParserError carrying the position (the raw key span) and key path of +// the offending expression, so that it is reported as a DecodeError with +// context. It mirrors decoder.wrapSeenError for the fused (AST-less) path. +func (d *decoder) fusedSeenError(rawKey []byte, parts [][]byte, err error) error { + key := make(Key, len(parts)) + for i, p := range parts { + key[i] = string(p) + } + return &unstable.ParserError{ + Highlight: rawKey, + Message: strings.TrimPrefix(err.Error(), "toml: "), + Key: key, + } +} + +// fusedScalar converts a scanned scalar value into the native Go value used +// for generic targets. It mirrors the scalar cases of decodeAny. +func (d *decoder) fusedScalar(kind unstable.Kind, value []byte) (interface{}, error) { + switch kind { + case unstable.String: + return string(value), nil + case unstable.Integer: + i, err := parseInteger(value) + return i, err + case unstable.Float: + f, err := parseFloat(value) + return f, err + case unstable.Bool: + return value[0] == 't', nil + case unstable.DateTime: + t, err := parseDateTime(value) + return t, err + case unstable.LocalDateTime: + dt, rest, err := parseLocalDateTime(value) + if err != nil { + return nil, err + } + if len(rest) > 0 { + return nil, unstable.NewParserError(rest, "extra characters at the end of a local date time") + } + return dt, nil + case unstable.LocalDate: + date, err := parseLocalDate(value) + return date, err + case unstable.LocalTime: + t, rest, err := parseLocalTime(value) + if err != nil { + return nil, err + } + if len(rest) > 0 { + return nil, unstable.NewParserError(rest, "extra characters at the end of a local time") + } + return t, nil + default: + return nil, unstable.NewParserError(value, "unsupported value kind %s", kind) + } +} + +// anyTableParts navigates a [table] header (given its key parts) to the map it +// designates, creating intermediate tables as needed. +func (d *decoder) anyTableParts(m map[string]interface{}, parts [][]byte) map[string]interface{} { + cur := m + for _, p := range parts { + cur = d.anyChildTable(cur, d.intern(p)) + } + return cur +} + +// anyArrayTableParts navigates a [[array table]] header (given its key parts), +// appends a fresh element to the designated array, and returns it. first is +// true the first time this header is seen, in which case any pre-existing array +// (from a reused target) is reset. +func (d *decoder) anyArrayTableParts(m map[string]interface{}, parts [][]byte, first bool) map[string]interface{} { + cur := m + name := d.intern(parts[0]) + for i := 1; i < len(parts); i++ { + cur = d.anyChildTable(cur, name) + name = d.intern(parts[i]) + } + s, _ := cur[name].([]interface{}) + if first { + s = s[:0] + } + elem := map[string]interface{}{} + cur[name] = append(s, elem) + return elem +} + +// setFusedLeaf assigns av at the (possibly dotted) key parts within cur, +// creating intermediate maps as needed. +func (d *decoder) setFusedLeaf(cur map[string]interface{}, parts [][]byte, av interface{}) { + for i := 0; i < len(parts)-1; i++ { + cur = d.anyChildTable(cur, d.intern(parts[i])) + } + cur[d.intern(parts[len(parts)-1])] = av +} + +// wrapFusedError gives document context to errors produced by the fused +// decoder. +func (d *decoder) wrapFusedError(data []byte, err error) error { + var perr *unstable.ParserError + if errors.As(err, &perr) && len(perr.Highlight) == 0 { + // Mirror NextExpression: give end-of-input errors a usable position by + // extending the empty highlight to the last byte of the document. + if offset := cap(data) - cap(perr.Highlight); offset > 0 && offset == len(data) { + perr.Highlight = data[offset-1 : offset] + } + } + return d.wrapError(data, err) +} + +func fusedSkipWS(b []byte) []byte { + for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') { + b = b[1:] + } + return b +} + +func fusedConsumeEOL(b []byte) ([]byte, error) { + if len(b) == 0 { + return b, nil + } + switch b[0] { + case '\n': + return b[1:], nil + case '\r': + if len(b) > 1 && b[1] == '\n' { + return b[2:], nil + } + } + return nil, unstable.NewParserError(b[:1], "expected newline but got %#U", b[0]) +} + +// fusedFinishLine consumes `ws [comment] (newline|eof)` after an expression. +func (d *decoder) fusedFinishLine(b []byte) ([]byte, error) { + b = fusedSkipWS(b) + if len(b) > 0 && b[0] == '#' { + _, rest, err := parserbridge.ScanComment(b) + if err != nil { + return nil, err + } + b = rest + } + return fusedConsumeEOL(b) +} + +func fusedHL1(b []byte) []byte { + if len(b) > 0 { + return b[:1] + } + return b +} diff --git a/vendor/github.com/pelletier/go-toml/v2/errors.go b/vendor/github.com/pelletier/go-toml/v2/errors.go index d68835dfa..8e10b128d 100644 --- a/vendor/github.com/pelletier/go-toml/v2/errors.go +++ b/vendor/github.com/pelletier/go-toml/v2/errors.go @@ -1,8 +1,7 @@ package toml import ( - "fmt" - "reflect" + "errors" "strconv" "strings" @@ -47,7 +46,6 @@ func (s *StrictMissingError) String() string { if i > 0 { buf.WriteString("\n---\n") } - buf.WriteString(e.String()) } @@ -73,7 +71,8 @@ func (e *DecodeError) Error() string { return "toml: " + e.message } -// String returns the human-readable contextualized error. This string is multi-line. +// String returns the human-readable contextualized error. This string is +// multi-line. func (e *DecodeError) String() string { return e.human } @@ -84,200 +83,151 @@ func (e *DecodeError) Position() (row int, column int) { return e.line, e.column } -// Key that was being processed when the error occurred. The key is present only -// if this DecodeError is part of a StrictMissingError. +// Key that was being processed when the error occurred. func (e *DecodeError) Key() Key { return e.key } -// wrapDecodeError creates a DecodeError referencing a highlighted -// range of bytes from document. -// -// highlight needs to be a sub-slice of document, or this function panics. -// -// The function copies all bytes used in DecodeError, so that document and -// highlight can be freely deallocated. -// -//nolint:funlen +// wrapDecodeError creates a DecodeError from a ParserError. The highlight of +// the ParserError needs to be a subslice of the document. func wrapDecodeError(document []byte, de *unstable.ParserError) *DecodeError { - offset := subsliceOffset(document, de.Highlight) - - errMessage := de.Error() - errLine, errColumn := positionAtEnd(document[:offset]) - before, after := linesOfContext(document, de.Highlight, offset, 3) - - var buf strings.Builder - - maxLine := errLine + len(after) - 1 - lineColumnWidth := len(strconv.Itoa(maxLine)) - - // Write the lines of context strictly before the error. - for i := len(before) - 1; i > 0; i-- { - line := errLine - i - buf.WriteString(formatLineNumber(line, lineColumnWidth)) - buf.WriteString("|") - - if len(before[i]) > 0 { - buf.WriteString(" ") - buf.Write(before[i]) - } - - buf.WriteRune('\n') + if de == nil { + return nil } + return newDecodeError(document, de.Highlight, de.Key, de.Message) +} - // Write the document line that contains the error. +// newDecodeError creates a DecodeError pointing at the given highlight, which +// needs to be a subslice of the document. +func newDecodeError(document []byte, highlight []byte, key Key, message string) *DecodeError { + offset := subsliceOffset(document, highlight) - buf.WriteString(formatLineNumber(errLine, lineColumnWidth)) - buf.WriteString("| ") + errLineIdx, errColumn := positionAt(document, offset) - if len(before) > 0 { - buf.Write(before[0]) - } - - buf.Write(de.Highlight) - - if len(after) > 0 { - buf.Write(after[0]) - } - - buf.WriteRune('\n') - - // Write the line with the error message itself (so it does not have a line - // number). - - buf.WriteString(strings.Repeat(" ", lineColumnWidth)) - buf.WriteString("| ") - - if len(before) > 0 { - buf.WriteString(strings.Repeat(" ", len(before[0]))) - } - - buf.WriteString(strings.Repeat("~", len(de.Highlight))) - - if len(errMessage) > 0 { - buf.WriteString(" ") - buf.WriteString(errMessage) - } - - // Write the lines of context strictly after the error. - - for i := 1; i < len(after); i++ { - buf.WriteRune('\n') - line := errLine + i - buf.WriteString(formatLineNumber(line, lineColumnWidth)) - buf.WriteString("|") - - if len(after[i]) > 0 { - buf.WriteString(" ") - buf.Write(after[i]) - } - } + human := buildHumanContext(document, errLineIdx, errColumn, len(highlight), message) return &DecodeError{ - message: errMessage, - line: errLine, + message: message, + line: errLineIdx + 1, column: errColumn, - key: de.Key, - human: buf.String(), + key: key, + human: human, } } -func formatLineNumber(line int, width int) string { - format := "%" + strconv.Itoa(width) + "d" - - return fmt.Sprintf(format, line) -} - -func linesOfContext(document []byte, highlight []byte, offset int, linesAround int) ([][]byte, [][]byte) { - return beforeLines(document, offset, linesAround), afterLines(document, highlight, offset, linesAround) -} - -func beforeLines(document []byte, offset int, linesAround int) [][]byte { - var beforeLines [][]byte - - // Walk the document backward from the highlight to find previous lines - // of context. - rest := document[:offset] -backward: - for o := len(rest) - 1; o >= 0 && len(beforeLines) <= linesAround && len(rest) > 0; { - switch { - case rest[o] == '\n': - // handle individual lines - beforeLines = append(beforeLines, rest[o+1:]) - rest = rest[:o] - o = len(rest) - 1 - case o == 0: - // add the first line only if it's non-empty - beforeLines = append(beforeLines, rest) - - break backward - default: - o-- - } - } - - return beforeLines -} - -func afterLines(document []byte, highlight []byte, offset int, linesAround int) [][]byte { - var afterLines [][]byte - - // Walk the document forward from the highlight to find the following - // lines of context. - rest := document[offset+len(highlight):] -forward: - for o := 0; o < len(rest) && len(afterLines) <= linesAround; { - switch { - case rest[o] == '\n': - // handle individual lines - afterLines = append(afterLines, rest[:o]) - rest = rest[o+1:] - o = 0 - - case o == len(rest)-1: - // add last line only if it's non-empty - afterLines = append(afterLines, rest) - - break forward - default: - o++ - } - } - - return afterLines -} - -func positionAtEnd(b []byte) (row int, column int) { - row = 1 - column = 1 - - for _, c := range b { - if c == '\n' { - row++ - column = 1 - } else { - column++ - } - } - - return row, column -} - -// subsliceOffset returns the byte offset of subslice within data. -// subslice must share the same backing array as data. -func subsliceOffset(data []byte, subslice []byte) int { - if len(subslice) == 0 { - return 0 - } - - // Use reflect to get the data pointers of both slices. - // This is safe because we're only reading the pointer values for comparison. - dataPtr := reflect.ValueOf(data).Pointer() - subPtr := reflect.ValueOf(subslice).Pointer() - - offset := int(subPtr - dataPtr) - if offset < 0 || offset > len(data) { - panic("subslice is not within data") +// subsliceOffset returns the offset of the subslice b within the document. +func subsliceOffset(document, b []byte) int { + // Highlights are subslices of the document, which means they share the + // same backing array, and their capacity counts the bytes between their + // start and the end of the backing array. + offset := cap(document) - cap(b) + if offset < 0 || offset+len(b) > len(document) { + panic(errors.New("highlight is not a subslice of the document")) } return offset } + +// positionAt returns the 0-indexed line and the 1-indexed column of the given +// offset in the document. +func positionAt(document []byte, offset int) (lineIdx int, column int) { + lineStart := 0 + for i := 0; i < offset; i++ { + if document[i] == '\n' { + lineIdx++ + lineStart = i + 1 + } + } + return lineIdx, offset - lineStart + 1 +} + +// docLines splits the document into lines, removing the trailing newline +// characters. +func docLines(document []byte) []string { + s := string(document) + lines := strings.Split(s, "\n") + for i, l := range lines { + lines[i] = strings.TrimSuffix(l, "\r") + } + return lines +} + +// buildHumanContext renders the human-readable multi-line context of an +// error: a window of up to 3 lines before and after the error line, with +// the error position underlined. +func buildHumanContext(document []byte, errLineIdx, errColumn, highlightLen int, message string) string { + lines := docLines(document) + + const window = 3 + firstIdx := errLineIdx - window + if firstIdx < 0 { + firstIdx = 0 + } + lastIdx := errLineIdx + window + if lastIdx > len(lines)-1 { + lastIdx = len(lines) - 1 + } + // Empty lines at the edges of the window are dropped, unless the error + // is about that very position. + for firstIdx < errLineIdx && lines[firstIdx] == "" { + firstIdx++ + } + for lastIdx > errLineIdx && lines[lastIdx] == "" { + lastIdx-- + } + + // Width of the column of line numbers. + width := len(strconv.Itoa(lastIdx + 1)) + + var buf strings.Builder + + writeLine := func(idx int) { + number := strconv.Itoa(idx + 1) + for i := len(number); i < width; i++ { + buf.WriteByte(' ') + } + buf.WriteString(number) + buf.WriteByte('|') + if len(lines[idx]) > 0 { + buf.WriteByte(' ') + buf.WriteString(lines[idx]) + } + buf.WriteByte('\n') + } + + for idx := firstIdx; idx <= errLineIdx; idx++ { + writeLine(idx) + } + + // Underline the error. + for i := 0; i < width; i++ { + buf.WriteByte(' ') + } + buf.WriteString("| ") + for i := 1; i < errColumn; i++ { + buf.WriteByte(' ') + } + // The highlight cannot extend past the end of its line. + tildes := highlightLen + if errLineIdx < len(lines) { + if avail := len(lines[errLineIdx]) - errColumn + 1; tildes > avail { + tildes = avail + } + } + if tildes < 1 { + tildes = 1 + } + for i := 0; i < tildes; i++ { + buf.WriteByte('~') + } + if message != "" { + buf.WriteByte(' ') + buf.WriteString(message) + } + buf.WriteByte('\n') + + for idx := errLineIdx + 1; idx <= lastIdx; idx++ { + writeLine(idx) + } + + return strings.TrimSuffix(buf.String(), "\n") +} diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go b/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go deleted file mode 100644 index 50a6d1702..000000000 --- a/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go +++ /dev/null @@ -1,42 +0,0 @@ -package characters - -var invalidASCIITable = [256]bool{ - 0x00: true, - 0x01: true, - 0x02: true, - 0x03: true, - 0x04: true, - 0x05: true, - 0x06: true, - 0x07: true, - 0x08: true, - // 0x09 TAB - // 0x0A LF - 0x0B: true, - 0x0C: true, - // 0x0D CR - 0x0E: true, - 0x0F: true, - 0x10: true, - 0x11: true, - 0x12: true, - 0x13: true, - 0x14: true, - 0x15: true, - 0x16: true, - 0x17: true, - 0x18: true, - 0x19: true, - 0x1A: true, - 0x1B: true, - 0x1C: true, - 0x1D: true, - 0x1E: true, - 0x1F: true, - // 0x20 - 0x7E Printable ASCII characters - 0x7F: true, -} - -func InvalidASCII(b byte) bool { - return invalidASCIITable[b] -} diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go b/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go deleted file mode 100644 index 7c5cb55e4..000000000 --- a/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go +++ /dev/null @@ -1,175 +0,0 @@ -// Package characters provides functions for working with string encodings. -package characters - -import ( - "unicode/utf8" -) - -// Utf8TomlValidAlreadyEscaped verifies that a given string is only made of -// valid UTF-8 characters allowed by the TOML spec: -// -// Any Unicode character may be used except those that must be escaped: -// quotation mark, backslash, and the control characters other than tab (U+0000 -// to U+0008, U+000A to U+001F, U+007F). -// -// It is a copy of the Go 1.17 utf8.Valid implementation, tweaked to exit early -// when a character is not allowed. -// -// The returned slice is empty if the string is valid, or contains the bytes -// of the invalid character. -// -// quotation mark => already checked -// backslash => already checked -// 0-0x8 => invalid -// 0x9 => tab, ok -// 0xA - 0x1F => invalid -// 0x7F => invalid -func Utf8TomlValidAlreadyEscaped(p []byte) []byte { - // Fast path. Check for and skip 8 bytes of ASCII characters per iteration. - for len(p) >= 8 { - // Combining two 32 bit loads allows the same code to be used - // for 32 and 64 bit platforms. - // The compiler can generate a 32bit load for first32 and second32 - // on many platforms. See test/codegen/memcombine.go. - first32 := uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 - second32 := uint32(p[4]) | uint32(p[5])<<8 | uint32(p[6])<<16 | uint32(p[7])<<24 - if (first32|second32)&0x80808080 != 0 { - // Found a non ASCII byte (>= RuneSelf). - break - } - - for i, b := range p[:8] { - if InvalidASCII(b) { - return p[i : i+1] - } - } - - p = p[8:] - } - n := len(p) - for i := 0; i < n; { - pi := p[i] - if pi < utf8.RuneSelf { - if InvalidASCII(pi) { - return p[i : i+1] - } - i++ - continue - } - x := first[pi] - if x == xx { - // Illegal starter byte. - return p[i : i+1] - } - size := int(x & 7) - if i+size > n { - // Short or invalid. - return p[i:n] - } - accept := acceptRanges[x>>4] - if c := p[i+1]; c < accept.lo || accept.hi < c { - return p[i : i+2] - } else if size == 2 { //revive:disable:empty-block - } else if c := p[i+2]; c < locb || hicb < c { - return p[i : i+3] - } else if size == 3 { //revive:disable:empty-block - } else if c := p[i+3]; c < locb || hicb < c { - return p[i : i+4] - } - i += size - } - return nil -} - -// Utf8ValidNext returns the size of the next rune if valid, 0 otherwise. -func Utf8ValidNext(p []byte) int { - c := p[0] - - if c < utf8.RuneSelf { - if InvalidASCII(c) { - return 0 - } - return 1 - } - - x := first[c] - if x == xx { - // Illegal starter byte. - return 0 - } - size := int(x & 7) - if size > len(p) { - // Short or invalid. - return 0 - } - accept := acceptRanges[x>>4] - if c := p[1]; c < accept.lo || accept.hi < c { - return 0 - } else if size == 2 { //nolint:revive - } else if c := p[2]; c < locb || hicb < c { - return 0 - } else if size == 3 { //nolint:revive - } else if c := p[3]; c < locb || hicb < c { - return 0 - } - - return size -} - -// acceptRange gives the range of valid values for the second byte in a UTF-8 -// sequence. -type acceptRange struct { - lo uint8 // lowest value for second byte. - hi uint8 // highest value for second byte. -} - -// acceptRanges has size 16 to avoid bounds checks in the code that uses it. -var acceptRanges = [16]acceptRange{ - 0: {locb, hicb}, - 1: {0xA0, hicb}, - 2: {locb, 0x9F}, - 3: {0x90, hicb}, - 4: {locb, 0x8F}, -} - -// first is information about the first byte in a UTF-8 sequence. -var first = [256]uint8{ - // 1 2 3 4 5 6 7 8 9 A B C D E F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F - as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F - // 1 2 3 4 5 6 7 8 9 A B C D E F - xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F - xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F - xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF - xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF - xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF - s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF - s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF - s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF -} - -const ( - // The default lowest and highest continuation byte. - locb = 0b10000000 - hicb = 0b10111111 - - // These names of these constants are chosen to give nice alignment in the - // table below. The first nibble is an index into acceptRanges or F for - // special one-byte cases. The second nibble is the Rune length or the - // Status for the special one-byte case. - xx = 0xF1 // invalid: size 1 - as = 0xF0 // ASCII: size 1 - s1 = 0x02 // accept 0, size 2 - s2 = 0x13 // accept 1, size 3 - s3 = 0x03 // accept 0, size 3 - s4 = 0x23 // accept 2, size 3 - s5 = 0x34 // accept 3, size 4 - s6 = 0x04 // accept 0, size 4 - s7 = 0x44 // accept 4, size 4 -) diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/parserbridge/parserbridge.go b/vendor/github.com/pelletier/go-toml/v2/internal/parserbridge/parserbridge.go new file mode 100644 index 000000000..703aceea4 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/v2/internal/parserbridge/parserbridge.go @@ -0,0 +1,37 @@ +// Package parserbridge exposes the unstable parser's non-AST scanners to the +// root toml package without making them part of the unstable public API. +// +// The fused generic-decode fast path needs to scan keys, scalars and comments +// (and parse container values into the arena) without going through the +// AST-pushing NextExpression/Expression methods. Those scanners depend on +// Parser internals (the string-unescape scratch buffer and the node arena), so +// they have to live in the unstable package; but they are an implementation +// detail of the decoder, not something we want to commit to in the public API. +// +// The unstable package populates these variables in its init; the toml package +// reads them. The parser is passed as an any (it is always an *unstable.Parser) +// and the scalar kind is an int (it is always an unstable.Kind) so that this +// package imports neither unstable nor toml, avoiding an import cycle. Passing +// a pointer through an interface does not allocate, so the fused path keeps its +// allocation profile. +package parserbridge + +var ( + // ScanScalar scans a single scalar value (string, integer, float, bool or + // date/time) without building an AST node. kind is an unstable.Kind. + ScanScalar func(p any, b []byte) (kind int, raw, value, rest []byte, err error) + + // ScanKey scans a (possibly dotted) key without building AST nodes, + // appending each decoded part to dst. + ScanKey func(p any, b []byte, dst [][]byte) (parts [][]byte, raw, rest []byte, err error) + + // ScanComment scans a comment starting at '#', returning the comment bytes + // (including '#', excluding the line ending) and the rest of the input. It + // needs no parser state. + ScanComment func(b []byte) (comment, rest []byte, err error) + + // ParseValue parses a single value (including arrays and inline tables) into + // the parser arena, returning the root *unstable.Node and the rest of the + // input. + ParseValue func(p any, b []byte) (node any, rest []byte, err error) +) diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go index 6344fd047..661b11cf9 100644 --- a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go +++ b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go @@ -14,7 +14,8 @@ func (t *KeyTracker) UpdateTable(node *unstable.Node) { t.Push(node) } -// UpdateArrayTable sets the state of the tracker with the AST array table node. +// UpdateArrayTable sets the state of the tracker with the AST array table +// node. func (t *KeyTracker) UpdateArrayTable(node *unstable.Node) { t.reset() t.Push(node) diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go index 206235800..e88cd9415 100644 --- a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go +++ b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go @@ -3,7 +3,6 @@ package tracker import ( "bytes" "fmt" - "sync" "github.com/pelletier/go-toml/v2/unstable" ) @@ -12,9 +11,21 @@ type keyKind uint8 const ( invalidKind keyKind = iota + // valueKind is a regular value (scalar, array, or inline table). It + // cannot be extended. valueKind + // kvTableKind is a table created implicitly by a dotted key. It can only + // be extended by other dotted keys. + kvTableKind + // tableKind is a table created by a [header]. The explicit flag tells + // whether the table was created by its own header (true) or as an + // intermediate step of a longer key (false). tableKind + // arrayTableKind is an array of tables created by [[header]]. arrayTableKind + // anonymousKind is an entry that cannot be looked up by name. It serves + // as the parent of the content of inline tables stored inside arrays. + anonymousKind ) func (k keyKind) String() string { @@ -23,22 +34,36 @@ func (k keyKind) String() string { return "invalid" case valueKind: return "value" + case kvTableKind: + return "kv-table" case tableKind: return "table" case arrayTableKind: - return "array table" + return "array-table" + case anonymousKind: + return "anonymous" } panic("missing keyKind string mapping") } +// entry represents a node that has been seen in the document. Its size has a +// direct impact on the performance of unmarshaling documents: keep it as +// small as possible. +type entry struct { + parent int32 + kind keyKind + explicit bool + name []byte +} + // SeenTracker tracks which keys have been seen with which TOML type to flag // duplicates and mismatches according to the spec. // -// Each node in the visited tree is represented by an entry. Each entry has an -// identifier, which is provided by a counter. Entries are stored in the array -// entries. As new nodes are discovered (referenced for the first time in the -// TOML document), entries are created and appended to the array. An entry -// points to its parent using its id. +// Each node in the visited tree is represented by an entry. Each entry has +// an identifier, which is provided by a counter. Entries are stored in the +// array entries. As new nodes are discovered (referenced for the first time +// in the TOML document), entries are created and appended to the array. An +// entry points to its parent using its id. // // To find whether a given key (sequence of []byte) has already been visited, // the entries are linearly searched, looking for one with the right name and @@ -53,307 +78,373 @@ func (k keyKind) String() string { // invariant above, the deletion process needs to keep the order of entries. // This results in more copies in that case. type SeenTracker struct { - entries []entry - currentIdx int + entries []entry + currentTable int32 + + // scratch buffers for clear() + removedBuf []bool + remapBuf []int32 } -var pool = sync.Pool{ - New: func() interface{} { - return &SeenTracker{} - }, +// Reset brings the tracker to its initial state, with just a root table, so +// that it can be reused across documents. +func (s *SeenTracker) Reset() { + s.reset() } +// reset brings the tracker to its initial state, with just a root table. func (s *SeenTracker) reset() { - // Always contains a root element at index 0. - s.currentIdx = 0 - if len(s.entries) == 0 { - s.entries = make([]entry, 1, 2) - } else { - s.entries = s.entries[:1] - } - s.entries[0].child = -1 - s.entries[0].next = -1 + s.entries = append(s.entries[:0], entry{ + parent: -1, + kind: tableKind, + }) + s.currentTable = 0 } -type entry struct { - // Use -1 to indicate no child or no sibling. - child int - next int - - name []byte - kind keyKind - explicit bool - kv bool -} - -// Find the index of the child of parentIdx with key k. Returns -1 if -// it does not exist. -func (s *SeenTracker) find(parentIdx int, k []byte) int { - for i := s.entries[parentIdx].child; i >= 0; i = s.entries[i].next { - if bytes.Equal(s.entries[i].name, k) { - return i +// find returns the id of the entry with the given parent and name, or -1. +// Anonymous entries are never returned. +func (s *SeenTracker) find(parent int32, name []byte) int32 { + // Children always appear after their parent. + for i := int(parent) + 1; i < len(s.entries); i++ { + e := &s.entries[i] + if e.parent == parent && e.kind != anonymousKind && bytes.Equal(e.name, name) { + return int32(i) //nolint:gosec // entry counts are bounded by document size } } return -1 } -// Remove all descendants of node at position idx. -func (s *SeenTracker) clear(idx int) { - if idx >= len(s.entries) { - return - } - - for i := s.entries[idx].child; i >= 0; { - next := s.entries[i].next - n := s.entries[0].next - s.entries[0].next = i - s.entries[i].next = n - s.entries[i].name = nil - s.clear(i) - i = next - } - - s.entries[idx].child = -1 -} - -func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit bool, kv bool) int { - e := entry{ - child: -1, - next: s.entries[parentIdx].child, - - name: name, +// create appends a new entry and returns its id. +func (s *SeenTracker) create(parent int32, name []byte, kind keyKind, explicit bool) int32 { + id := int32(len(s.entries)) //nolint:gosec // entry counts are bounded by document size + s.entries = append(s.entries, entry{ + parent: parent, kind: kind, explicit: explicit, - kv: kv, - } - var idx int - if s.entries[0].next >= 0 { - idx = s.entries[0].next - s.entries[0].next = s.entries[idx].next - s.entries[idx] = e - } else { - idx = len(s.entries) - s.entries = append(s.entries, e) - } - - s.entries[parentIdx].child = idx - - return idx + name: name, + }) + return id } -func (s *SeenTracker) setExplicitFlag(parentIdx int) { - for i := s.entries[parentIdx].child; i >= 0; i = s.entries[i].next { - if s.entries[i].kv { - s.entries[i].explicit = true - s.entries[i].kv = false - } - s.setExplicitFlag(i) +// clear removes all the descendants of the entry with the given id, keeping +// the order of the remaining entries. +func (s *SeenTracker) clear(id int32) { + // Compute which entries are removed. Given that children always appear + // after their parent, a single forward pass is enough. + if cap(s.removedBuf) < len(s.entries) { + s.removedBuf = make([]bool, len(s.entries)) + s.remapBuf = make([]int32, len(s.entries)) } + removed := s.removedBuf[:len(s.entries)] + remap := s.remapBuf[:len(s.entries)] + for i := range removed { + removed[i] = false + } + + n := int32(0) + for i := 0; i < len(s.entries); i++ { + parent := s.entries[i].parent + if parent >= 0 && (parent == id && s.entries[i].kind != invalidKind || removed[parent]) { + removed[i] = true + continue + } + remap[i] = n + if int32(i) != n { //nolint:gosec // entry counts are bounded by document size + e := s.entries[i] + e.parent = remap[e.parent] + s.entries[n] = e + } + n++ + } + s.entries = s.entries[:n] } // CheckExpression takes a top-level node and checks that it does not contain // keys that have been seen in previous calls, and validates that types are -// consistent. It returns true if it is the first time this node's key is seen. -// Useful to clear array tables on first use. +// consistent. It returns true if it is the first time this node's key is +// seen. Useful to clear array tables on first use. func (s *SeenTracker) CheckExpression(node *unstable.Node) (bool, error) { - if s.entries == nil { + if len(s.entries) == 0 { s.reset() } switch node.Kind { case unstable.KeyValue: - return s.checkKeyValue(node) + return false, s.checkKeyValue(s.currentTable, node) case unstable.Table: return s.checkTable(node) case unstable.ArrayTable: return s.checkArrayTable(node) default: - panic(fmt.Errorf("this should not be a top level node type: %s", node.Kind)) + return false, fmt.Errorf("toml: unexpected expression kind %s", node.Kind) } } +// CheckTable validates a [table] header given the decoded parts of its key. +// It mirrors checkTable but is driven directly from the key parts instead of +// an AST, for callers that decode without building one. It returns whether the +// table is seen for the first time. +func (s *SeenTracker) CheckTable(parts [][]byte) (bool, error) { + parent := int32(0) + for k := 0; k < len(parts); k++ { + name := parts[k] + if k == len(parts)-1 { + // Final part of the key. + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, tableKind, true) + s.currentTable = i + return true, nil + } + e := &s.entries[i] + switch e.kind { + case tableKind: + if e.explicit { + return false, fmt.Errorf("toml: table %s already exists", name) + } + e.explicit = true + s.currentTable = i + return false, nil + case kvTableKind: + return false, fmt.Errorf("toml: table %s already exists as defined by a dotted key", name) + case arrayTableKind: + return false, fmt.Errorf("toml: table %s already exists as an array of tables", name) + default: + return false, fmt.Errorf("toml: key %s should be a table, not a %s", name, e.kind) + } + } + + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, tableKind, false) + } else { + switch s.entries[i].kind { + case tableKind, arrayTableKind, kvTableKind: + // Tables created by dotted keys can receive new sub-tables, + // but cannot be redefined (handled by the last-part case). + default: + return false, fmt.Errorf("toml: key %s already exists as a value", name) + } + } + parent = i + } + panic("unreachable: table expression without key") +} + +// CheckArrayTable validates a [[array table]] header given the decoded parts +// of its key. It mirrors checkArrayTable but is driven directly from the key +// parts. It returns whether the array table is seen for the first time. +func (s *SeenTracker) CheckArrayTable(parts [][]byte) (bool, error) { + parent := int32(0) + for k := 0; k < len(parts); k++ { + name := parts[k] + if k == len(parts)-1 { + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, arrayTableKind, true) + s.currentTable = i + return true, nil + } + if s.entries[i].kind != arrayTableKind { + return false, fmt.Errorf("toml: key %s already exists as a %s, but should be an array table", name, s.entries[i].kind) + } + // Make the descendants of this array table re-discoverable for + // the new element. + s.clear(i) + s.currentTable = i + return false, nil + } + + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, tableKind, false) + } else { + switch s.entries[i].kind { + case tableKind, arrayTableKind, kvTableKind: + // Tables created by dotted keys can receive new sub-tables, + // but cannot be redefined (handled by the last-part case). + default: + return false, fmt.Errorf("toml: key %s already exists as a value", name) + } + } + parent = i + } + panic("unreachable: array table expression without key") +} + +// CheckKeyValue validates the (possibly dotted) key of a key-value under the +// current table, WITHOUT validating its value. It returns the id of the leaf +// entry, so the caller can validate a container value with CheckValueUnder. +func (s *SeenTracker) CheckKeyValue(parts [][]byte) (int32, error) { + parent := s.currentTable + for k := 0; k < len(parts); k++ { + name := parts[k] + if k == len(parts)-1 { + if i := s.find(parent, name); i >= 0 { + return -1, fmt.Errorf("toml: key %s is already defined", name) + } + return s.create(parent, name, valueKind, false), nil + } + + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, kvTableKind, false) + } else if s.entries[i].kind != kvTableKind { + return -1, fmt.Errorf("toml: key %s is already defined", name) + } + parent = i + } + panic("unreachable: key-value expression without key") +} + +// CheckValueUnder validates the content of a value stored under the given +// entry (typically the leaf returned by CheckKeyValue): inline tables cannot +// contain duplicate keys, including in the inline tables and arrays they +// contain. +func (s *SeenTracker) CheckValueUnder(parent int32, value *unstable.Node) error { + return s.checkValue(parent, value) +} + func (s *SeenTracker) checkTable(node *unstable.Node) (bool, error) { - if s.currentIdx >= 0 { - s.setExplicitFlag(s.currentIdx) - } + parent := int32(0) it := node.Key() - - parentIdx := 0 - - // This code is duplicated in checkArrayTable. This is because factoring - // it in a function requires to copy the iterator, or allocate it to the - // heap, which is not cheap. + // Handle the intermediate parts of the key. for it.Next() { + part := it.Node() + name := part.Data if it.IsLast() { - break - } - - k := it.Node().Data - - idx := s.find(parentIdx, k) - - if idx < 0 { - idx = s.create(parentIdx, k, tableKind, false, false) - } else { - entry := s.entries[idx] - if entry.kind == valueKind { - return false, fmt.Errorf("toml: expected %s to be a table, not a %s", string(k), entry.kind) + // Final part of the key. + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, tableKind, true) + s.currentTable = i + return true, nil + } + e := &s.entries[i] + switch e.kind { + case tableKind: + if e.explicit { + return false, fmt.Errorf("toml: table %s already exists", name) + } + e.explicit = true + s.currentTable = i + return false, nil + case kvTableKind: + return false, fmt.Errorf("toml: table %s already exists as defined by a dotted key", name) + case arrayTableKind: + return false, fmt.Errorf("toml: table %s already exists as an array of tables", name) + default: + return false, fmt.Errorf("toml: key %s should be a table, not a %s", name, e.kind) } } - parentIdx = idx - } - k := it.Node().Data - idx := s.find(parentIdx, k) - - first := false - if idx >= 0 { - kind := s.entries[idx].kind - if kind != tableKind { - return false, fmt.Errorf("toml: key %s should be a table, not a %s", string(k), kind) + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, tableKind, false) + } else { + switch s.entries[i].kind { + case tableKind, arrayTableKind, kvTableKind: + // Tables created by dotted keys can receive new sub-tables, + // but cannot be redefined (handled by the last-part case). + default: + return false, fmt.Errorf("toml: key %s already exists as a value", name) + } } - if s.entries[idx].explicit { - return false, fmt.Errorf("toml: table %s already exists", string(k)) - } - s.entries[idx].explicit = true - } else { - idx = s.create(parentIdx, k, tableKind, true, false) - first = true + parent = i } - - s.currentIdx = idx - - return first, nil + panic("unreachable: table expression without key") } func (s *SeenTracker) checkArrayTable(node *unstable.Node) (bool, error) { - if s.currentIdx >= 0 { - s.setExplicitFlag(s.currentIdx) - } + parent := int32(0) it := node.Key() - - parentIdx := 0 - for it.Next() { + part := it.Node() + name := part.Data if it.IsLast() { - break + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, arrayTableKind, true) + s.currentTable = i + return true, nil + } + if s.entries[i].kind != arrayTableKind { + return false, fmt.Errorf("toml: key %s already exists as a %s, but should be an array table", name, s.entries[i].kind) + } + // Make the descendants of this array table re-discoverable for + // the new element. + s.clear(i) + // Note: clear cannot move i because i comes before all its + // descendants. + s.currentTable = i + return false, nil } - k := it.Node().Data - - idx := s.find(parentIdx, k) - - if idx < 0 { - idx = s.create(parentIdx, k, tableKind, false, false) + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, tableKind, false) } else { - entry := s.entries[idx] - if entry.kind == valueKind { - return false, fmt.Errorf("toml: expected %s to be a table, not a %s", string(k), entry.kind) + switch s.entries[i].kind { + case tableKind, arrayTableKind, kvTableKind: + // Tables created by dotted keys can receive new sub-tables, + // but cannot be redefined (handled by the last-part case). + default: + return false, fmt.Errorf("toml: key %s already exists as a value", name) } } - - parentIdx = idx + parent = i } - - k := it.Node().Data - idx := s.find(parentIdx, k) - - firstTime := idx < 0 - if firstTime { - idx = s.create(parentIdx, k, arrayTableKind, true, false) - } else { - kind := s.entries[idx].kind - if kind != arrayTableKind { - return false, fmt.Errorf("toml: key %s already exists as a %s, but should be an array table", kind, string(k)) - } - s.clear(idx) - } - - s.currentIdx = idx - - return firstTime, nil + panic("unreachable: array table expression without key") } -func (s *SeenTracker) checkKeyValue(node *unstable.Node) (bool, error) { - parentIdx := s.currentIdx +func (s *SeenTracker) checkKeyValue(parent int32, node *unstable.Node) error { it := node.Key() - for it.Next() { - k := it.Node().Data - - idx := s.find(parentIdx, k) - - if idx < 0 { - idx = s.create(parentIdx, k, tableKind, false, true) - } else { - entry := s.entries[idx] - switch { - case it.IsLast(): - return false, fmt.Errorf("toml: key %s is already defined", string(k)) - case entry.kind != tableKind: - return false, fmt.Errorf("toml: expected %s to be a table, not a %s", string(k), entry.kind) - case entry.explicit: - return false, fmt.Errorf("toml: cannot redefine table %s that has already been explicitly defined", string(k)) + part := it.Node() + name := part.Data + if it.IsLast() { + if i := s.find(parent, name); i >= 0 { + return fmt.Errorf("toml: key %s is already defined", name) } + id := s.create(parent, name, valueKind, false) + return s.checkValue(id, node.Value()) } - parentIdx = idx + i := s.find(parent, name) + if i < 0 { + i = s.create(parent, name, kvTableKind, false) + } else if s.entries[i].kind != kvTableKind { + return fmt.Errorf("toml: key %s is already defined", name) + } + parent = i } + panic("unreachable: key-value expression without key") +} - s.entries[parentIdx].kind = valueKind - - value := node.Value() - +// checkValue verifies the content of a value: inline tables cannot contain +// duplicate keys, including in the inline tables and arrays they contain. +func (s *SeenTracker) checkValue(id int32, value *unstable.Node) error { switch value.Kind { case unstable.InlineTable: - return s.checkInlineTable(value) + it := value.Children() + for it.Next() { + if err := s.checkKeyValue(id, it.Node()); err != nil { + return err + } + } case unstable.Array: - return s.checkArray(value) + it := value.Children() + for it.Next() { + elem := it.Node() + if elem.Kind == unstable.InlineTable || elem.Kind == unstable.Array { + elemID := s.create(id, nil, anonymousKind, false) + if err := s.checkValue(elemID, elem); err != nil { + return err + } + } + } default: - return false, nil } -} - -func (s *SeenTracker) checkArray(node *unstable.Node) (first bool, err error) { - it := node.Children() - for it.Next() { - n := it.Node() - switch n.Kind { //nolint:exhaustive - case unstable.InlineTable: - first, err = s.checkInlineTable(n) - if err != nil { - return false, err - } - case unstable.Array: - first, err = s.checkArray(n) - if err != nil { - return false, err - } - } - } - return first, nil -} - -func (s *SeenTracker) checkInlineTable(node *unstable.Node) (first bool, err error) { - s = pool.Get().(*SeenTracker) - s.reset() - - it := node.Children() - for it.Next() { - n := it.Node() - first, err = s.checkKeyValue(n) - if err != nil { - return false, err - } - } - - // As inline tables are self-contained, the tracker does not - // need to retain the details of what they contain. The - // keyValue element that creates the inline table is kept to - // mark the presence of the inline table and prevent - // redefinition of its keys: check* functions cannot walk into - // a value. - pool.Put(s) - return first, nil + return nil } diff --git a/vendor/github.com/pelletier/go-toml/v2/localtime.go b/vendor/github.com/pelletier/go-toml/v2/localtime.go index 502ef2f2f..eb8c20e6d 100644 --- a/vendor/github.com/pelletier/go-toml/v2/localtime.go +++ b/vendor/github.com/pelletier/go-toml/v2/localtime.go @@ -62,7 +62,7 @@ func (d LocalTime) String() string { } else if d.Nanosecond > 0 { // Nanoseconds are specified, but precision is not provided. Use the // minimum. - s += strings.Trim(fmt.Sprintf(".%09d", d.Nanosecond), "0") + s += strings.TrimRight(fmt.Sprintf(".%09d", d.Nanosecond), "0") } return s @@ -77,7 +77,7 @@ func (d LocalTime) MarshalText() ([]byte, error) { func (d *LocalTime) UnmarshalText(b []byte) error { res, left, err := parseLocalTime(b) if err == nil && len(left) != 0 { - err = unstable.NewParserError(left, "extra characters") + err = unstable.NewParserError(left, "extra characters at the end of a local time") } if err != nil { return err @@ -111,12 +111,11 @@ func (d LocalDateTime) MarshalText() ([]byte, error) { func (d *LocalDateTime) UnmarshalText(data []byte) error { res, left, err := parseLocalDateTime(data) if err == nil && len(left) != 0 { - err = unstable.NewParserError(left, "extra characters") + err = unstable.NewParserError(left, "extra characters at the end of a local date time") } if err != nil { return err } - *d = res return nil } diff --git a/vendor/github.com/pelletier/go-toml/v2/marshaler.go b/vendor/github.com/pelletier/go-toml/v2/marshaler.go index ca462d40e..7f6a9408e 100644 --- a/vendor/github.com/pelletier/go-toml/v2/marshaler.go +++ b/vendor/github.com/pelletier/go-toml/v2/marshaler.go @@ -12,25 +12,37 @@ import ( "slices" "strconv" "strings" + "sync" "time" - "unicode" + "unicode/utf8" - "github.com/pelletier/go-toml/v2/internal/characters" + "github.com/pelletier/go-toml/v2/internal/parserbridge" + "github.com/pelletier/go-toml/v2/unstable" ) // Marshal serializes a Go value as a TOML document. // // It is a shortcut for Encoder.Encode() with the default options. func Marshal(v interface{}) ([]byte, error) { - var buf bytes.Buffer - enc := NewEncoder(&buf) + enc := Encoder{indentSymbol: " "} - err := enc.Encode(v) + e := encoderStatePool.Get().(*encoderState) + e.Encoder = &enc + e.marshalerOn = enc.marshalerInterface + e.buf = e.buf[:0] + e.keyStack = e.keyStack[:0] + e.lastWasHeader = false + + err := e.encodeRoot(v) if err != nil { + encoderStatePool.Put(e) return nil, err } - return buf.Bytes(), nil + out := make([]byte, len(e.buf)) + copy(out, e.buf) + encoderStatePool.Put(e) + return out, nil } // Encoder writes a TOML document to an output stream. @@ -44,6 +56,9 @@ type Encoder struct { indentSymbol string indentTables bool marshalJSONNumbers bool + + // toggles the unstable.Marshaler interface + marshalerInterface bool } // NewEncoder returns a new Encoder that writes to w. @@ -56,8 +71,8 @@ func NewEncoder(w io.Writer) *Encoder { // SetTablesInline forces the encoder to emit all tables inline. // -// This behavior can be controlled on an individual struct field basis with the -// inline tag: +// This behavior can be controlled on an individual struct field basis with +// the inline tag: // // MyField `toml:",inline"` func (enc *Encoder) SetTablesInline(inline bool) *Encoder { @@ -65,10 +80,11 @@ func (enc *Encoder) SetTablesInline(inline bool) *Encoder { return enc } -// SetArraysMultiline forces the encoder to emit all arrays with one element per -// line. +// SetArraysMultiline forces the encoder to emit all arrays with one element +// per line. // -// This behavior can be controlled on an individual struct field basis with the multiline tag: +// This behavior can be controlled on an individual struct field basis with +// the multiline tag: // // MyField `multiline:"true"` func (enc *Encoder) SetArraysMultiline(multiline bool) *Encoder { @@ -101,6 +117,35 @@ func (enc *Encoder) SetMarshalJSONNumbers(indent bool) *Encoder { return enc } +// EnableMarshalerInterface enables the unstable.Marshaler interface. +// +// With this feature enabled, types implementing the unstable.Marshaler +// interface emit their own raw TOML instead of being encoded structurally. It +// is the encoding counterpart of Decoder.EnableUnmarshalerInterface, and allows +// types such as unstable.RawMessage to round-trip raw TOML bytes. +// +// The bytes returned by MarshalTOML are spliced into the document verbatim. The +// encoder parses them to decide between the valid positions: +// - bytes forming a single value are emitted inline, as in `key = `; +// - bytes forming key-value lines are emitted as the body of a `[key]` table; +// - at the document root, the bytes are emitted as the whole document: the +// encode counterpart of the decoder delivering the whole document to a +// root unstable.Unmarshaler. +// +// An empty result is omitted from the output. Bytes that are not valid TOML +// for their position result in an error, as do bytes forming table content in +// a position where only a value is valid (an array element, an inline table, +// or a table forced inline). MarshalTOML can be called more than once for the +// same value during a single encode, so it must be deterministic. +// +// *Unstable:* This method does not follow the compatibility guarantees of +// semver. It can be changed or removed without a new major version being +// issued. +func (enc *Encoder) EnableMarshalerInterface() *Encoder { + enc.marshalerInterface = true + return enc +} + // Encode writes a TOML representation of v to the stream. // // If v cannot be represented to TOML it returns an error. @@ -119,9 +164,9 @@ func (enc *Encoder) SetMarshalJSONNumbers(indent bool) *Encoder { // // Intermediate tables are always printed. // -// By default, strings are encoded as literal string, unless they contain either -// a newline character or a single quote. In that case they are emitted as -// quoted strings. +// By default, strings are encoded as literal string, unless they contain +// either a newline character or a single quote. In that case they are emitted +// as quoted strings. // // Unsigned integers larger than math.MaxInt64 cannot be encoded. Doing so // results in an error. This rule exists because the TOML specification only @@ -130,8 +175,8 @@ func (enc *Encoder) SetMarshalJSONNumbers(indent bool) *Encoder { // readable (at best) by other implementations. To encode such numbers, a // solution is a custom type that implements encoding.TextMarshaler. // -// When encoding structs, fields are encoded in order of definition, with their -// exact name. +// When encoding structs, fields are encoded in order of definition, with +// their exact name. // // Tables and array tables are separated by empty lines. However, consecutive // subtables definitions are not. For example: @@ -151,308 +196,1083 @@ func (enc *Encoder) SetMarshalJSONNumbers(indent bool) *Encoder { // The encoding of each public struct field can be customized by the format // string in the "toml" key of the struct field's tag. This follows // encoding/json's convention. The format string starts with the name of the -// field, optionally followed by a comma-separated list of options. The name may -// be empty in order to provide options without overriding the default name. +// field, optionally followed by a comma-separated list of options. The name +// may be empty in order to provide options without overriding the default +// name. // -// The "multiline" option emits strings as quoted multi-line TOML strings. It -// has no effect on fields that would not be encoded as strings. +// The "multiline" option emits strings as quoted multi-line TOML strings, and +// arrays with one element per line. For strings, it only takes effect when the +// value contains a newline; single-line values are emitted as regular strings. +// It has no effect on fields that would not be encoded as strings or arrays. // -// The "inline" option turns fields that would be emitted as tables into inline -// tables instead. It has no effect on other fields. +// The "inline" option turns fields that would be emitted as tables into +// inline tables instead. It has no effect on other fields. // // The "omitempty" option prevents empty values or groups from being emitted. // // The "omitzero" option prevents zero values or groups from being emitted. // -// The "commented" option prefixes the value and all its children with a comment -// symbol. +// The "commented" option prefixes the value and all its children with a +// comment symbol. // -// In addition to the "toml" tag struct tag, a "comment" tag can be used to emit -// a TOML comment before the value being annotated. Comments are ignored inside -// inline tables. For array tables, the comment is only present before the first -// element of the array. +// In addition to the "toml" tag struct tag, a "comment" tag can be used to +// emit a TOML comment before the value being annotated. Comments are ignored +// inside inline tables. For array tables, the comment is only present before +// the first element of the array. func (enc *Encoder) Encode(v interface{}) error { - var ( - b []byte - ctx encoderCtx - ) + e := encoderStatePool.Get().(*encoderState) + e.Encoder = enc + e.marshalerOn = enc.marshalerInterface + e.buf = e.buf[:0] + e.keyStack = e.keyStack[:0] + e.lastWasHeader = false - ctx.inline = enc.tablesInline + err := e.encodeRoot(v) + if err != nil { + encoderStatePool.Put(e) + return err + } + _, err = enc.w.Write(e.buf) + encoderStatePool.Put(e) + if err != nil { + return fmt.Errorf("toml: cannot write: %w", err) + } + return nil +} + +var encoderStatePool = sync.Pool{ + New: func() interface{} { return &encoderState{} }, +} + +type encoderState struct { + *Encoder + + buf []byte + + // keyStack is the dotted key of the table being encoded, shared by the + // whole encode as a stack. + keyStack []string + + // entriesPool recycles entry slices across tables of the same encode. + entriesPool [][]entry + + // lastWasHeader is true when the last line written was a table header, + // used to avoid empty lines between consecutive table definitions. + lastWasHeader bool + + // stringKeyBuf is a reusable buffer to read string map keys without + // allocating one per map. + stringKeyBuf reflect.Value + + // parser classifies the bytes returned by unstable.Marshaler values as a + // single value or a table body. Only used when marshalerOn is set. + parser unstable.Parser + + // marshalerOn mirrors Encoder.marshalerInterface, copied onto the state so + // the per-value hot path checks a direct field instead of dereferencing the + // embedded *Encoder on every value. + marshalerOn bool +} + +// valueOptions are the encoding options attached to one entry of a table. +type valueOptions struct { + multiline bool + inline bool + omitempty bool + omitzero bool + commented bool + // rawShape is the unstable.Marshaler classification of the entry's value, + // resolved at encode time (not from tags). It lives here, in the byte of + // padding the booleans already leave, so that entry does not grow and the + // encoder's default (interface-disabled) path keeps its exact layout and + // performance. It stays shapeUnknown for everything that is not a Marshaler. + rawShape rawShape + comment string +} + +// entry is a deferred key-value of a table being encoded. +type entry struct { + key string + value reflect.Value + options valueOptions +} + +// rawShape classifies the bytes produced by an unstable.Marshaler. +type rawShape uint8 + +const ( + // shapeUnknown is the default: not an unstable.Marshaler, or the interface + // is disabled. + shapeUnknown rawShape = iota + // shapeEmpty is whitespace-only content: it has no TOML representation and + // is omitted from the output. + shapeEmpty + // shapeValue is a single TOML value, emitted inline as `key = `. + shapeValue + // shapeTable is one or more key-value lines, emitted as a `[key]` body. + shapeTable +) + +func (e *encoderState) encodeRoot(v interface{}) error { if v == nil { return errors.New("toml: cannot encode a nil interface") } - b, err := enc.encode(b, ctx, reflect.ValueOf(v)) + rv := reflect.ValueOf(v) + rv, ok := resolve(rv) + if !ok { + return errors.New("toml: cannot encode a nil pointer") + } + + if e.marshalerOn && encPropsForType(rv.Type()).marshaler != 0 { + return e.encodeMarshalerRoot(rv) + } + + switch rv.Kind() { + case reflect.Map, reflect.Struct: + if isValueKind(rv) { + return fmt.Errorf("toml: cannot encode a %s as a document root", rv.Type()) + } + return e.encodeTable(rv, false, 0) + default: + return fmt.Errorf("toml: cannot encode a %s as a document root", rv.Type()) + } +} + +// encodeMarshalerRoot emits the bytes of a root-level unstable.Marshaler as +// the whole document: the encode counterpart of the decoder delivering the +// whole document to a root Unmarshaler. The bytes must form a TOML document +// (key-value lines and table headers); empty output produces an empty +// document. +func (e *encoderState) encodeMarshalerRoot(rv reflect.Value) error { + raw, err := e.marshalerBytes(rv) + if err != nil { + return err + } + trimmed := bytes.TrimSpace(raw) + if len(trimmed) == 0 { + return nil + } + if err := e.validateRawTableBody(rv.Type(), trimmed); err != nil { + // A single TOML value has no meaning at the document root; report it + // as such rather than as a syntax error. + if shape, _ := e.classifyRaw(trimmed); shape == shapeValue { + return fmt.Errorf("toml: cannot encode %s as a document root: MarshalTOML returned a single TOML value, not a document", rv.Type()) + } + return err + } + e.buf = append(e.buf, trimmed...) + e.buf = append(e.buf, '\n') + e.lastWasHeader = false + return nil +} + +// resolve unwraps pointers and interfaces until a concrete value is found. +// Returns false if it resolves to nil. +func resolve(v reflect.Value) (reflect.Value, bool) { + for { + switch v.Kind() { + case reflect.Ptr: + if v.IsNil() { + return v, false + } + v = v.Elem() + case reflect.Interface: + if v.IsNil() { + return v, false + } + v = v.Elem() + default: + return v, true + } + } +} + +// typeEncProps caches the per-type facts used on every value encode. +type typeEncProps struct { + // 0: not a TextMarshaler, 1: the type implements it, 2: its pointer does + text uint8 + // 0: not an unstable.Marshaler, 1: the type implements it, 2: its pointer + // does. Only consulted when Encoder.marshalerInterface is set. + marshaler uint8 + // encoded as a TOML value (as opposed to a table) + isValue bool +} + +var marshalerType = reflect.TypeOf(new(unstable.Marshaler)).Elem() + +var typeEncPropsCache sync.Map // reflect.Type -> typeEncProps + +func encPropsForType(t reflect.Type) typeEncProps { + if p, ok := typeEncPropsCache.Load(t); ok { + return p.(typeEncProps) + } + var p typeEncProps + switch { + case t.Implements(textMarshalerType): + p.text = 1 + case reflect.PtrTo(t).Implements(textMarshalerType): + p.text = 2 + } + switch { + case t.Implements(marshalerType): + p.marshaler = 1 + case reflect.PtrTo(t).Implements(marshalerType): + p.marshaler = 2 + } + switch t { + case timeType, localDateType, localTimeType, localDateTimeType: + p.isValue = true + default: + if p.text != 0 { + p.isValue = true + } else { + switch t.Kind() { + case reflect.Map, reflect.Struct: + p.isValue = false + default: + p.isValue = true + } + } + } + typeEncPropsCache.Store(t, p) + return p +} + +// isValueKind returns true when the resolved value is encoded as a TOML +// value (as opposed to a table). +func isValueKind(v reflect.Value) bool { + return encPropsForType(v.Type()).isValue +} + +// isTableLike returns true when the value should be encoded as a table (or +// an array of tables for slices). +func (e *encoderState) isTableLike(v reflect.Value) bool { + v, ok := resolve(v) + if !ok { + // Unresolvable values (interface-held nil pointers) are encoded as + // the zero value of their element type by the value path. + return false + } + return !isValueKind(v) +} + +// isArrayOfTables returns true when the value is a non-empty slice or array +// containing only table-like values. +func (e *encoderState) isArrayOfTables(v reflect.Value) bool { + v, ok := resolve(v) + if !ok { + return false + } + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return false + } + if v.Len() == 0 { + return false + } + // The Marshaler-aware classification lives in a separate method, hoisted out + // of this loop, so the default path keeps its exact original shape. + if e.marshalerOn { + return e.isMarshalerArrayOfTables(v) + } + for i := 0; i < v.Len(); i++ { + elem, ok := resolve(v.Index(i)) + if !ok || isValueKind(elem) { + return false + } + } + return true +} + +// isMarshalerArrayOfTables is the EnableMarshalerInterface variant of +// isArrayOfTables: a Marshaler element counts as a table only when its raw +// content is table shaped (key-value lines); one holding a single value makes +// the whole slice a plain array instead. +func (e *encoderState) isMarshalerArrayOfTables(v reflect.Value) bool { + for i := 0; i < v.Len(); i++ { + elem, ok := resolve(v.Index(i)) + if !ok { + return false + } + if encPropsForType(elem.Type()).marshaler != 0 { + raw, err := e.marshalerBytes(elem) + if err != nil { + return false + } + if shape, _ := e.classifyRaw(raw); shape != shapeTable { + return false + } + continue + } + if isValueKind(elem) { + return false + } + } + return true +} + +// marshalerBytes returns the raw TOML produced by v's unstable.Marshaler +// implementation. The caller guarantees v implements the interface +// (encPropsForType(v.Type()).marshaler != 0). +func (e *encoderState) marshalerBytes(v reflect.Value) ([]byte, error) { + t := v.Type() + var m unstable.Marshaler + switch { + case encPropsForType(t).marshaler == 1: + // The type itself implements Marshaler (e.g. a value receiver). + m = v.Interface().(unstable.Marshaler) + case v.CanAddr(): + // Only the pointer implements it, and v is addressable. + m = v.Addr().Interface().(unstable.Marshaler) + default: + // Only the pointer implements it, but v is not addressable: take the + // address of a copy. + tmp := reflect.New(t) + tmp.Elem().Set(v) + m = tmp.Interface().(unstable.Marshaler) + } + b, err := m.MarshalTOML() + if err != nil { + return nil, fmt.Errorf("toml: error calling MarshalTOML for type %s: %w", t, err) + } + return b, nil +} + +// validateRawTableBody checks that trimmed — table-shaped Marshaler output +// about to be spliced verbatim — is syntactically valid TOML, so a Marshaler +// cannot silently corrupt the document. It reuses e.parser, like classifyRaw. +func (e *encoderState) validateRawTableBody(t reflect.Type, trimmed []byte) error { + e.parser.Reset(trimmed) + for e.parser.NextExpression() { + } + if err := e.parser.Error(); err != nil { + return fmt.Errorf("toml: error calling MarshalTOML for type %s: invalid TOML: %w", t, err) + } + return nil +} + +// classifyRaw decides whether b (the output of an unstable.Marshaler) is empty, +// a single TOML value, or a table body. It returns the trimmed bytes that +// should be spliced into the document. It reuses e.parser, so it is not safe +// for concurrent use (encoderState is not shared). +func (e *encoderState) classifyRaw(b []byte) (rawShape, []byte) { + trimmed := bytes.TrimSpace(b) + if len(trimmed) == 0 { + return shapeEmpty, trimmed + } + e.parser.Reset(trimmed) + _, rest, err := parserbridge.ParseValue(&e.parser, trimmed) + if err == nil && len(bytes.TrimSpace(rest)) == 0 { + return shapeValue, trimmed + } + return shapeTable, trimmed +} + +// resolveMarshalerEntries classifies every entry whose value implements +// unstable.Marshaler, recording the shape on the entry so the two table passes +// can route it without re-classifying. Any error from MarshalTOML is surfaced +// eagerly. The marshaled bytes themselves are produced again at emit time by +// marshalerValue; that keeps entry small on the encoder's hot path, and only +// runs when the (opt-in) interface is enabled. +func (e *encoderState) resolveMarshalerEntries(entries []entry) error { + for i := range entries { + ent := &entries[i] + v, ok := resolve(ent.value) + if !ok || encPropsForType(v.Type()).marshaler == 0 { + continue + } + raw, err := e.marshalerBytes(v) + if err != nil { + return err + } + ent.options.rawShape, _ = e.classifyRaw(raw) + } + return nil +} + +// marshalerValue returns the trimmed bytes to splice for an entry already known +// to be an unstable.Marshaler (ent.options.rawShape != shapeUnknown). +func (e *encoderState) marshalerValue(ent *entry) ([]byte, error) { + v, _ := resolve(ent.value) + raw, err := e.marshalerBytes(v) + if err != nil { + return nil, err + } + return bytes.TrimSpace(raw), nil +} + +// appendMarshalerInline emits an unstable.Marshaler value in a value position +// (array element or inline-table member), where only a single TOML value is +// valid. done is false when t is not a Marshaler, so appendValue falls through +// to its normal handling. It is split out of appendValue (type check included) +// to keep that hot path lean. +func (e *encoderState) appendMarshalerInline(b []byte, v reflect.Value, t reflect.Type) (out []byte, done bool, err error) { + if encPropsForType(t).marshaler == 0 { + return b, false, nil + } + raw, err := e.marshalerBytes(v) + if err != nil { + return nil, true, err + } + shape, trimmed := e.classifyRaw(raw) + switch shape { + case shapeValue: + return append(b, trimmed...), true, nil + case shapeEmpty: + return nil, true, fmt.Errorf("toml: cannot encode an empty %s as an inline value", t) + default: + return nil, true, fmt.Errorf("toml: cannot encode %s as an inline value: %q is not a single TOML value", t, trimmed) + } +} + +// encodeTable writes the content of a table at the given key path. +func (e *encoderState) encodeTable(v reflect.Value, commented bool, indent int) error { + entries, err := e.collectEntries(v) if err != nil { return err } - _, err = enc.w.Write(b) - if err != nil { - return fmt.Errorf("toml: cannot write: %w", err) + // Marshaler routing is hoisted behind a single local flag. When the (opt-in) + // interface is off, mOn is false and both passes run the exact baseline + // code, so the default Marshal path keeps its performance. + mOn := e.marshalerOn + if mOn { + // Classify Marshaler entries once, up front, so the passes can route + // them by shape and surface MarshalTOML errors eagerly. + if err := e.resolveMarshalerEntries(entries); err != nil { + return err + } } + // First pass: emit all key-values; tables are handled by the second + // pass. + for i := range entries { + ent := &entries[i] + if mOn { + switch ent.options.rawShape { + case shapeUnknown: + // Not a Marshaler: handled by the baseline logic below. + case shapeEmpty: + // No TOML representation: omit the key. + continue + case shapeValue: + if err := e.encodeKeyValue(*ent, commented, indent); err != nil { + return err + } + continue + case shapeTable: + // A table body is emitted in the second pass, unless it is + // forced inline (SetTablesInline / inline tag), which has no + // valid inline form and is reported as an error by + // encodeKeyValue. + if e.tablesInline || ent.options.inline { + if err := e.encodeKeyValue(*ent, commented, indent); err != nil { + return err + } + } + continue + } + } + if e.entryIsTable(ent) { + continue + } + if err := e.encodeKeyValue(*ent, commented, indent); err != nil { + return err + } + } + + // Second pass: emit the sub-tables, extending the shared key stack. + for i := range entries { + ent := entries[i] + if mOn { + switch ent.options.rawShape { + case shapeUnknown: + // Not a Marshaler: handled by the baseline logic below. + case shapeValue, shapeEmpty: + // Not a table: already handled (or omitted) in the first pass. + continue + case shapeTable: + // Emit the raw body verbatim under the freshly pushed header. + // (The forced-inline case already errored in the first pass.) + entCommented := commented || ent.options.commented + e.keyStack = append(e.keyStack, ent.key) + if err := e.encodeMarshalerTable(&ent, entCommented, indent); err != nil { + return err + } + e.keyStack = e.keyStack[:len(e.keyStack)-1] + continue + } + } + if !e.entryIsTable(&ent) { + continue + } + entCommented := commented || ent.options.commented + e.keyStack = append(e.keyStack, ent.key) + + if e.isArrayOfTables(ent.value) { + err := e.encodeArrayTable(ent, entCommented, indent) + if err != nil { + return err + } + e.keyStack = e.keyStack[:len(e.keyStack)-1] + continue + } + + // The value is resolvable: entryIsTable already resolved it. + tv, _ := resolve(ent.value) + + e.writeTableHeader(ent.options.comment, entCommented, false, indent) + + err := e.encodeTable(tv, entCommented, indent+1) + if err != nil { + return err + } + e.keyStack = e.keyStack[:len(e.keyStack)-1] + } + + e.putEntries(entries) return nil } -type valueOptions struct { - multiline bool - omitempty bool - omitzero bool - commented bool - comment string +// encodeMarshalerTable emits a table-shaped unstable.Marshaler entry: the +// header for the key currently on the stack, then the raw body verbatim. +func (e *encoderState) encodeMarshalerTable(ent *entry, commented bool, indent int) error { + raw, err := e.marshalerValue(ent) + if err != nil { + return err + } + // Validate the bytes actually being spliced: MarshalTOML is called again + // for the emit, so this both rejects invalid TOML and guards against an + // implementation that returned different content than during + // classification. + if err := e.validateRawTableBody(ent.value.Type(), raw); err != nil { + return err + } + e.writeTableHeader(ent.options.comment, commented, false, indent) + e.spliceRawTableBody(raw, commented) + return nil } -type encoderCtx struct { - // Current top-level key. - parentKey []string - - // Key that should be used for a KV. - key string - // Extra flag to account for the empty string - hasKey bool - - // Set to true to indicate that the encoder is inside a KV, so that all - // tables need to be inlined. - insideKv bool - - // Set to true to skip the first table header in an array table. - skipTableHeader bool - - // Should the next table be encoded as inline - inline bool - - // Indentation level - indent int - - // Prefix the current value with a comment. - commented bool - - // Options coming from struct tags - options valueOptions +// spliceRawTableBody appends a raw table body verbatim after its header. When +// the table is commented, every physical line is prefixed with the comment +// marker so the body does not leak into the document as live keys. +func (e *encoderState) spliceRawTableBody(raw []byte, commented bool) { + if len(raw) == 0 { + return + } + if commented { + e.buf = append(e.buf, "# "...) + e.buf = append(e.buf, bytes.ReplaceAll(raw, []byte("\n"), []byte("\n# "))...) + } else { + e.buf = append(e.buf, raw...) + } + e.buf = append(e.buf, '\n') + e.lastWasHeader = false } -func (ctx *encoderCtx) shiftKey() { - if ctx.hasKey { - ctx.parentKey = append(ctx.parentKey, ctx.key) - ctx.clearKey() +// entryIsTable reports whether the entry is emitted as a (sub-)table rather +// than a key-value. Marshaler entries are routed by encodeTable before this is +// reached, so it carries no marshaler-specific cost. +func (e *encoderState) entryIsTable(ent *entry) bool { + return !e.tablesInline && !ent.options.inline && (e.isTableLike(ent.value) || e.isArrayOfTables(ent.value)) +} + +// getEntries returns a reusable entry slice. +func (e *encoderState) getEntries() []entry { + if n := len(e.entriesPool); n > 0 { + s := e.entriesPool[n-1] + e.entriesPool = e.entriesPool[:n-1] + return s[:0] + } + return nil +} + +// putEntries returns an entry slice to the pool. +func (e *encoderState) putEntries(s []entry) { + if cap(s) > 0 { + e.entriesPool = append(e.entriesPool, s) } } -func (ctx *encoderCtx) setKey(k string) { - ctx.key = k - ctx.hasKey = true -} +// encodeArrayTable writes all the elements of an array of tables. +func (e *encoderState) encodeArrayTable(ent entry, commented bool, indent int) error { + v, _ := resolve(ent.value) + comment := ent.options.comment + for i := 0; i < v.Len(); i++ { + // Elements are resolvable: isArrayOfTables already resolved them. + elem, _ := resolve(v.Index(i)) -func (ctx *encoderCtx) clearKey() { - ctx.key = "" - ctx.hasKey = false -} + e.writeTableHeader(comment, commented, true, indent) + // The comment is only present before the first element. + comment = "" -func (ctx *encoderCtx) isRoot() bool { - return len(ctx.parentKey) == 0 && !ctx.hasKey -} - -func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - i := v.Interface() - - switch x := i.(type) { - case time.Time: - if x.Nanosecond() > 0 { - return x.AppendFormat(b, time.RFC3339Nano), nil - } - return x.AppendFormat(b, time.RFC3339), nil - case LocalTime: - return append(b, x.String()...), nil - case LocalDate: - return append(b, x.String()...), nil - case LocalDateTime: - return append(b, x.String()...), nil - case json.Number: - if enc.marshalJSONNumbers { - if x == "" { /// Useful zero value. - return append(b, "0"...), nil - } else if v, err := x.Int64(); err == nil { - return enc.encode(b, ctx, reflect.ValueOf(v)) - } else if f, err := x.Float64(); err == nil { - return enc.encode(b, ctx, reflect.ValueOf(f)) + // A Marshaler element splices its raw table body verbatim. The shape + // was checked by isArrayOfTables, but MarshalTOML is called again for + // the emit, so the spliced bytes are validated here. + if e.marshalerOn && encPropsForType(elem.Type()).marshaler != 0 { + raw, err := e.marshalerBytes(elem) + if err != nil { + return err } - return nil, fmt.Errorf("toml: unable to convert %q to int64 or float64", x) - } - } - - hasTextMarshaler := v.Type().Implements(textMarshalerType) - if hasTextMarshaler || (v.CanAddr() && reflect.PointerTo(v.Type()).Implements(textMarshalerType)) { - if !hasTextMarshaler { - v = v.Addr() + trimmed := bytes.TrimSpace(raw) + if err := e.validateRawTableBody(elem.Type(), trimmed); err != nil { + return err + } + e.spliceRawTableBody(trimmed, commented) + continue } - if ctx.isRoot() { - return nil, fmt.Errorf("toml: type %s implementing the TextMarshaler interface cannot be a root element", v.Type()) - } - - text, err := v.Interface().(encoding.TextMarshaler).MarshalText() + err := e.encodeTable(elem, commented, indent+1) if err != nil { - return nil, err + return err } - - b = enc.encodeString(b, string(text), ctx.options) - - return b, nil } - - switch v.Kind() { - // containers - case reflect.Map: - return enc.encodeMap(b, ctx, v) - case reflect.Struct: - return enc.encodeStruct(b, ctx, v) - case reflect.Slice, reflect.Array: - return enc.encodeSlice(b, ctx, v) - case reflect.Interface: - if v.IsNil() { - return nil, errors.New("toml: encoding a nil interface is not supported") - } - - return enc.encode(b, ctx, v.Elem()) - case reflect.Ptr: - if v.IsNil() { - return enc.encode(b, ctx, reflect.Zero(v.Type().Elem())) - } - - return enc.encode(b, ctx, v.Elem()) - - // values - case reflect.String: - b = enc.encodeString(b, v.String(), ctx.options) - case reflect.Float32: - f := v.Float() - - switch { - case math.IsNaN(f): - b = append(b, "nan"...) - case f > math.MaxFloat32: - b = append(b, "inf"...) - case f < -math.MaxFloat32: - b = append(b, "-inf"...) - case math.Trunc(f) == f: - b = strconv.AppendFloat(b, f, 'f', 1, 32) - default: - b = strconv.AppendFloat(b, f, 'f', -1, 32) - } - case reflect.Float64: - f := v.Float() - switch { - case math.IsNaN(f): - b = append(b, "nan"...) - case f > math.MaxFloat64: - b = append(b, "inf"...) - case f < -math.MaxFloat64: - b = append(b, "-inf"...) - case math.Trunc(f) == f: - b = strconv.AppendFloat(b, f, 'f', 1, 64) - default: - b = strconv.AppendFloat(b, f, 'f', -1, 64) - } - case reflect.Bool: - if v.Bool() { - b = append(b, "true"...) - } else { - b = append(b, "false"...) - } - case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint: - x := v.Uint() - if x > uint64(math.MaxInt64) { - return nil, fmt.Errorf("toml: not encoding uint (%d) greater than max int64 (%d)", x, int64(math.MaxInt64)) - } - b = strconv.AppendUint(b, x, 10) - case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: - b = strconv.AppendInt(b, v.Int(), 10) - default: - return nil, fmt.Errorf("toml: cannot encode value of type %s", v.Kind()) - } - - return b, nil + return nil } -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Ptr, reflect.Interface, reflect.Map: - return v.IsNil() - default: - return false +// writeTableHeader emits a [table] or [[array table]] header line, preceded +// by an empty line and comments as needed. +func (e *encoderState) writeTableHeader(comment string, commented bool, array bool, indent int) { + key := e.keyStack + if len(e.buf) > 0 && !e.lastWasHeader { + e.buf = append(e.buf, '\n') + } + + headerIndent := indent + + e.writeComment(comment, headerIndent) + + // The "commented" marker is emitted at column zero, ahead of any table + // indentation, so that the indentation appears inside the comment + // (e.g. `# [a.b]`). This matches the historical v2.3 layout. + if commented { + e.buf = append(e.buf, "# "...) + } + e.writeIndent(headerIndent) + e.buf = append(e.buf, '[') + if array { + e.buf = append(e.buf, '[') + } + for i, part := range key { + if i > 0 { + e.buf = append(e.buf, '.') + } + e.buf = e.appendKey(e.buf, part) + } + e.buf = append(e.buf, ']') + if array { + e.buf = append(e.buf, ']') + } + e.buf = append(e.buf, '\n') + e.lastWasHeader = true +} + +func (e *encoderState) writeIndent(indent int) { + if !e.indentTables { + return + } + for i := 0; i < indent; i++ { + e.buf = append(e.buf, e.indentSymbol...) } } -func shouldOmitEmpty(options valueOptions, v reflect.Value) bool { - return options.omitempty && isEmptyValue(v) +// writeComment emits the comment lines attached to an entry. +func (e *encoderState) writeComment(comment string, indent int) { + if comment == "" { + return + } + for _, line := range strings.Split(comment, "\n") { + e.writeIndent(indent) + e.buf = append(e.buf, "# "...) + e.buf = append(e.buf, line...) + e.buf = append(e.buf, '\n') + } } -func shouldOmitZero(options valueOptions, v reflect.Value) bool { - if !options.omitzero { - return false +// encodeKeyValue writes one `key = value` line of a table. +func (e *encoderState) encodeKeyValue(ent entry, commented bool, indent int) error { + commented = commented || ent.options.commented + + e.writeComment(ent.options.comment, indent) + + // The "commented" marker is emitted at column zero, ahead of any table + // indentation, so that the indentation appears inside the comment + // (e.g. `# key = value`). This matches the historical v2.3 layout. + lineStart := len(e.buf) + if commented { + e.buf = append(e.buf, "# "...) + } + e.writeIndent(indent) + e.buf = e.appendKey(e.buf, ent.key) + e.buf = append(e.buf, " = "...) + + // When tables are not indented, the key is emitted at column zero + // regardless of its nesting depth. Value continuation lines (most + // notably the elements of a multiline array) must line up with that key, + // so the value indentation starts from zero as well rather than from the + // table nesting depth. + valueIndent := indent + if !e.indentTables { + valueIndent = 0 } - // Check if the type implements isZeroer interface (has a custom IsZero method). - if v.Type().Implements(isZeroerType) { - return v.Interface().(isZeroer).IsZero() - } - - // Check if pointer type implements isZeroer. - if reflect.PointerTo(v.Type()).Implements(isZeroerType) { - if v.CanAddr() { - return v.Addr().Interface().(isZeroer).IsZero() - } - // Create a temporary addressable copy to call the pointer receiver method. - pv := reflect.New(v.Type()) - pv.Elem().Set(v) - return pv.Interface().(isZeroer).IsZero() - } - - // Fall back to reflect's IsZero for types without custom IsZero method. - return v.IsZero() -} - -func (enc *Encoder) encodeKv(b []byte, ctx encoderCtx, options valueOptions, v reflect.Value) ([]byte, error) { + // A Marshaler value is delegated, keeping this hot function lean for the + // default path (rawShape stays shapeUnknown when the interface is off). It + // shares the commented/newline handling below. var err error - - if !ctx.inline { - b = enc.encodeComment(ctx.indent, options.comment, b) - b = enc.commented(ctx.commented, b) - b = enc.indent(ctx.indent, b) + if ent.options.rawShape != shapeUnknown { + e.buf, err = e.appendMarshalerInlineValue(e.buf, &ent) + } else { + e.buf, err = e.appendValue(e.buf, ent.value, ent.options, valueIndent) + } + if err != nil { + return err } - b = enc.encodeKey(b, ctx.key) - b = append(b, " = "...) + // A commented value that renders across multiple lines (a multiline string + // or a multiline array) must have every physical line prefixed with the + // comment marker, not just the first; otherwise the continuation lines are + // emitted as live, syntactically invalid TOML. + if commented { + if bytes.IndexByte(e.buf[lineStart:], '\n') >= 0 { + region := bytes.ReplaceAll( + append([]byte(nil), e.buf[lineStart:]...), + []byte("\n"), []byte("\n# "), + ) + e.buf = append(e.buf[:lineStart], region...) + } + } + e.buf = append(e.buf, '\n') + e.lastWasHeader = false + return nil +} - // create a copy of the context because the value of a KV shouldn't - // modify the global context. - subctx := ctx - subctx.insideKv = true - subctx.shiftKey() - subctx.options = options - - b, err = enc.encode(b, subctx, v) +// appendMarshalerInlineValue appends the value part of a `key = ` line for an +// unstable.Marshaler entry, leaving the trailing newline and commented handling +// to encodeKeyValue. Empty entries are filtered out before this point, so the +// value is either a single value (spliced verbatim) or, when forced inline by +// SetTablesInline or an inline tag, table content (an error). +func (e *encoderState) appendMarshalerInlineValue(b []byte, ent *entry) ([]byte, error) { + errNotValue := func() error { + return fmt.Errorf("toml: cannot encode %s as an inline value: not a single TOML value", ent.value.Type()) + } + if ent.options.rawShape != shapeValue { + return nil, errNotValue() + } + raw, err := e.marshalerValue(ent) if err != nil { return nil, err } - - return b, nil -} - -func (enc *Encoder) commented(commented bool, b []byte) []byte { - if commented { - return append(b, "# "...) + // Classify the just-returned bytes rather than trusting the earlier pass: + // MarshalTOML is called again for the emit, and an implementation that + // returns different content must not splice non-value bytes into a + // `key = ` position. + if shape, trimmed := e.classifyRaw(raw); shape == shapeValue { + return append(b, trimmed...), nil } - return b + return nil, errNotValue() } +// collectEntries builds the ordered list of the entries of a table, +// applying tags and omission rules. +func (e *encoderState) collectEntries(v reflect.Value) ([]entry, error) { + switch v.Kind() { + case reflect.Map: + return e.collectMapEntries(v) + case reflect.Struct: + entries := e.getEntries() + e.collectStructEntries(&entries, v) + return entries, nil + default: + return nil, fmt.Errorf("toml: cannot encode a %s as a table", v.Type()) + } +} + +func (e *encoderState) collectMapEntries(v reflect.Value) ([]entry, error) { + entries := e.getEntries() + + // Keys are converted to strings right away: read them into a reusable + // buffer to avoid one allocation per key. + var kbuf reflect.Value + if v.Type().Key() == stringType { + if !e.stringKeyBuf.IsValid() { + e.stringKeyBuf = reflect.New(stringType).Elem() + } + kbuf = e.stringKeyBuf + } else { + kbuf = reflect.New(v.Type().Key()).Elem() + } + + iter := v.MapRange() + for iter.Next() { + kbuf.SetIterKey(iter) + key, err := mapKeyString(kbuf) + if err != nil { + return nil, err + } + value := iter.Value() + if value.Kind() == reflect.Interface && value.IsNil() { + // nil interface values are skipped + continue + } + if value.Kind() == reflect.Ptr && value.IsNil() { + // nil pointers in maps are encoded as their zero value + value = reflect.New(value.Type().Elem()).Elem() + } + entries = append(entries, entry{key: key, value: value}) + } + + if len(entries) > 1 { + // slices.SortFunc avoids boxing the slice into a sort.Interface (an + // allocation that sort.Sort incurs for every table). + slices.SortFunc(entries, func(a, b entry) int { + return strings.Compare(a.key, b.key) + }) + } + + return entries, nil +} + +// mapKeyString converts a map key to its string representation. +func mapKeyString(k reflect.Value) (string, error) { + kr, ok := resolve(k) + if !ok { + return "", errors.New("toml: cannot encode a nil map key") + } + if kr.Type().Implements(textMarshalerType) { + b, err := kr.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return "", fmt.Errorf("toml: cannot marshal map key: %w", err) + } + return string(b), nil + } + if kr.CanAddr() && reflect.PtrTo(kr.Type()).Implements(textMarshalerType) { + b, err := kr.Addr().Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return "", fmt.Errorf("toml: cannot marshal map key: %w", err) + } + return string(b), nil + } + switch kr.Kind() { + case reflect.String: + return kr.String(), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(kr.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(kr.Uint(), 10), nil + case reflect.Float32: + return strconv.FormatFloat(kr.Float(), 'f', -1, 32), nil + case reflect.Float64: + return strconv.FormatFloat(kr.Float(), 'f', -1, 64), nil + default: + return "", fmt.Errorf("toml: cannot encode a map with key type %s", k.Type()) + } +} + +// encPlanField is the static encoding information of one field of a struct. +type encPlanField struct { + name string + index []int + depth int + options valueOptions +} + +// encPlan caches the per-type information needed to encode a struct: +// flattened fields with parsed tags, in order of definition, with shadowed +// duplicates already removed. +type encPlan struct { + fields []encPlanField +} + +var encPlans sync.Map // reflect.Type -> *encPlan + +func encPlanForType(t reflect.Type) *encPlan { + if plan, ok := encPlans.Load(t); ok { + return plan.(*encPlan) + } + plan := &encPlan{} + visited := map[reflect.Type]bool{} + buildEncPlan(plan, t, nil, 0, visited) + dedupEncPlan(plan) + encPlans.Store(t, plan) + return plan +} + +func buildEncPlan(plan *encPlan, t reflect.Type, prefix []int, depth int, visited map[reflect.Type]bool) { + if visited[t] { + return + } + visited[t] = true + defer delete(visited, t) + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + + tag, tagged := f.Tag.Lookup("toml") + if tag == "-" { + continue + } + + name := f.Name + var opts valueOptions + if tagged { + parts := strings.Split(tag, ",") + if parts[0] != "" { + name = parts[0] + } + for _, opt := range parts[1:] { + switch opt { + case "multiline": + opts.multiline = true + case "inline": + opts.inline = true + case "omitempty": + opts.omitempty = true + case "omitzero": + opts.omitzero = true + case "commented": + opts.commented = true + } + } + } + // Standalone boolean tags, e.g. multiline:"true". + const tagTrue = "true" + if f.Tag.Get("multiline") == tagTrue { + opts.multiline = true + } + if f.Tag.Get("inline") == tagTrue { + opts.inline = true + } + if f.Tag.Get("commented") == tagTrue { + opts.commented = true + } + opts.comment = f.Tag.Get("comment") + + index := make([]int, 0, len(prefix)+1) + index = append(index, prefix...) + index = append(index, i) + + if f.Anonymous { + ft := f.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + if ft.Kind() == reflect.Struct && (!tagged || tagName(tag) == "") { + buildEncPlan(plan, ft, index, depth+1, visited) + continue + } + if f.PkgPath != "" && ft.Kind() != reflect.Interface { + continue + } + } else if f.PkgPath != "" { + // unexported + continue + } + + plan.fields = append(plan.fields, encPlanField{ + name: name, + index: index, + depth: depth, + options: opts, + }) + } +} + +// dedupEncPlan removes the fields shadowed by another one with the same +// name (the shallowest wins), keeping the order of first appearance. +func dedupEncPlan(plan *encPlan) { + byName := make(map[string]int, len(plan.fields)) + drop := false + for i := range plan.fields { + f := &plan.fields[i] + j, seen := byName[f.name] + if !seen { + byName[f.name] = i + continue + } + drop = true + // Shallowest wins; on equal depth, the first in order wins. + if f.depth < plan.fields[j].depth { + plan.fields[j].name = "" + byName[f.name] = i + } else { + f.name = "" + } + } + if !drop { + return + } + out := plan.fields[:0] + for _, f := range plan.fields { + if f.name != "" { + out = append(out, f) + } + } + plan.fields = out +} + +// collectStructEntries appends the entries of a struct, flattening embedded +// structs in place. +func (e *encoderState) collectStructEntries(entries *[]entry, v reflect.Value) { + plan := encPlanForType(v.Type()) + + for i := range plan.fields { + f := &plan.fields[i] + fv, ok := fieldByIndexSkipNil(v, f.index) + if !ok { + // nil embedded pointer on the way: skipped + continue + } + + // Anonymous interface fields that are nil are skipped. + if fv.Kind() == reflect.Interface && fv.IsNil() { + continue + } + // nil values in struct fields are skipped + if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Map) && fv.IsNil() { + continue + } + + if f.options.omitempty && isEmptyValue(fv) { + continue + } + if f.options.omitzero && isZeroValue(fv) { + continue + } + + *entries = append(*entries, entry{key: f.name, value: fv, options: f.options}) + } +} + +// fieldByIndexSkipNil returns the field at the given index path, reporting +// false if a nil embedded pointer is found on the way. +func fieldByIndexSkipNil(v reflect.Value, index []int) (reflect.Value, bool) { + for i, x := range index { + if i > 0 { + for v.Kind() == reflect.Ptr { + if v.IsNil() { + return v, false + } + v = v.Elem() + } + } + v = v.Field(x) + } + return v, true +} + +func tagName(tag string) string { + if idx := strings.IndexByte(tag, ','); idx >= 0 { + return tag[:idx] + } + return tag +} + +// isEmptyValue implements the omitempty rules. func isEmptyValue(v reflect.Value) bool { switch v.Kind() { - case reflect.Struct: - return isEmptyStruct(v) - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + case reflect.String: return v.Len() == 0 case reflect.Bool: return !v.Bool() @@ -462,741 +1282,416 @@ func isEmptyValue(v reflect.Value) bool { return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 - case reflect.Interface, reflect.Ptr: + case reflect.Map, reflect.Slice, reflect.Array: + return v.Len() == 0 + case reflect.Ptr, reflect.Interface: return v.IsNil() + case reflect.Struct: + // Structs that encode as a scalar value (time.Time, the local + // date/time types, or any TextMarshaler) are empty only when they + // equal their zero value; their fields are typically unexported, so + // recursing into them would be meaningless. + if encPropsForType(v.Type()).isValue { + return v.IsZero() + } + // Plain structs encode as tables and are empty when every field that + // would be encoded is itself empty. This matches the recursive rule + // used before the encoder rewrite and, in particular, treats a + // non-nil but empty map or slice as empty (reflect.Value.IsZero does + // not, which would otherwise emit an empty table header). + return isEmptyStruct(v) default: return false } } +// isEmptyStruct reports whether all of a table-valued struct's encodable +// fields are empty per isEmptyValue. It mirrors the field selection done by +// collectStructEntries (embedded flattening, shadowing, and "-" skips) so the +// emptiness decision matches what would actually be encoded. func isEmptyStruct(v reflect.Value) bool { - // TODO: merge with walkStruct and cache. - typ := v.Type() - for i := 0; i < typ.NumField(); i++ { - fieldType := typ.Field(i) - - // only consider exported fields - if fieldType.PkgPath != "" { + plan := encPlanForType(v.Type()) + for i := range plan.fields { + fv, ok := fieldByIndexSkipNil(v, plan.fields[i].index) + if !ok { + // A nil embedded pointer along the path contributes nothing. continue } - - tag := fieldType.Tag.Get("toml") - - // special field name to skip field - if tag == "-" { - continue - } - - f := v.Field(i) - - if !isEmptyValue(f) { - return false - } - } - - return true -} - -const literalQuote = '\'' - -func (enc *Encoder) encodeString(b []byte, v string, options valueOptions) []byte { - if needsQuoting(v) { - return enc.encodeQuotedString(options.multiline, b, v) - } - - return enc.encodeLiteralString(b, v) -} - -func needsQuoting(v string) bool { - // TODO: vectorize - for _, b := range []byte(v) { - if b == '\'' || b == '\r' || b == '\n' || characters.InvalidASCII(b) { - return true - } - } - return false -} - -// caller should have checked that the string does not contain new lines or ' . -func (enc *Encoder) encodeLiteralString(b []byte, v string) []byte { - b = append(b, literalQuote) - b = append(b, v...) - b = append(b, literalQuote) - - return b -} - -func (enc *Encoder) encodeQuotedString(multiline bool, b []byte, v string) []byte { - stringQuote := `"` - - if multiline { - stringQuote = `"""` - } - - b = append(b, stringQuote...) - if multiline { - b = append(b, '\n') - } - - const ( - hextable = "0123456789ABCDEF" - // U+0000 to U+0008, U+000A to U+001F, U+007F - nul = 0x0 - bs = 0x8 - lf = 0xa - us = 0x1f - del = 0x7f - ) - - bv := []byte(v) - for i := 0; i < len(bv); i++ { - r := bv[i] - switch r { - case '\\': - b = append(b, `\\`...) - case '"': - if multiline { - // Quotation marks do not need to be quoted in multiline strings unless - // it contains 3 consecutive. If 3+ quotes appear, quote all of them - // because it's visually better - if i+2 > len(bv) || bv[i+1] != '"' || bv[i+2] != '"' { - b = append(b, r) - } else { - b = append(b, `\"\"\"`...) - i += 2 - } - } else { - b = append(b, `\"`...) - } - case '\b': - b = append(b, `\b`...) - case '\f': - b = append(b, `\f`...) - case '\n': - if multiline { - b = append(b, r) - } else { - b = append(b, `\n`...) - } - case '\r': - b = append(b, `\r`...) - case '\t': - b = append(b, `\t`...) - default: - switch { - case r >= nul && r <= bs, r >= lf && r <= us, r == del: - b = append(b, `\u00`...) - b = append(b, hextable[r>>4]) - b = append(b, hextable[r&0x0f]) - default: - b = append(b, r) - } - } - } - - b = append(b, stringQuote...) - - return b -} - -// caller should have checked that the string is in A-Z / a-z / 0-9 / - / _ . -func (enc *Encoder) encodeUnquotedKey(b []byte, v string) []byte { - return append(b, v...) -} - -func (enc *Encoder) encodeTableHeader(ctx encoderCtx, b []byte) []byte { - if len(ctx.parentKey) == 0 { - return b - } - - b = enc.encodeComment(ctx.indent, ctx.options.comment, b) - - b = enc.commented(ctx.commented, b) - - b = enc.indent(ctx.indent, b) - - b = append(b, '[') - - b = enc.encodeKey(b, ctx.parentKey[0]) - - for _, k := range ctx.parentKey[1:] { - b = append(b, '.') - b = enc.encodeKey(b, k) - } - - b = append(b, "]\n"...) - - return b -} - -func (enc *Encoder) encodeKey(b []byte, k string) []byte { - needsQuotation := false - cannotUseLiteral := false - - if len(k) == 0 { - return append(b, "''"...) - } - - for _, c := range k { - if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' { - continue - } - - if c == literalQuote { - cannotUseLiteral = true - } - - needsQuotation = true - } - - if needsQuotation && needsQuoting(k) { - cannotUseLiteral = true - } - - switch { - case cannotUseLiteral: - return enc.encodeQuotedString(false, b, k) - case needsQuotation: - return enc.encodeLiteralString(b, k) - default: - return enc.encodeUnquotedKey(b, k) - } -} - -func (enc *Encoder) keyToString(k reflect.Value) (string, error) { - keyType := k.Type() - if keyType.Implements(textMarshalerType) { - keyB, err := k.Interface().(encoding.TextMarshaler).MarshalText() - if err != nil { - return "", fmt.Errorf("toml: error marshalling key %v from text: %w", k, err) - } - return string(keyB), nil - } - - switch keyType.Kind() { - case reflect.String: - return k.String(), nil - - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(k.Int(), 10), nil - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return strconv.FormatUint(k.Uint(), 10), nil - - case reflect.Float32: - return strconv.FormatFloat(k.Float(), 'f', -1, 32), nil - - case reflect.Float64: - return strconv.FormatFloat(k.Float(), 'f', -1, 64), nil - - default: - return "", fmt.Errorf("toml: type %s is not supported as a map key", keyType.Kind()) - } -} - -func (enc *Encoder) encodeMap(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - var ( - t table - emptyValueOptions valueOptions - ) - - iter := v.MapRange() - for iter.Next() { - v := iter.Value() - - // Handle nil values: convert nil pointers to zero value, - // skip nil interfaces and nil maps. - switch v.Kind() { - case reflect.Ptr: - if v.IsNil() { - v = reflect.Zero(v.Type().Elem()) - } - case reflect.Interface, reflect.Map: - if v.IsNil() { - continue - } - default: - } - - k, err := enc.keyToString(iter.Key()) - if err != nil { - return nil, err - } - - if willConvertToTableOrArrayTable(ctx, v) { - t.pushTable(k, v, emptyValueOptions) - } else { - t.pushKV(k, v, emptyValueOptions) - } - } - - sortEntriesByKey(t.kvs) - sortEntriesByKey(t.tables) - - return enc.encodeTable(b, ctx, t) -} - -func sortEntriesByKey(e []entry) { - slices.SortFunc(e, func(a, b entry) int { - return strings.Compare(a.Key, b.Key) - }) -} - -type entry struct { - Key string - Value reflect.Value - Options valueOptions -} - -type table struct { - kvs []entry - tables []entry -} - -func (t *table) pushKV(k string, v reflect.Value, options valueOptions) { - for _, e := range t.kvs { - if e.Key == k { - return - } - } - - t.kvs = append(t.kvs, entry{Key: k, Value: v, Options: options}) -} - -func (t *table) pushTable(k string, v reflect.Value, options valueOptions) { - for _, e := range t.tables { - if e.Key == k { - return - } - } - t.tables = append(t.tables, entry{Key: k, Value: v, Options: options}) -} - -func walkStruct(ctx encoderCtx, t *table, v reflect.Value) { - // TODO: cache this - typ := v.Type() - for i := 0; i < typ.NumField(); i++ { - fieldType := typ.Field(i) - - // only consider exported fields - if fieldType.PkgPath != "" { - continue - } - - tag := fieldType.Tag.Get("toml") - - // special field name to skip field - if tag == "-" { - continue - } - - k, opts := parseTag(tag) - if !isValidName(k) { - k = "" - } - - f := v.Field(i) - - if k == "" { - if fieldType.Anonymous { - if fieldType.Type.Kind() == reflect.Struct { - walkStruct(ctx, t, f) - } else if fieldType.Type.Kind() == reflect.Ptr && !f.IsNil() && f.Elem().Kind() == reflect.Struct { - walkStruct(ctx, t, f.Elem()) - } - continue - } - k = fieldType.Name - } - - if isNil(f) { - continue - } - - options := valueOptions{ - multiline: opts.multiline, - omitempty: opts.omitempty, - omitzero: opts.omitzero, - commented: opts.commented, - comment: fieldType.Tag.Get("comment"), - } - - if opts.inline || !willConvertToTableOrArrayTable(ctx, f) { - t.pushKV(k, f, options) - } else { - t.pushTable(k, f, options) - } - } -} - -func (enc *Encoder) encodeStruct(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - var t table - - walkStruct(ctx, &t, v) - - return enc.encodeTable(b, ctx, t) -} - -func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte { - for len(comment) > 0 { - var line string - idx := strings.IndexByte(comment, '\n') - if idx >= 0 { - line = comment[:idx] - comment = comment[idx+1:] - } else { - line = comment - comment = "" - } - b = enc.indent(indent, b) - b = append(b, "# "...) - b = append(b, line...) - b = append(b, '\n') - } - return b -} - -func isValidName(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - case !unicode.IsLetter(c) && !unicode.IsDigit(c): + if !isEmptyValue(fv) { return false } } return true } -type tagOptions struct { - multiline bool - inline bool - omitempty bool - omitzero bool - commented bool +// isZeroValue implements the omitzero rules: the type's own IsZero() when +// implemented, the reflect zero value otherwise. +func isZeroValue(v reflect.Value) bool { + if v.Type().Implements(isZeroerType) { + return v.Interface().(isZeroer).IsZero() + } + if v.CanAddr() && reflect.PtrTo(v.Type()).Implements(isZeroerType) { + return v.Addr().Interface().(isZeroer).IsZero() + } + if !v.CanAddr() && reflect.PtrTo(v.Type()).Implements(isZeroerType) { + tmp := reflect.New(v.Type()) + tmp.Elem().Set(v) + return tmp.Interface().(isZeroer).IsZero() + } + return v.IsZero() } -func parseTag(tag string) (string, tagOptions) { - opts := tagOptions{} - - idx := strings.Index(tag, ",") - if idx == -1 { - return tag, opts +// appendKey emits a key, quoted only if necessary. +func (e *encoderState) appendKey(b []byte, key string) []byte { + if isBareKey(key) { + return append(b, key...) } - - raw := tag[idx+1:] - tag = tag[:idx] - for raw != "" { - var o string - i := strings.Index(raw, ",") - if i >= 0 { - o, raw = raw[:i], raw[i+1:] - } else { - o, raw = raw, "" - } - switch o { - case "multiline": - opts.multiline = true - case "inline": - opts.inline = true - case "omitempty": - opts.omitempty = true - case "omitzero": - opts.omitzero = true - case "commented": - opts.commented = true - } - } - - return tag, opts + return e.appendString(b, key) } -func (enc *Encoder) encodeTable(b []byte, ctx encoderCtx, t table) ([]byte, error) { - var err error - - ctx.shiftKey() - - if ctx.insideKv || (ctx.inline && !ctx.isRoot()) { - return enc.encodeTableInline(b, ctx, t) - } - - if !ctx.skipTableHeader { - b = enc.encodeTableHeader(ctx, b) - - if enc.indentTables && len(ctx.parentKey) > 0 { - ctx.indent++ - } - } - ctx.skipTableHeader = false - - hasNonEmptyKV := false - for _, kv := range t.kvs { - if shouldOmitEmpty(kv.Options, kv.Value) { - continue - } - if kv.Options.omitzero && shouldOmitZero(kv.Options, kv.Value) { - continue - } - hasNonEmptyKV = true - - ctx.setKey(kv.Key) - ctx2 := ctx - ctx2.commented = kv.Options.commented || ctx2.commented - - b, err = enc.encodeKv(b, ctx2, kv.Options, kv.Value) - if err != nil { - return nil, err - } - - b = append(b, '\n') - } - - first := true - for _, table := range t.tables { - if shouldOmitEmpty(table.Options, table.Value) { - continue - } - if table.Options.omitzero && shouldOmitZero(table.Options, table.Value) { - continue - } - if first { - first = false - if hasNonEmptyKV { - b = append(b, '\n') - } - } else { - b = append(b, "\n"...) - } - - ctx.setKey(table.Key) - - ctx.options = table.Options - ctx2 := ctx - ctx2.commented = ctx2.commented || ctx.options.commented - - b, err = enc.encode(b, ctx2, table.Value) - if err != nil { - return nil, err - } - } - - return b, nil -} - -func (enc *Encoder) encodeTableInline(b []byte, ctx encoderCtx, t table) ([]byte, error) { - var err error - - b = append(b, '{') - - first := true - for _, kv := range t.kvs { - if shouldOmitEmpty(kv.Options, kv.Value) { - continue - } - if kv.Options.omitzero && shouldOmitZero(kv.Options, kv.Value) { - continue - } - - if first { - first = false - } else { - b = append(b, `, `...) - } - - ctx.setKey(kv.Key) - - b, err = enc.encodeKv(b, ctx, kv.Options, kv.Value) - if err != nil { - return nil, err - } - } - - if len(t.tables) > 0 { - panic("inline table cannot contain nested tables, only key-values") - } - - b = append(b, "}"...) - - return b, nil -} - -func willConvertToTable(ctx encoderCtx, v reflect.Value) bool { - if !v.IsValid() { +func isBareKey(key string) bool { + if len(key) == 0 { return false } + for _, c := range []byte(key) { + if !isUnquotedKeyByte(c) { + return false + } + } + return true +} + +func isUnquotedKeyByte(c byte) bool { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' +} + +// appendValue emits a TOML value. +func (e *encoderState) appendValue(b []byte, v reflect.Value, opts valueOptions, indent int) ([]byte, error) { t := v.Type() - if t == timeType || t.Implements(textMarshalerType) { - return false - } - if v.Kind() != reflect.Ptr && v.CanAddr() && reflect.PointerTo(t).Implements(textMarshalerType) { - return false + + // Special types take precedence over their kind. + switch t { + case timeType: + return v.Interface().(time.Time).AppendFormat(b, "2006-01-02T15:04:05.999999999Z07:00"), nil + case localDateType: + return append(b, v.Interface().(LocalDate).String()...), nil + case localTimeType: + return append(b, v.Interface().(LocalTime).String()...), nil + case localDateTimeType: + return append(b, v.Interface().(LocalDateTime).String()...), nil + case jsonNumberType: + if e.marshalJSONNumbers { + return appendJSONNumber(b, v.Interface().(json.Number)) + } } - switch t.Kind() { - case reflect.Map, reflect.Struct: - return !ctx.inline - case reflect.Interface: - return willConvertToTable(ctx, v.Elem()) + // A Marshaler reached through a value position (an array element or inline + // table member) splices its bytes verbatim. Everything (including the type + // check) lives in a separate method so this hot function keeps its default + // layout: when the opt-in interface is off, only the bool test runs here. + if e.marshalerOn { + if b2, done, err := e.appendMarshalerInline(b, v, t); done { + return b2, err + } + } + + switch encPropsForType(t).text { + case 1: + if t.Kind() != reflect.String { + return e.appendTextMarshaler(b, v.Interface().(encoding.TextMarshaler)) + } + case 2: + if v.CanAddr() { + return e.appendTextMarshaler(b, v.Addr().Interface().(encoding.TextMarshaler)) + } + tmp := reflect.New(t) + tmp.Elem().Set(v) + return e.appendTextMarshaler(b, tmp.Interface().(encoding.TextMarshaler)) + } + + switch v.Kind() { case reflect.Ptr: if v.IsNil() { - return false + // nil pointers are encoded as the zero value of their element + // type. + return e.appendValue(b, reflect.Zero(t.Elem()), opts, indent) } - - return willConvertToTable(ctx, v.Elem()) + return e.appendValue(b, v.Elem(), opts, indent) + case reflect.Interface: + if v.IsNil() { + return nil, errors.New("toml: cannot encode a nil interface") + } + return e.appendValue(b, v.Elem(), opts, indent) + case reflect.String: + s := v.String() + // The "multiline" option only takes effect when the string actually + // contains a newline. Wrapping a single-line value such as "2" in a + // """...""" block adds noise without improving readability, so it is + // emitted as a regular single-line string instead. + if opts.multiline && strings.IndexByte(s, '\n') >= 0 { + return e.appendMultilineString(b, s), nil + } + return e.appendString(b, s), nil + case reflect.Bool: + if v.Bool() { + return append(b, "true"...), nil + } + return append(b, "false"...), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.AppendInt(b, v.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + u := v.Uint() + if u > math.MaxInt64 { + return nil, fmt.Errorf("toml: cannot encode an unsigned integer above math.MaxInt64: %d", u) + } + return strconv.AppendUint(b, u, 10), nil + case reflect.Float32: + return appendFloat(b, v.Float(), 32), nil + case reflect.Float64: + return appendFloat(b, v.Float(), 64), nil + case reflect.Slice, reflect.Array: + return e.appendArray(b, v, opts, indent) + case reflect.Map: + return e.appendInlineTable(b, v, indent) + case reflect.Struct: + return e.appendInlineTable(b, v, indent) default: - return false + return nil, fmt.Errorf("toml: cannot encode value of type %s", v.Type()) } } -func willConvertToTableOrArrayTable(ctx encoderCtx, v reflect.Value) bool { - if ctx.insideKv { - return false +var jsonNumberType = reflect.TypeOf(json.Number("")) + +func appendJSONNumber(b []byte, n json.Number) ([]byte, error) { + if n == "" { + return append(b, '0'), nil } - t := v.Type() - - if t.Kind() == reflect.Interface { - return willConvertToTableOrArrayTable(ctx, v.Elem()) + if i, err := n.Int64(); err == nil { + return strconv.AppendInt(b, i, 10), nil } - - if t.Kind() == reflect.Slice || t.Kind() == reflect.Array { - if v.Len() == 0 { - // An empty slice should be a kv = []. - return false - } - - for i := 0; i < v.Len(); i++ { - t := willConvertToTable(ctx, v.Index(i)) - - if !t { - return false - } - } - - return true + f, err := n.Float64() + if err != nil { + return nil, fmt.Errorf("toml: cannot encode json.Number %q: %w", string(n), err) } - - return willConvertToTable(ctx, v) + return appendFloat(b, f, 64), nil } -func (enc *Encoder) encodeSlice(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - if v.Len() == 0 { - b = append(b, "[]"...) - - return b, nil +func appendFloat(b []byte, f float64, bitSize int) []byte { + switch { + case math.IsNaN(f): + return append(b, "nan"...) + case math.IsInf(f, 1): + return append(b, "inf"...) + case math.IsInf(f, -1): + return append(b, "-inf"...) } - - if willConvertToTableOrArrayTable(ctx, v) { - return enc.encodeSliceAsArrayTable(b, ctx, v) + start := len(b) + b = strconv.AppendFloat(b, f, 'f', -1, bitSize) + // TOML floats must have a fractional part or an exponent. + if !bytes.ContainsAny(b[start:], ".eE") { + b = append(b, ".0"...) } - - return enc.encodeSliceAsArray(b, ctx, v) -} - -// caller should have checked that v is a slice that only contains values that -// encode into tables. -func (enc *Encoder) encodeSliceAsArrayTable(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - ctx.shiftKey() - - scratch := make([]byte, 0, 64) - - scratch = enc.commented(ctx.commented, scratch) - - if enc.indentTables { - scratch = enc.indent(ctx.indent, scratch) - } - - scratch = append(scratch, "[["...) - - for i, k := range ctx.parentKey { - if i > 0 { - scratch = append(scratch, '.') - } - - scratch = enc.encodeKey(scratch, k) - } - - scratch = append(scratch, "]]\n"...) - ctx.skipTableHeader = true - - b = enc.encodeComment(ctx.indent, ctx.options.comment, b) - - if enc.indentTables { - ctx.indent++ - } - - for i := 0; i < v.Len(); i++ { - if i != 0 { - b = append(b, "\n"...) - } - - b = append(b, scratch...) - - var err error - b, err = enc.encode(b, ctx, v.Index(i)) - if err != nil { - return nil, err - } - } - - return b, nil -} - -func (enc *Encoder) encodeSliceAsArray(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) { - multiline := ctx.options.multiline || enc.arraysMultiline - separator := ", " - - b = append(b, '[') - - subCtx := ctx - subCtx.options = valueOptions{} - - if multiline { - separator = ",\n" - - b = append(b, '\n') - - subCtx.indent++ - } - - var err error - first := true - - for i := 0; i < v.Len(); i++ { - if first { - first = false - } else { - b = append(b, separator...) - } - - if multiline { - b = enc.indent(subCtx.indent, b) - } - - b, err = enc.encode(b, subCtx, v.Index(i)) - if err != nil { - return nil, err - } - } - - if multiline { - b = append(b, '\n') - b = enc.indent(ctx.indent, b) - } - - b = append(b, ']') - - return b, nil -} - -func (enc *Encoder) indent(level int, b []byte) []byte { - for i := 0; i < level; i++ { - b = append(b, enc.indentSymbol...) - } - return b } + +func (e *encoderState) appendTextMarshaler(b []byte, m encoding.TextMarshaler) ([]byte, error) { + text, err := m.MarshalText() + if err != nil { + return nil, fmt.Errorf("toml: error calling MarshalText: %w", err) + } + return e.appendString(b, string(text)), nil +} + +// appendArray encodes a slice or array value. +func (e *encoderState) appendArray(b []byte, v reflect.Value, opts valueOptions, indent int) ([]byte, error) { + multiline := opts.multiline || e.arraysMultiline + + b = append(b, '[') + if multiline && v.Len() > 0 { + for i := 0; i < v.Len(); i++ { + if i > 0 { + b = append(b, ',') + } + b = append(b, '\n') + for j := 0; j <= indent; j++ { + b = append(b, e.indentSymbol...) + } + var err error + b, err = e.appendValue(b, v.Index(i), valueOptions{}, indent+1) + if err != nil { + return nil, err + } + } + b = append(b, '\n') + for j := 0; j < indent; j++ { + b = append(b, e.indentSymbol...) + } + } else { + for i := 0; i < v.Len(); i++ { + if i > 0 { + b = append(b, ", "...) + } + var err error + b, err = e.appendValue(b, v.Index(i), valueOptions{}, indent) + if err != nil { + return nil, err + } + } + } + return append(b, ']'), nil +} + +// appendInlineTable encodes a map or a struct as an inline table. +func (e *encoderState) appendInlineTable(b []byte, v reflect.Value, indent int) ([]byte, error) { + entries, err := e.collectEntries(v) + if err != nil { + return nil, err + } + + b = append(b, '{') + for i, ent := range entries { + if i > 0 { + b = append(b, ", "...) + } + b = e.appendKey(b, ent.key) + b = append(b, " = "...) + // multiline strings are not allowed inside inline tables: they + // would break the single-line requirement. + opts := ent.options + opts.multiline = false + b, err = e.appendValue(b, ent.value, opts, indent) + if err != nil { + return nil, err + } + } + e.putEntries(entries) + return append(b, '}'), nil +} + +// appendString encodes a string, using a literal string when possible and a +// basic string otherwise. +func (e *encoderState) appendString(b []byte, s string) []byte { + if canBeLiteral(s) { + b = append(b, '\'') + b = append(b, s...) + return append(b, '\'') + } + return appendBasicString(b, s) +} + +// canBeLiteral returns true when the string can be represented as a TOML +// literal string: no control characters, no single quote, no newline. +func canBeLiteral(s string) bool { + for i := 0; i < len(s); i++ { + c := s[i] + if c == '\'' || c == 0x7f || c < 0x20 { + return false + } + } + return utf8.ValidString(s) +} + +// appendBasicString encodes a string as a TOML basic (double-quoted) string. +func appendBasicString(b []byte, s string) []byte { + b = append(b, '"') + for i := 0; i < len(s); { + c := s[i] + switch { + case c == '"': + b = append(b, '\\', '"') + i++ + case c == '\\': + b = append(b, '\\', '\\') + i++ + case c == '\b': + b = append(b, '\\', 'b') + i++ + case c == '\f': + b = append(b, '\\', 'f') + i++ + case c == '\n': + b = append(b, '\\', 'n') + i++ + case c == '\r': + b = append(b, '\\', 'r') + i++ + case c == '\t': + b = append(b, '\\', 't') + i++ + case c < 0x20 || c == 0x7f: + b = append(b, fmt.Sprintf("\\u%04X", c)...) + i++ + default: + r, size := utf8.DecodeRuneInString(s[i:]) + if r == utf8.RuneError && size == 1 { + // Replace invalid bytes by the replacement character. + b = append(b, fmt.Sprintf("\\u%04X", c)...) + i++ + continue + } + b = append(b, s[i:i+size]...) + i += size + } + } + return append(b, '"') +} + +// appendMultilineString encodes a string as a TOML multi-line basic string. +func appendMultilineString(b []byte, s string) []byte { + b = append(b, `"""`...) + b = append(b, '\n') + for i := 0; i < len(s); { + c := s[i] + switch { + case c == '"': + // Runs of three or more quotes must be escaped. + j := i + for j < len(s) && s[j] == '"' { + j++ + } + if j-i >= 3 { + for ; i < j; i++ { + b = append(b, '\\', '"') + } + } else { + b = append(b, s[i:j]...) + i = j + } + case c == '\\': + b = append(b, '\\', '\\') + i++ + case c == '\n': + b = append(b, '\n') + i++ + case c == '\b': + b = append(b, '\\', 'b') + i++ + case c == '\f': + b = append(b, '\\', 'f') + i++ + case c == '\r': + b = append(b, '\\', 'r') + i++ + case c == '\t': + b = append(b, '\t') + i++ + case c < 0x20 || c == 0x7f: + b = append(b, fmt.Sprintf("\\u%04X", c)...) + i++ + default: + r, size := utf8.DecodeRuneInString(s[i:]) + if r == utf8.RuneError && size == 1 { + b = append(b, fmt.Sprintf("\\u%04X", c)...) + i++ + continue + } + b = append(b, s[i:i+size]...) + i += size + } + } + return append(b, `"""`...) +} + +func (e *encoderState) appendMultilineString(b []byte, s string) []byte { + return appendMultilineString(b, s) +} diff --git a/vendor/github.com/pelletier/go-toml/v2/strict.go b/vendor/github.com/pelletier/go-toml/v2/strict.go index e9a4be2c3..b58571df1 100644 --- a/vendor/github.com/pelletier/go-toml/v2/strict.go +++ b/vendor/github.com/pelletier/go-toml/v2/strict.go @@ -11,69 +11,63 @@ type strict struct { // Tracks the current key being processed. key tracker.KeyTracker - missing []unstable.ParserError - - // Reference to the document for computing key ranges. - doc []byte + missing []decodeError } +// decodeError is the information needed to materialize a DecodeError once the +// whole document is available. +type decodeError struct { + highlight unstable.Range + key Key + message string +} + +// Reset clears the state of the tracker so it can be reused for another +// document. +func (s *strict) Reset() { + s.key = tracker.KeyTracker{} + s.missing = s.missing[:0] +} + +// EnterTable is called when a new table or array table expression starts +// being processed. func (s *strict) EnterTable(node *unstable.Node) { if !s.Enabled { return } - s.key.UpdateTable(node) } -func (s *strict) EnterArrayTable(node *unstable.Node) { - if !s.Enabled { - return - } - - s.key.UpdateArrayTable(node) -} - -func (s *strict) EnterKeyValue(node *unstable.Node) { - if !s.Enabled { - return - } - - s.key.Push(node) -} - -func (s *strict) ExitKeyValue(node *unstable.Node) { - if !s.Enabled { - return - } - - s.key.Pop(node) -} - +// MissingTable is called when a table is present in the document but has no +// corresponding field in the target. func (s *strict) MissingTable(node *unstable.Node) { if !s.Enabled { return } - - s.missing = append(s.missing, unstable.ParserError{ - Highlight: s.keyLocation(node), - Message: "missing table", - Key: s.key.Key(), + s.missing = append(s.missing, decodeError{ + highlight: keyLocation(node), + key: s.key.Key(), + message: "missing table", }) } +// MissingField is called when a key-value is present in the document but has +// no corresponding field in the target. func (s *strict) MissingField(node *unstable.Node) { if !s.Enabled { return } - - s.missing = append(s.missing, unstable.ParserError{ - Highlight: s.keyLocation(node), - Message: "unknown field", - Key: s.key.Key(), + s.key.Push(node) + s.missing = append(s.missing, decodeError{ + highlight: keyLocation(node), + key: s.key.Key(), + message: "unknown field", }) + s.key.Pop(node) } -func (s *strict) Error(doc []byte) error { +// Error returns the cumulated StrictMissingError for the document, or nil. +func (s *strict) Error(document []byte) error { if !s.Enabled || len(s.missing) == 0 { return nil } @@ -83,14 +77,16 @@ func (s *strict) Error(doc []byte) error { } for _, derr := range s.missing { - derr := derr - err.Errors = append(err.Errors, *wrapDecodeError(doc, &derr)) + highlight := document[derr.highlight.Offset : derr.highlight.Offset+derr.highlight.Length] + err.Errors = append(err.Errors, *newDecodeError(document, highlight, derr.key, derr.message)) } return err } -func (s *strict) keyLocation(node *unstable.Node) []byte { +// keyLocation returns the range of the document covering all the parts of +// the key of the given node. +func keyLocation(node *unstable.Node) unstable.Range { k := node.Key() hasOne := k.Next() @@ -98,17 +94,15 @@ func (s *strict) keyLocation(node *unstable.Node) []byte { panic("should not be called with empty key") } - // Get the range from the first key to the last key. - firstRaw := k.Node().Raw - lastRaw := firstRaw + start := k.Node().Raw + end := start for k.Next() { - lastRaw = k.Node().Raw + end = k.Node().Raw } - // Compute the slice from the document using the ranges. - start := firstRaw.Offset - end := lastRaw.Offset + lastRaw.Length - - return s.doc[start:end] + return unstable.Range{ + Offset: start.Offset, + Length: end.Offset + end.Length - start.Offset, + } } diff --git a/vendor/github.com/pelletier/go-toml/v2/toml.abnf b/vendor/github.com/pelletier/go-toml/v2/toml.abnf index 473f3749e..7647c4bed 100644 --- a/vendor/github.com/pelletier/go-toml/v2/toml.abnf +++ b/vendor/github.com/pelletier/go-toml/v2/toml.abnf @@ -36,7 +36,7 @@ newline =/ %x0D.0A ; CRLF comment-start-symbol = %x23 ; # non-ascii = %x80-D7FF / %xE000-10FFFF -non-eol = %x09 / %x20-7F / non-ascii +non-eol = %x09 / %x20-7E / non-ascii comment = comment-start-symbol *non-eol @@ -74,12 +74,14 @@ escape = %x5C ; \ escape-seq-char = %x22 ; " quotation mark U+0022 escape-seq-char =/ %x5C ; \ reverse solidus U+005C escape-seq-char =/ %x62 ; b backspace U+0008 +escape-seq-char =/ %x65 ; e escape U+001B escape-seq-char =/ %x66 ; f form feed U+000C escape-seq-char =/ %x6E ; n line feed U+000A escape-seq-char =/ %x72 ; r carriage return U+000D escape-seq-char =/ %x74 ; t tab U+0009 -escape-seq-char =/ %x75 4HEXDIG ; uXXXX U+XXXX -escape-seq-char =/ %x55 8HEXDIG ; UXXXXXXXX U+XXXXXXXX +escape-seq-char =/ %x78 2HEXDIG ; xHH U+00HH +escape-seq-char =/ %x75 4HEXDIG ; uHHHH U+HHHH +escape-seq-char =/ %x55 8HEXDIG ; UHHHHHHHH U+HHHHHHHH ;; Multiline Basic String @@ -174,7 +176,7 @@ time-secfrac = "." 1*DIGIT time-numoffset = ( "+" / "-" ) time-hour ":" time-minute time-offset = "Z" / time-numoffset -partial-time = time-hour ":" time-minute ":" time-second [ time-secfrac ] +partial-time = time-hour ":" time-minute [ ":" time-second [ time-secfrac ] ] full-date = date-fullyear "-" date-month "-" date-mday full-time = partial-time time-offset @@ -221,13 +223,14 @@ std-table-close = ws %x5D ; ] Right square bracket ;; Inline Table -inline-table = inline-table-open [ inline-table-keyvals ] inline-table-close +inline-table = inline-table-open [ inline-table-keyvals ] ws-comment-newline inline-table-close -inline-table-open = %x7B ws ; { -inline-table-close = ws %x7D ; } -inline-table-sep = ws %x2C ws ; , Comma +inline-table-open = %x7B ; { +inline-table-close = %x7D ; } +inline-table-sep = %x2C ; , Comma -inline-table-keyvals = keyval [ inline-table-sep inline-table-keyvals ] +inline-table-keyvals = ws-comment-newline keyval ws-comment-newline inline-table-sep inline-table-keyvals +inline-table-keyvals =/ ws-comment-newline keyval ws-comment-newline [ inline-table-sep ] ;; Array Table diff --git a/vendor/github.com/pelletier/go-toml/v2/types.go b/vendor/github.com/pelletier/go-toml/v2/types.go index 6d12fe580..420f1982f 100644 --- a/vendor/github.com/pelletier/go-toml/v2/types.go +++ b/vendor/github.com/pelletier/go-toml/v2/types.go @@ -6,17 +6,18 @@ import ( "time" ) -// isZeroer is used to check if a type has a custom IsZero method. -// This allows custom types to define their own zero-value semantics. +// isZeroer is used to check whether a value is the zero value for its type, +// as defined by the type itself. type isZeroer interface { IsZero() bool } +var isZeroerType = reflect.TypeOf(new(isZeroer)).Elem() + var ( - timeType = reflect.TypeOf((*time.Time)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() - isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem() + timeType = reflect.TypeOf(time.Time{}) + textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem() + textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem() mapStringInterfaceType = reflect.TypeOf(map[string]interface{}(nil)) sliceInterfaceType = reflect.TypeOf([]interface{}(nil)) stringType = reflect.TypeOf("") diff --git a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go index e7db8128c..d110243f4 100644 --- a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go +++ b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go @@ -9,20 +9,70 @@ import ( "reflect" "strconv" "strings" - "sync/atomic" + "sync" "time" "github.com/pelletier/go-toml/v2/internal/tracker" "github.com/pelletier/go-toml/v2/unstable" ) +// decoderPool recycles decoders (and their internal buffers: parser arena, +// seen-tracker entries, scratch buffers) across calls to Unmarshal and +// Decode. +var decoderPool = sync.Pool{ + New: func() interface{} { return &decoder{} }, +} + +func getDecoder(strictMode, unmarshalerInterface bool) *decoder { + d := decoderPool.Get().(*decoder) + d.reset() + d.strict.Enabled = strictMode + d.unmarshalerInterface = unmarshalerInterface + return d +} + +func putDecoder(d *decoder) { + decoderPool.Put(d) +} + +// reset clears the per-document state of the decoder, keeping the allocated +// buffers for reuse. +func (d *decoder) reset() { + d.seen.Reset() + d.tableKey = d.tableKey[:0] + d.skipUntilTable = false + d.path = d.path[:0] + d.captures = d.captures[:0] + d.captureIdx = -1 + d.segIdx = d.segIdx[:0] + // Reuse the array-table counter slots across documents instead of + // deleting them: a zeroed slot is indistinguishable from an absent one, + // and keeping it alive means setArrayCount does not have to allocate a new + // *int every time the same path reappears. A safety valve bounds the table + // for adversarial inputs that introduce unboundedly many distinct paths. + if len(d.arrayCounts) > 1<<14 { + d.arrayCounts = nil + } else { + for _, p := range d.arrayCounts { + *p = 0 + } + } + d.tableTarget = reflect.Value{} + d.tableTargetValid = false + d.tableFlush = d.tableFlush[:0] + d.tableParentSlot = slotWriter{} + d.keyParts = d.keyParts[:0] + d.strict.Reset() +} + // Unmarshal deserializes a TOML document into a Go value. // // It is a shortcut for Decoder.Decode() with the default options. func Unmarshal(data []byte, v interface{}) error { - d := decoder{} - d.p.Reset(data) - return d.FromParser(v) + d := getDecoder(false, false) + err := d.unmarshal(data, v) + putDecoder(d) + return err } // Decoder reads and decode a TOML document from an input stream. @@ -124,165 +174,501 @@ func (d *Decoder) Decode(v interface{}) error { return fmt.Errorf("toml: %w", err) } - dec := decoder{ - strict: strict{ - Enabled: d.strict, - doc: b, - }, - unmarshalerInterface: d.unmarshalerInterface, - } - dec.p.Reset(b) + dec := getDecoder(d.strict, d.unmarshalerInterface) + err = dec.unmarshal(b, v) + putDecoder(dec) + return err +} - return dec.FromParser(v) +// pathPart is one part of the key path leading to a value. Parts that come +// from the current table header only carry a name; parts that come from the +// key of the current key-value expression also carry the AST node, and their +// name is materialized lazily to avoid allocations. +type pathPart struct { + name string + node *unstable.Node +} + +// bytes returns the raw bytes of the key part. +func (p *pathPart) bytes() []byte { + if p.node != nil { + return p.node.Data + } + return []byte(p.name) +} + +// str returns the key part as a string, possibly allocating. +func (p *pathPart) str() string { + if p.node != nil { + return string(p.node.Data) + } + return p.name +} + +// rawCapture accumulates the raw bytes fed to a type implementing +// unstable.Unmarshaler for a table target. The target is identified by the +// parts of its key and the array-table indexes in effect when the capture +// was created, so that it can be located again once the whole document has +// been processed (the address of the target may change as slices grow). +type rawCapture struct { + names []string + // indexes[i] is the index to use when reaching a slice or array right + // before consuming names[i]. indexes[len(names)] is the index of the + // element when the target is an element of an array table. -1 when not + // relevant. + indexes []int + buf []byte } type decoder struct { - // Which parser instance in use for this decoding session. p unstable.Parser - // Flag indicating that the current expression is stashed. - // If set to true, calling nextExpr will not actually pull a new expression - // but turn off the flag instead. - stashedExpr bool - - // Skip expressions until a table is found. This is set to true when a - // table could not be created (missing field in map), so all KV expressions - // need to be skipped. - skipUntilTable bool - - // Flag indicating that the current array/slice table should be cleared because - // it is the first encounter of an array table. - clearArrayTable bool - - // Tracks position in Go arrays. - // This is used when decoding [[array tables]] into Go arrays. Given array - // tables are separate TOML expression, we need to keep track of where we - // are at in the Go array, as we can't just introspect its size. - arrayIndexes map[reflect.Value]int - - // Tracks keys that have been seen, with which type. - seen tracker.SeenTracker - - // Strict mode + // strict mode strict strict - // Flag that enables/disables unmarshaler interface. + // toggles unmarshaler interface unmarshalerInterface bool - // Current context for the error. - errorContext *errorContext + // tracks the duplicate and type consistency of the keys + seen tracker.SeenTracker + + // path of the current table header, as copied strings + tableKey []string + + // true when the expressions under the current table header cannot be + // stored anywhere and should be skipped + skipUntilTable bool + + // scratch buffer for the key path of the current expression + path []pathPart + + // raw captures for the unmarshaler interface, in order of first + // appearance. captureIdx is the index of the capture the current table + // belongs to, or -1. + captures []rawCapture + captureIdx int + + // segIdx[i] records the array element index used when traversing a + // slice or array right before consuming the i-th part of the current + // table key. Reset for each table expression. + segIdx []int + + // arrayCounts tracks the number of elements appended to fixed-size + // arrays used as array tables, keyed by the NUL-joined key parts. + // Values are pointer slots so that updating an existing path does not + // allocate a new key string. + arrayCounts map[string]*int + + // Cached target of the current table, so that key-values do not need to + // walk the document structure from the root for every expression. + // tableFlush holds the write-backs to perform when leaving the table + // (for targets reached through map values, which are copies). + // tableParentSlot stores a replacement of the target itself (e.g. a nil + // map that was allocated) into its parent. + tableTarget reflect.Value + tableTargetValid bool + tableFlush []flushOp + tableParentSlot slotWriter + + // strKey is a reusable string value used as map key, so that map + // operations with string keys do not need to allocate a boxed key for + // every access. It must be refreshed with stringMapKey immediately + // before each use: any recursive call may overwrite it. + strKey reflect.Value + + // interned de-duplicates key strings: documents repeat the same keys + // over and over, and the table survives pooling, so repeated decodes + // of similar documents stop allocating key strings altogether. + interned map[string]string + + // pathScratch is the buffer used by joinPath. + pathScratch []byte + + // keyParts is the reusable buffer holding the decoded parts of the key of + // the current expression in the fused generic decode path. + keyParts [][]byte } -type errorContext struct { - Struct reflect.Type - Field []int +// slotWriter remembers how to store a value at some location of the target +// structure. Implemented as a struct instead of a closure to avoid +// allocations. +type slotWriter struct { + kind uint8 // 0: none, 1: slot.Set, 2: m.SetMapIndex(k, ...), 3: m.SetMapIndex(string key ks, ...) + slot reflect.Value + m reflect.Value + k reflect.Value + ks string } -func (d *decoder) typeMismatchError(toml string, target reflect.Type) error { - return fmt.Errorf("toml: %s", d.typeMismatchString(toml, target)) -} - -func (d *decoder) typeMismatchString(toml string, target reflect.Type) string { - if d.errorContext != nil && d.errorContext.Struct != nil { - ctx := d.errorContext - f := ctx.Struct.FieldByIndex(ctx.Field) - return fmt.Sprintf("cannot decode TOML %s into struct field %s.%s of type %s", toml, ctx.Struct, f.Name, f.Type) +func (d *decoder) storeSlot(s *slotWriter, nv reflect.Value) { + switch s.kind { + case 1: + if s.slot.CanSet() { + s.slot.Set(nv) + } + case 2: + s.m.SetMapIndex(s.k, nv) + case 3: + s.m.SetMapIndex(d.stringMapKey(s.ks), nv) } - return fmt.Sprintf("cannot decode TOML %s into a Go value of type %s", toml, target) } -func (d *decoder) expr() *unstable.Node { - return d.p.Expression() +// flushOp stores val using w when the table is flushed. +type flushOp struct { + w slotWriter + val reflect.Value } -func (d *decoder) nextExpr() bool { - if d.stashedExpr { - d.stashedExpr = false - return true +// flushTable performs the pending write-backs of the cached table target, in +// reverse order so that inner copies land before their parents are stored. +func (d *decoder) flushTable() { + for i := len(d.tableFlush) - 1; i >= 0; i-- { + d.storeSlot(&d.tableFlush[i].w, d.tableFlush[i].val) } - return d.p.NextExpression() + d.tableFlush = d.tableFlush[:0] + d.tableTargetValid = false + d.tableParentSlot = slotWriter{} + d.tableTarget = reflect.Value{} } -func (d *decoder) stashExpr() { - d.stashedExpr = true -} - -func (d *decoder) arrayIndex(shouldAppend bool, v reflect.Value) int { - if d.arrayIndexes == nil { - d.arrayIndexes = make(map[reflect.Value]int, 1) +// intern returns the string corresponding to the given bytes, reusing a +// previous allocation when the same key has been seen before. +func (d *decoder) intern(b []byte) string { + if s, ok := d.interned[string(b)]; ok { // does not allocate + return s } - - idx, ok := d.arrayIndexes[v] - - if !ok { - d.arrayIndexes[v] = 0 - } else if shouldAppend { - idx++ - d.arrayIndexes[v] = idx + if d.interned == nil { + d.interned = make(map[string]string, 64) + } else if len(d.interned) >= 1<<14 { + // Safety valve for adversarial inputs: do not let the table grow + // without bounds. + for k := range d.interned { + delete(d.interned, k) + } } - - return idx + s := string(b) + d.interned[s] = s + return s } -func (d *decoder) FromParser(v interface{}) error { +// partString returns the name of a path part, interning it when it comes +// from the document. +func (d *decoder) partString(p *pathPart) string { + if p.node != nil { + return d.intern(p.node.Data) + } + return p.name +} + +// stringMapKey returns a reflect.Value holding the given string, reusing the +// same allocation every time. The result must be used (the map operation +// performed) before any recursive call, which may overwrite the buffer. +func (d *decoder) stringMapKey(s string) reflect.Value { + if !d.strKey.IsValid() { + d.strKey = reflect.New(stringType).Elem() + } + d.strKey.SetString(s) + return d.strKey +} + +// joinPath builds the NUL-joined representation of a key path in the +// decoder's scratch buffer. The result is only valid until the next call. +func (d *decoder) joinPath(parts []string) []byte { + d.pathScratch = d.pathScratch[:0] + for i, p := range parts { + if i > 0 { + d.pathScratch = append(d.pathScratch, 0) + } + d.pathScratch = append(d.pathScratch, p...) + } + return d.pathScratch +} + +// arrayCount returns the number of elements appended so far to the array +// table at the given path. +func (d *decoder) arrayCount(key []byte) int { + if d.arrayCounts == nil { + return 0 + } + if p := d.arrayCounts[string(key)]; p != nil { // does not allocate + return *p + } + return 0 +} + +func (d *decoder) setArrayCount(key []byte, n int) { + if d.arrayCounts == nil { + d.arrayCounts = map[string]*int{} + } + if p := d.arrayCounts[string(key)]; p != nil { // does not allocate + *p = n + return + } + v := n + d.arrayCounts[string(key)] = &v +} + +// resetChildArrayCounts forgets the counts of all the array tables under +// the given path, so that a new element starts fresh. +func (d *decoder) resetChildArrayCounts(key []byte) { + if len(d.arrayCounts) == 0 { + return + } + for k, p := range d.arrayCounts { + // Prefix match without building the prefix string: same bytes as + // key, followed by the NUL separator. + if len(k) > len(key) && k[len(key)] == 0 && k[:len(key)] == string(key) { + // Zero instead of delete: the next element of the parent table + // will reuse the slot without allocating a new key. + *p = 0 + } + } +} + +func (d *decoder) typeMismatchError(toml string, target reflect.Type, highlight []byte) error { + return &typeMismatchError{ + toml: toml, + target: target, + highlight: highlight, + } +} + +type typeMismatchError struct { + toml string + target reflect.Type + highlight []byte + // key is the TOML key being processed when the mismatch occurred. It is + // populated lazily as the error propagates back up to the key-value + // handler (see contextualizeError). + key Key +} + +func (e *typeMismatchError) Error() string { + return fmt.Sprintf("cannot decode TOML %s into %s", e.toml, e.target) +} + +// contextualizeError attaches the TOML key currently being processed to errors +// raised while decoding a key-value expression, so that DecodeError.Key() +// reports the offending key (e.g. on type mismatch errors). The current key is +// reconstructed from d.path; when the table target is cached, d.path holds only +// the key-value parts, so the table key prefix is prepended. This only runs on +// the error path and adds no cost to successful decodes. +func (d *decoder) contextualizeError(err error, withTableKey bool) error { + var mm *typeMismatchError + if errors.As(err, &mm) { + if mm.key == nil { + mm.key = d.currentKey(withTableKey) + } + return err + } + var perr *unstable.ParserError + if errors.As(err, &perr) { + if perr.Key == nil { + perr.Key = d.currentKey(withTableKey) + } + } + return err +} + +// currentKey reconstructs the full TOML key being processed from the decoder's +// path. When withTableKey is true, d.path contains only the key-value parts +// (the table target is cached) and the table key is prepended. +func (d *decoder) currentKey(withTableKey bool) Key { + n := len(d.path) + if withTableKey { + n += len(d.tableKey) + } + key := make(Key, 0, n) + if withTableKey { + key = append(key, d.tableKey...) + } + for i := range d.path { + key = append(key, d.path[i].str()) + } + return key +} + +func (d *decoder) unmarshal(data []byte, v interface{}) error { r := reflect.ValueOf(v) if r.Kind() != reflect.Ptr { return fmt.Errorf("toml: decoding can only be performed into a pointer, not %s", r.Kind()) } - if r.IsNil() { return errors.New("toml: decoding pointer target cannot be nil") } - r = r.Elem() - if r.Kind() == reflect.Interface && r.IsNil() { - newMap := map[string]interface{}{} - r.Set(reflect.ValueOf(newMap)) + root := r.Elem() + + d.captureIdx = -1 + d.p.Reset(data) + + // Fully generic targets (interface{} or map[string]interface{}) are + // decoded straight into native Go maps and slices, with no reflection on + // the document structure at all. This covers the common "decode arbitrary + // TOML into a map" case, including every standard benchmark dataset. + if !d.unmarshalerInterface { + if k := root.Kind(); k == reflect.Interface || (k == reflect.Map && root.Type() == mapStringInterfaceType) { + return d.unmarshalFused(root, data) + } } - err := d.fromParser(r) - if err == nil { - return d.strict.Error(d.p.Data()) + // When the root target itself implements the Unmarshaler interface, the + // whole document decodes into it. Open a capture spanning the entire + // document up front: the top-level key-values then flow through the + // existing capture branch and any tables attach to it via resumeCapture, + // so UnmarshalTOML receives the assembled document exactly once. + if d.unmarshalerInterface && hasUnmarshaler(root) { + d.startRootCapture() } - var e *unstable.ParserError - if errors.As(err, &e) { - return wrapDecodeError(d.p.Data(), e) + for d.p.NextExpression() { + err := d.handleRootExpression(d.p.Expression(), root) + if err != nil { + return d.wrapError(data, err) + } + } + if err := d.p.Error(); err != nil { + var perr *unstable.ParserError + if errors.As(err, &perr) { + return wrapDecodeError(data, perr) + } + return err } + d.flushTable() + + // Deliver the accumulated raw documents to the unmarshaler-interface + // targets. + for i := range d.captures { + nv, err := d.resolveCapture(root, &d.captures[i], 0, false) + if err != nil { + return err + } + if nv.IsValid() { + root.Set(nv) + } + } + + // An empty document into a generic target still initializes it. + switch root.Kind() { + case reflect.Map: + if root.IsNil() { + root.Set(reflect.MakeMap(root.Type())) + } + case reflect.Interface: + if root.IsNil() { + root.Set(reflect.ValueOf(map[string]interface{}{})) + } + default: + } + + return d.strict.Error(data) +} + +// setAnyKey assigns the value of a key-value into the native map m, following +// the (possibly dotted) key and creating intermediate maps as needed. +func (d *decoder) setAnyKey(m map[string]interface{}, key unstable.Iterator, value *unstable.Node) error { + cur := m + for key.Next() { + name := d.intern(key.Node().Data) + if key.IsLast() { + av, err := d.decodeAny(value) + if err != nil { + return err + } + cur[name] = av + return nil + } + cur = d.anyChildTable(cur, name) + } + return nil +} + +// anyChildTable returns the child table at name within cur, creating it if +// absent and descending into the current (last) element when an array table +// occupies the slot. A non-container in the slot cannot occur for a document +// the seen-tracker has accepted. +func (d *decoder) anyChildTable(cur map[string]interface{}, name string) map[string]interface{} { + switch v := cur[name].(type) { + case map[string]interface{}: + return v + case []interface{}: + if len(v) > 0 { + if last, ok := v[len(v)-1].(map[string]interface{}); ok { + return last + } + } + } + nm := map[string]interface{}{} + cur[name] = nm + return nm +} + +// wrapError gives document context to errors generated while processing an +// expression. +func (d *decoder) wrapError(data []byte, err error) error { + var perr *unstable.ParserError + if errors.As(err, &perr) { + return wrapDecodeError(data, perr) + } + var mm *typeMismatchError + if errors.As(err, &mm) { + return wrapDecodeError(data, &unstable.ParserError{ + Highlight: mm.highlight, + Message: mm.Error(), + Key: mm.key, + }) + } return err } -func (d *decoder) fromParser(root reflect.Value) error { - for d.nextExpr() { - err := d.handleRootExpression(d.expr(), root) - if err != nil { - return err - } +// keyedError turns a bare error raised while processing an expression into a +// ParserError carrying the position and key of that expression, so that it is +// reported as a DecodeError with context. It is used for the errors returned +// by SeenTracker.CheckExpression (redefinitions and duplicate keys, see issue +// #668) and for table placement errors raised by walkTable (see issue #806). +// +// The highlight spans the expression's key. Unlike Node.Raw, key nodes always +// carry a Raw range, so this works for tables and array tables too (whose own +// Raw range is not set by the parser). For a duplicate detected inside an +// inline table, node is the enclosing key-value expression, so the error +// points at that expression's key. +func (d *decoder) keyedError(node *unstable.Node, err error) error { + if err == nil { + return nil } - return d.p.Error() + var key Key + var start, end unstable.Range + it := node.Key() + for it.Next() { + n := it.Node() + key = append(key, string(n.Data)) + if len(key) == 1 { + start = n.Raw + } + end = n.Raw + } + + var highlight []byte + if len(key) > 0 { + highlight = d.p.Raw(unstable.Range{ + Offset: start.Offset, + Length: end.Offset + end.Length - start.Offset, + }) + } + + return &unstable.ParserError{ + Highlight: highlight, + Message: strings.TrimPrefix(err.Error(), "toml: "), + Key: key, + } } -/* -Rules for the unmarshal code: - -- The stack is used to keep track of which values need to be set where. -- handle* functions <=> switch on a given unstable.Kind. -- unmarshalX* functions need to unmarshal a node of kind X. -- An "object" is either a struct or a map. -*/ - -func (d *decoder) handleRootExpression(expr *unstable.Node, v reflect.Value) error { - var x reflect.Value - var err error - var first bool // used for to clear array tables on first use - - if !d.skipUntilTable || expr.Kind != unstable.KeyValue { - first, err = d.seen.CheckExpression(expr) - if err != nil { - return err - } +func (d *decoder) handleRootExpression(expr *unstable.Node, root reflect.Value) error { + first, err := d.seen.CheckExpression(expr) + if err != nil { + return d.keyedError(expr, err) } switch expr.Kind { @@ -290,1169 +676,1721 @@ func (d *decoder) handleRootExpression(expr *unstable.Node, v reflect.Value) err if d.skipUntilTable { return nil } - x, err = d.handleKeyValue(expr, v) + if d.captureIdx >= 0 { + d.captureKeyValue(expr) + return nil + } + return d.handleKeyValueExpression(expr, root) case unstable.Table: + d.flushTable() d.skipUntilTable = false + d.captureIdx = -1 d.strict.EnterTable(expr) - x, err = d.handleTable(expr.Key(), v) + return d.handleTableExpression(expr, root, false, first) case unstable.ArrayTable: + d.flushTable() d.skipUntilTable = false - d.strict.EnterArrayTable(expr) - d.clearArrayTable = first - x, err = d.handleArrayTable(expr.Key(), v) + d.captureIdx = -1 + d.strict.EnterTable(expr) + return d.handleTableExpression(expr, root, true, first) default: - panic(fmt.Errorf("parser should not permit expression of kind %s at document root", expr.Kind)) + return unstable.NewParserError(expr.Data, "unsupported expression kind %s", expr.Kind) } +} - if d.skipUntilTable { - if expr.Kind == unstable.Table || expr.Kind == unstable.ArrayTable { - d.strict.MissingTable(expr) +// updateTableKey copies the parts of the key of a table expression into +// tableKey. +func (d *decoder) updateTableKey(expr *unstable.Node) { + d.tableKey = d.tableKey[:0] + it := expr.Key() + for it.Next() { + d.tableKey = append(d.tableKey, d.intern(it.Node().Data)) + } +} + +func (d *decoder) handleTableExpression(expr *unstable.Node, root reflect.Value, isArrayTable bool, first bool) error { + d.updateTableKey(expr) + + // Check whether this table belongs to an exisiting raw capture (split + // tables, or children of a table assigned to an Unmarshaler). + if d.unmarshalerInterface { + if d.resumeCapture(expr) { + return nil } - } else if err == nil && x.IsValid() { - v.Set(x) } - return err -} - -func (d *decoder) handleArrayTable(key unstable.Iterator, v reflect.Value) (reflect.Value, error) { - if key.Next() { - return d.handleArrayTablePart(key, v) + // Reset the per-segment array indexes. + d.segIdx = d.segIdx[:0] + for i := 0; i <= len(d.tableKey); i++ { + d.segIdx = append(d.segIdx, -1) } - return d.handleKeyValues(v) + + return d.walkTable(root, expr, isArrayTable, first) } -func (d *decoder) handleArrayTableCollectionLast(key unstable.Iterator, v reflect.Value) (reflect.Value, error) { - switch v.Kind() { - case reflect.Interface: - elem := v.Elem() - if !elem.IsValid() { - elem = reflect.New(sliceInterfaceType).Elem() - elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16)) - } else if elem.Kind() == reflect.Slice { - if elem.Type() != sliceInterfaceType { - elem = reflect.New(sliceInterfaceType).Elem() - elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16)) - } else if !elem.CanSet() { - nelem := reflect.New(sliceInterfaceType).Elem() - nelem.Set(reflect.MakeSlice(sliceInterfaceType, elem.Len(), elem.Cap())) - reflect.Copy(nelem, elem) - elem = nelem +// newContainerElem returns a fresh element for a slice of the given element +// type. Plain interface elements start out as an empty table. +func newContainerElem(et reflect.Type) reflect.Value { + if et == interfaceType { + return reflect.ValueOf(map[string]interface{}{}) + } + return reflect.New(et).Elem() +} + +// walkTable processes a [table] or [[array table]] header: it creates the +// intermediate containers, appends array-table elements, applies the strict +// policy, registers unmarshaler-interface captures, and caches the target +// container so that the key-values that follow are stored directly. +// +// Map values are not addressable: when one needs in-place mutations (struct +// or array values), a copy is made and registered to be stored back when the +// table changes (see flushTable). Maps and slices are references and are +// traversed without copies. +func (d *decoder) walkTable(root reflect.Value, expr *unstable.Node, isArrayTable bool, first bool) error { + v := root + pf := slotWriter{kind: 1, slot: root} + idx := 0 + +walk: + for { + // Dereference pointers in place. + for v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) } - if d.clearArrayTable && elem.Len() > 0 { - elem.SetLen(0) - d.clearArrayTable = false + elem := v.Elem() + pf = slotWriter{kind: 1, slot: elem} + v = elem + } + + // Tables assigned to a type implementing the unmarshaler interface + // are captured as raw bytes, delivered once the document is read. + if d.unmarshalerInterface && hasUnmarshaler(v) { + d.startCapture(idx, expr) + return nil + } + + if idx >= len(d.tableKey) { + break walk + } + + name := d.tableKey[idx] + + switch v.Kind() { + case reflect.Interface: + if !v.IsNil() { + c := v.Elem() + if k := c.Kind(); k == reflect.Map || k == reflect.Slice { + // Reference types: mutations are visible through the + // existing interface value. + v = c + continue + } } - } - return d.handleArrayTableCollectionLast(key, elem) - case reflect.Ptr: - elem := v.Elem() - if !elem.IsValid() { - ptr := reflect.New(v.Type().Elem()) - v.Set(ptr) - elem = ptr.Elem() - } - - elem, err := d.handleArrayTableCollectionLast(key, elem) - if err != nil { - return reflect.Value{}, err - } - v.Elem().Set(elem) - - return v, nil - case reflect.Slice: - if d.clearArrayTable && v.Len() > 0 { - v.SetLen(0) - d.clearArrayTable = false - } - elemType := v.Type().Elem() - var elem reflect.Value - if elemType.Kind() == reflect.Interface { - elem = makeMapStringInterface() - } else { - elem = reflect.New(elemType).Elem() - } - elem2, err := d.handleArrayTable(key, elem) - if err != nil { - return reflect.Value{}, err - } - if elem2.IsValid() { - elem = elem2 - } - return reflect.Append(v, elem), nil - case reflect.Array: - idx := d.arrayIndex(true, v) - if idx >= v.Len() { - return v, fmt.Errorf("%w at position %d", d.typeMismatchError("array table", v.Type()), idx) - } - elem := v.Index(idx) - _, err := d.handleArrayTable(key, elem) - return v, err - default: - return reflect.Value{}, d.typeMismatchError("array table", v.Type()) - } -} - -// When parsing an array table expression, each part of the key needs to be -// evaluated like a normal key, but if it returns a collection, it also needs to -// point to the last element of the collection. Unless it is the last part of -// the key, then it needs to create a new element at the end. -func (d *decoder) handleArrayTableCollection(key unstable.Iterator, v reflect.Value) (reflect.Value, error) { - if key.IsLast() { - return d.handleArrayTableCollectionLast(key, v) - } - - switch v.Kind() { - case reflect.Ptr: - elem := v.Elem() - if !elem.IsValid() { - ptr := reflect.New(v.Type().Elem()) - v.Set(ptr) - elem = ptr.Elem() - } - - elem, err := d.handleArrayTableCollection(key, elem) - if err != nil { - return reflect.Value{}, err - } - if elem.IsValid() { - v.Elem().Set(elem) - } - - return v, nil - case reflect.Slice: - // Create a new element when the slice is empty; otherwise operate on - // the last element. - var ( - elem reflect.Value - created bool - ) - if v.Len() == 0 { - created = true - elemType := v.Type().Elem() - if elemType.Kind() == reflect.Interface { - elem = makeMapStringInterface() + // Anything else is replaced by a fresh generic map. + if !mapStringInterfaceType.AssignableTo(v.Type()) { + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", v.Type())) + } + fresh := reflect.ValueOf(map[string]interface{}{}) + d.storeSlot(&pf, fresh) + v = fresh + case reflect.Slice: + if v.Len() == 0 { + // Implicit creation of the first element: the array table + // that would create it has not been seen yet (issue 995). + if v.IsNil() { + v = reflect.MakeSlice(v.Type(), 0, 4) + } + v = reflect.Append(v, newContainerElem(v.Type().Elem())) + d.storeSlot(&pf, v) + } + n := v.Len() - 1 + d.segIdx[idx] = n + elem := v.Index(n) + pf = slotWriter{kind: 1, slot: elem} + v = elem + case reflect.Array: + key := d.joinPath(d.tableKey[:idx]) + cnt := d.arrayCount(key) + if cnt == 0 { + cnt = 1 + d.setArrayCount(key, 1) + } + if cnt > v.Len() { + return d.keyedError(expr, fmt.Errorf("cannot reach element %d of array of size %d", cnt-1, v.Len())) + } + d.segIdx[idx] = cnt - 1 + elem := v.Index(cnt - 1) + pf = slotWriter{kind: 1, slot: elem} + v = elem + case reflect.Map: + if v.IsNil() { + nm := reflect.MakeMap(v.Type()) + d.storeSlot(&pf, nm) + v = nm + } + var key reflect.Value + var w slotWriter + if v.Type().Key() == stringType { + key = d.stringMapKey(name) + w = slotWriter{kind: 3, m: v, ks: name} } else { - elem = reflect.New(elemType).Elem() + k, err := makeMapKey(v.Type().Key(), name) + if err != nil { + return err + } + key = k + w = slotWriter{kind: 2, m: v, k: k} } - } else { - elem = v.Index(v.Len() - 1) - } - x, err := d.handleArrayTable(key, elem) - if err != nil || d.skipUntilTable { - return reflect.Value{}, err - } - if x.IsValid() { - if created { - elem = x + elem := v.MapIndex(key) + + // The last part of an array table is finalized as a slice + // container: do not materialize a table for it. + if isArrayTable && idx == len(d.tableKey)-1 { + et := v.Type().Elem() + switch et.Kind() { + case reflect.Interface, reflect.Slice, reflect.Array: + if elem.IsValid() { + v = elem + } else { + v = reflect.Zero(et) + } + pf = w + idx++ + continue + default: + } + } + + if elem.IsValid() { + ce := elem + ceIface := false + if ce.Kind() == reflect.Interface { + ceIface = true + if !ce.IsNil() { + ce = ce.Elem() + } + } + switch ce.Kind() { + case reflect.Map, reflect.Slice: + pf = w + v = ce + case reflect.Ptr: + if ce.IsNil() { + np := reflect.New(ce.Type().Elem()) + d.storeSlot(&w, np) + ce = np + } + pf = w + v = ce + case reflect.Struct, reflect.Array: + if ceIface { + // Interface-held non-generic content is replaced. + fresh := reflect.ValueOf(map[string]interface{}{}) + d.storeSlot(&w, fresh) + pf = w + v = fresh + } else { + tmp := reflect.New(elem.Type()).Elem() + tmp.Set(elem) + d.tableFlush = append(d.tableFlush, flushOp{w: w, val: tmp}) + pf = slotWriter{kind: 1, slot: tmp} + v = tmp + } + default: + if !ceIface { + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", ce.Type())) + } + fresh := reflect.ValueOf(map[string]interface{}{}) + d.storeSlot(&w, fresh) + pf = w + v = fresh + } } else { - elem.Set(x) + et := v.Type().Elem() + switch et.Kind() { + case reflect.Interface: + if !mapStringInterfaceType.AssignableTo(et) { + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", et)) + } + fresh := reflect.ValueOf(map[string]interface{}{}) + d.storeSlot(&w, fresh) + pf = w + v = fresh + case reflect.Map: + nm := reflect.MakeMap(et) + d.storeSlot(&w, nm) + pf = w + v = nm + case reflect.Ptr: + np := reflect.New(et.Elem()) + d.storeSlot(&w, np) + pf = w + v = np + case reflect.Struct, reflect.Array, reflect.Slice: + tmp := reflect.New(et).Elem() + d.tableFlush = append(d.tableFlush, flushOp{w: w, val: tmp}) + pf = slotWriter{kind: 1, slot: tmp} + v = tmp + default: + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", et)) + } } + idx++ + case reflect.Struct: + plan := planForType(v.Type()) + f, found := plan.lookup(name) + if !found { + d.strict.MissingTable(expr) + d.skipUntilTable = true + return nil + } + fv, err := fieldByIndexAlloc(v, f.index) + if err != nil { + return err + } + pf = slotWriter{kind: 1, slot: fv} + v = fv + idx++ + default: + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", v.Kind())) + } + } + + if isArrayTable { + akey := d.joinPath(d.tableKey) + d.resetChildArrayCounts(akey) + + // Unwrap an interface container. + if v.Kind() == reflect.Interface { + var slice []interface{} + if !v.IsNil() { + if s, ok := v.Elem().Interface().([]interface{}); ok { + slice = s + } + } + if first { + slice = slice[:0] + } + m := map[string]interface{}{} + slice = append(slice, m) + sv := reflect.ValueOf(slice) + d.storeSlot(&pf, sv) + d.setArrayCount(akey, len(slice)) + d.segIdx[len(d.tableKey)] = len(slice) - 1 + d.tableTarget = reflect.ValueOf(m) + d.tableParentSlot = slotWriter{kind: 1, slot: sv.Index(len(slice) - 1)} + d.tableTargetValid = true + return nil } - if created { - return reflect.Append(v, elem), nil + switch v.Kind() { + case reflect.Slice: + if v.IsNil() { + v = reflect.MakeSlice(v.Type(), 0, 4) + } else if first { + v = v.Slice(0, 0) + } + v = reflect.Append(v, newContainerElem(v.Type().Elem())) + d.storeSlot(&pf, v) + n := v.Len() - 1 + d.setArrayCount(akey, n+1) + d.segIdx[len(d.tableKey)] = n + elem := v.Index(n) + if d.unmarshalerInterface && hasUnmarshaler(elem) { + d.startCapture(len(d.tableKey), expr) + return nil + } + pf = slotWriter{kind: 1, slot: elem} + v = elem + case reflect.Array: + cnt := d.arrayCount(akey) + if first { + cnt = 0 + } + if cnt >= v.Len() { + return d.keyedError(expr, fmt.Errorf("array of size %d is too small to store this array table", v.Len())) + } + v.Index(cnt).Set(reflect.Zero(v.Type().Elem())) + d.setArrayCount(akey, cnt+1) + d.segIdx[len(d.tableKey)] = cnt + elem := v.Index(cnt) + if d.unmarshalerInterface && hasUnmarshaler(elem) { + d.startCapture(len(d.tableKey), expr) + return nil + } + pf = slotWriter{kind: 1, slot: elem} + v = elem + default: + return d.keyedError(expr, fmt.Errorf("cannot store an array table in a %s", v.Kind())) } - return v, err - case reflect.Array: - idx := d.arrayIndex(false, v) - if idx >= v.Len() { - return v, fmt.Errorf("%w at position %d", d.typeMismatchError("array table", v.Type()), idx) + } + + // Settle on the concrete container for the key-values that follow. + for { + switch v.Kind() { + case reflect.Ptr: + if v.IsNil() { + if !v.CanSet() { + return nil + } + v.Set(reflect.New(v.Type().Elem())) + } + elem := v.Elem() + pf = slotWriter{kind: 1, slot: elem} + v = elem + continue + case reflect.Interface: + if !v.IsNil() { + c := v.Elem() + if c.Type() == mapStringInterfaceType || c.Type() == sliceInterfaceType { + v = c + continue + } + } + if !mapStringInterfaceType.AssignableTo(v.Type()) { + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", v.Type())) + } + fresh := reflect.ValueOf(map[string]interface{}{}) + d.storeSlot(&pf, fresh) + v = fresh + continue + case reflect.Slice: + if v.Len() == 0 { + if v.IsNil() { + v = reflect.MakeSlice(v.Type(), 0, 4) + } + v = reflect.Append(v, newContainerElem(v.Type().Elem())) + d.storeSlot(&pf, v) + } + n := v.Len() - 1 + d.segIdx[len(d.tableKey)] = n + elem := v.Index(n) + pf = slotWriter{kind: 1, slot: elem} + v = elem + continue + case reflect.Map, reflect.Struct: + d.tableTarget = v + d.tableParentSlot = pf + d.tableTargetValid = true + return nil + default: + return d.keyedError(expr, fmt.Errorf("cannot store a table in a %s", v.Kind())) } - elem := v.Index(idx) - _, err := d.handleArrayTable(key, elem) - return v, err - default: - return d.handleArrayTable(key, v) } } -func (d *decoder) handleKeyPart(key unstable.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) { - var rv reflect.Value +// resumeCapture looks for an existing capture this table expression belongs +// to. It returns true if the expression was consumed. +func (d *decoder) resumeCapture(expr *unstable.Node) bool { + // Iterate in reverse, so that tables attach to the latest element of + // array tables. + for i := len(d.captures) - 1; i >= 0; i-- { + c := &d.captures[i] + if len(d.tableKey) < len(c.names) { + continue + } + if expr.Kind == unstable.ArrayTable && len(d.tableKey) == len(c.names) { + // A new element of an array table is not part of the capture of + // the previous element. + continue + } + match := true + for j, p := range c.names { + if d.tableKey[j] != p { + match = false + break + } + } + if !match { + continue + } + d.captureIdx = i + if len(d.tableKey) > len(c.names) { + d.appendCaptureHeader(c, expr, len(c.names)) + } + return true + } + return false +} - // First, dispatch over v to make sure it is a valid object. - // There is no guarantee over what it could be. - switch v.Kind() { - case reflect.Ptr: - elem := v.Elem() - if !elem.IsValid() { +// appendCaptureHeader writes the table header of expr in the capture buffer, +// adjusted to be relative to the capture root. +func (d *decoder) appendCaptureHeader(c *rawCapture, expr *unstable.Node, skip int) { + c.buf = append(c.buf, '[') + if expr.Kind == unstable.ArrayTable { + c.buf = append(c.buf, '[') + } + c.buf = append(c.buf, d.rawKeySuffix(expr, skip)...) + c.buf = append(c.buf, ']') + if expr.Kind == unstable.ArrayTable { + c.buf = append(c.buf, ']') + } + c.buf = append(c.buf, '\n') +} + +// rawKeySuffix returns the raw bytes of the key of the expression, skipping +// the first n parts. +func (d *decoder) rawKeySuffix(expr *unstable.Node, n int) []byte { + it := expr.Key() + idx := 0 + var start, end unstable.Range + for it.Next() { + if idx >= n { + r := it.Node().Raw + if start.Length == 0 && start.Offset == 0 && idx == n { + start = r + } + end = r + } + idx++ + } + return d.p.Data()[start.Offset : end.Offset+end.Length] +} + +// startCapture registers a new capture for the table at the given path +// (prefix of tableKey). +func (d *decoder) startCapture(pathLen int, expr *unstable.Node) { + names := make([]string, pathLen) + copy(names, d.tableKey[:pathLen]) + indexes := make([]int, pathLen+1) + copy(indexes, d.segIdx[:pathLen+1]) + d.captures = append(d.captures, rawCapture{ + names: names, + indexes: indexes, + }) + d.captureIdx = len(d.captures) - 1 + if pathLen < len(d.tableKey) { + d.appendCaptureHeader(&d.captures[d.captureIdx], expr, pathLen) + } +} + +// startRootCapture opens a capture covering the entire document, used when the +// root target itself implements the Unmarshaler interface. It is opened before +// reading any expression: top-level key-values are then accumulated through the +// regular capture branch, and its empty name path matches every table in +// resumeCapture, so the whole document is handed to UnmarshalTOML once. The +// single index slot is -1 because the root is never reached through an array +// table. +func (d *decoder) startRootCapture() { + d.captures = append(d.captures, rawCapture{indexes: []int{-1}}) + d.captureIdx = len(d.captures) - 1 +} + +// resolveCapture walks back to the target of a capture and delivers the +// accumulated raw bytes to its UnmarshalTOML implementation. +func (d *decoder) resolveCapture(v reflect.Value, c *rawCapture, idx int, indexed bool) (reflect.Value, error) { + if v.Kind() == reflect.Ptr { + if v.Type().Implements(unmarshalerType) && idx == len(c.names) { + u, _ := unmarshalerOf(v) + return v, u.UnmarshalTOML(c.buf) + } + if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } - elem = v.Elem() - return d.handleKeyPart(key, elem, nextFn, makeFn) - case reflect.Map: - vt := v.Type() - - // Create the key for the map element. Convert to key type. - mk, err := d.keyFromData(vt.Key(), key.Node().Data) + nv, err := d.resolveCapture(v.Elem(), c, idx, indexed) if err != nil { return reflect.Value{}, err } - - // If the map does not exist, create it. - if v.IsNil() { - vt := v.Type() - v = reflect.MakeMap(vt) - rv = v + if nv.IsValid() { + v.Elem().Set(nv) } + return v, nil + } - mv := v.MapIndex(mk) - set := false - switch { - case !mv.IsValid(): - // If there is no value in the map, create a new one according to - // the map type. If the element type is interface, create either a - // map[string]interface{} or a []interface{} depending on whether - // this is the last part of the array table key. - - t := vt.Elem() - if t.Kind() == reflect.Interface { - mv = makeFn() - } else { - mv = reflect.New(t).Elem() - } - set = true - case mv.Kind() == reflect.Interface: - mv = mv.Elem() - if !mv.IsValid() { - mv = makeFn() - } - set = true - case !mv.CanAddr(): - vt := v.Type() - t := vt.Elem() - oldmv := mv - mv = reflect.New(t).Elem() - mv.Set(oldmv) - set = true + if !indexed && (v.Kind() == reflect.Slice || v.Kind() == reflect.Array) && c.indexes[idx] >= 0 { + i := c.indexes[idx] + if i >= v.Len() { + return reflect.Value{}, errors.New("toml: internal error: capture index out of range") } - - x, err := nextFn(key, mv) + elem := v.Index(i) + nv, err := d.resolveCapture(elem, c, idx, true) if err != nil { return reflect.Value{}, err } - - if x.IsValid() { - mv = x - set = true + if nv.IsValid() { + elem.Set(nv) } + return v, nil + } - if set { - v.SetMapIndex(mk, mv) + if idx == len(c.names) { + u, ok := unmarshalerOf(v) + if !ok { + return reflect.Value{}, errors.New("toml: internal error: capture target does not implement UnmarshalTOML") } + return v, u.UnmarshalTOML(c.buf) + } + + name := c.names[idx] + + switch v.Kind() { case reflect.Struct: - path, found := structFieldPath(v, string(key.Node().Data)) + plan := planForType(v.Type()) + f, found := plan.lookup(name) if !found { - d.skipUntilTable = true - return reflect.Value{}, nil + return v, nil } - - if d.errorContext == nil { - d.errorContext = new(errorContext) - } - t := v.Type() - d.errorContext.Struct = t - d.errorContext.Field = path - - f := fieldByIndex(v, path) - x, err := nextFn(key, f) - if err != nil || d.skipUntilTable { - return reflect.Value{}, err - } - if x.IsValid() { - f.Set(x) - } - d.errorContext.Field = nil - d.errorContext.Struct = nil - case reflect.Interface: - if v.Elem().IsValid() { - v = v.Elem() - } else { - v = makeMapStringInterface() - } - - x, err := d.handleKeyPart(key, v, nextFn, makeFn) + fv, err := fieldByIndexAlloc(v, f.index) if err != nil { return reflect.Value{}, err } - if x.IsValid() { - v = x + nv, err := d.resolveCapture(fv, c, idx+1, false) + if err != nil { + return reflect.Value{}, err } - rv = v + if nv.IsValid() && fv.CanSet() { + fv.Set(nv) + } + return v, nil + case reflect.Map: + key, err := makeMapKey(v.Type().Key(), name) + if err != nil { + return reflect.Value{}, err + } + if v.IsNil() { + v = reflect.MakeMap(v.Type()) + } + elem := reflect.New(v.Type().Elem()).Elem() + if existing := v.MapIndex(key); existing.IsValid() { + elem.Set(existing) + } + nv, err := d.resolveCapture(elem, c, idx+1, false) + if err != nil { + return reflect.Value{}, err + } + if nv.IsValid() { + v.SetMapIndex(key, nv) + } + return v, nil + case reflect.Interface: + elem := elemOrNewMap(v) + nv, err := d.resolveCapture(elem, c, idx, indexed) + if err != nil || !nv.IsValid() { + return reflect.Value{}, err + } + return nv, nil default: - panic(fmt.Errorf("unhandled part: %s", v.Kind())) + return reflect.Value{}, fmt.Errorf("toml: internal error: cannot resolve capture target through %s", v.Kind()) } - - return rv, nil } -// HandleArrayTablePart navigates the Go structure v using the key v. It is -// only used for the prefix (non-last) parts of an array-table. When -// encountering a collection, it should go to the last element. -func (d *decoder) handleArrayTablePart(key unstable.Iterator, v reflect.Value) (reflect.Value, error) { - var makeFn valueMakerFn - if key.IsLast() { - makeFn = makeSliceInterface +// captureKeyValue appends the raw bytes of a key-value expression to the +// current capture. +func (d *decoder) captureKeyValue(expr *unstable.Node) { + c := &d.captures[d.captureIdx] + c.buf = append(c.buf, d.p.Raw(expr.Raw)...) + c.buf = append(c.buf, '\n') +} + +// hasUnmarshaler reports whether v can provide an unstable.Unmarshaler, +// without allocating anything. +func hasUnmarshaler(v reflect.Value) bool { + t := v.Type() + return t.Implements(unmarshalerType) || (v.CanAddr() && reflect.PtrTo(t).Implements(unmarshalerType)) +} + +// makeMapKey converts a TOML key into a value usable as the given map key +// type. +func makeMapKey(kt reflect.Type, name string) (reflect.Value, error) { + switch kt.Kind() { + case reflect.String: + return reflect.ValueOf(name).Convert(kt), nil + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + i, err := strconv.ParseInt(name, 10, 64) + if err != nil { + return reflect.Value{}, fmt.Errorf("toml: cannot parse map key %q as %s: %w", name, kt, err) + } + k := reflect.New(kt).Elem() + if k.OverflowInt(i) { + return reflect.Value{}, fmt.Errorf("toml: map key %q overflows %s", name, kt) + } + k.SetInt(i) + return k, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + u, err := strconv.ParseUint(name, 10, 64) + if err != nil { + return reflect.Value{}, fmt.Errorf("toml: cannot parse map key %q as %s: %w", name, kt, err) + } + k := reflect.New(kt).Elem() + if k.OverflowUint(u) { + return reflect.Value{}, fmt.Errorf("toml: map key %q overflows %s", name, kt) + } + k.SetUint(u) + return k, nil + case reflect.Float32, reflect.Float64: + f, err := strconv.ParseFloat(name, 64) + if err != nil { + return reflect.Value{}, fmt.Errorf("toml: cannot parse map key %q as %s: %w", name, kt, err) + } + k := reflect.New(kt).Elem() + k.SetFloat(f) + return k, nil + case reflect.Ptr: + if kt.Implements(textUnmarshalerType) { + k := reflect.New(kt.Elem()) + err := k.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(name)) + if err != nil { + return reflect.Value{}, fmt.Errorf("toml: error unmarshaling map key %q: %w", name, err) + } + return k, nil + } + default: + if reflect.PtrTo(kt).Implements(textUnmarshalerType) { + k := reflect.New(kt) + err := k.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(name)) + if err != nil { + return reflect.Value{}, fmt.Errorf("toml: error unmarshaling map key %q: %w", name, err) + } + return k.Elem(), nil + } + } + return reflect.Value{}, fmt.Errorf("toml: cannot decode a key into a map with key type %s", kt) +} + +// elemOrNewMap unwraps an interface value to descend into it. Contents that +// can hold a table (generic maps and slices) are kept; anything else is +// replaced by a fresh map[string]interface{}. Maps and slices are reference +// types: they are returned directly, not copied. +func elemOrNewMap(v reflect.Value) reflect.Value { + if !v.IsNil() { + concrete := v.Elem() + t := concrete.Type() + if t == mapStringInterfaceType || t == sliceInterfaceType { + return concrete + } + } + return reflect.ValueOf(map[string]interface{}{}) +} + +// handleKeyValueExpression stores the value of a top-level key-value +// expression, relative to the current table. +func (d *decoder) handleKeyValueExpression(expr *unstable.Node, root reflect.Value) error { + d.path = d.path[:0] + + target := root + useCache := d.tableTargetValid && len(d.tableKey) > 0 + if useCache { + target = d.tableTarget } else { - makeFn = makeMapStringInterface + for _, name := range d.tableKey { + d.path = append(d.path, pathPart{name: name}) + } } - return d.handleKeyPart(key, v, d.handleArrayTableCollection, makeFn) + + it := expr.Key() + for it.Next() { + d.path = append(d.path, pathPart{node: it.Node()}) + } + + nv, err := d.descend(target, d.path, 0, expr, expr.Value()) + if err != nil { + return d.contextualizeError(err, useCache) + } + if !nv.IsValid() { + return nil + } + if useCache { + // The target may have been replaced (e.g. a nil map allocated): + // re-link it into its parent. + if nv.Kind() == reflect.Map && nv.Pointer() != d.tableTarget.Pointer() { + d.storeSlot(&d.tableParentSlot, nv) + d.tableTarget = nv + } + } else { + if root.CanSet() { + root.Set(nv) + } + } + return nil } -// HandleTable returns a reference when it has checked the next expression but -// cannot handle it. -func (d *decoder) handleTable(key unstable.Iterator, v reflect.Value) (reflect.Value, error) { - if v.Kind() == reflect.Slice { - // For non-empty slices, work with the last element - if v.Len() > 0 { - elem := v.Index(v.Len() - 1) - x, err := d.handleTable(key, elem) +// descend walks the given key path into v, and assigns the value at the +// end. It returns the value to store back at this level. An invalid value +// means nothing should be stored (e.g. unknown field). +func (d *decoder) descend(v reflect.Value, path []pathPart, idx int, expr *unstable.Node, value *unstable.Node) (reflect.Value, error) { + if idx == len(path) { + return d.assignValue(v, expr, value) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + nv, err := d.descend(v.Elem(), path, idx, expr, value) + if err != nil || !nv.IsValid() { + return reflect.Value{}, err + } + v.Elem().Set(nv) + return v, nil + } + + // A target implementing the unmarshaler interface consumes the value, + // whatever the remaining parts of the key are. + if d.unmarshalerInterface { + if u, ok := unmarshalerOf(v); ok { + return v, u.UnmarshalTOML(d.rawValue(expr, value)) + } + } + + part := path[idx] + + switch v.Kind() { + case reflect.Map: + // Native fast path for the most common generic target: walk the + // remaining dotted-key path with plain Go map operations and decode + // the value directly, skipping the reflect.Value round-trips + // (stringMapKey, MapIndex, New, SetMapIndex) entirely. + if !d.unmarshalerInterface && v.Type() == mapStringInterfaceType { + return d.descendStrMap(v, path, idx, value) + } + var name string + var key reflect.Value + var err error + fastKey := v.Type().Key() == stringType + if fastKey { + name = d.partString(&part) + key = d.stringMapKey(name) + } else { + key, err = makeMapKey(v.Type().Key(), d.partString(&part)) if err != nil { return reflect.Value{}, err } - if x.IsValid() { - elem.Set(x) - } - return reflect.Value{}, nil } - // Empty slice - check if it implements Unmarshaler (e.g., RawMessage) - // and we're at the end of the key path - if d.unmarshalerInterface && !key.Next() { - if v.CanAddr() && v.Addr().CanInterface() { - if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok { - return d.handleKeyValuesUnmarshaler(outi) + if v.IsNil() { + v = reflect.MakeMap(v.Type()) + } + elemType := v.Type().Elem() + existing := v.MapIndex(key) + var elem reflect.Value + switch { + case existing.IsValid(): + elem = reflect.New(elemType).Elem() + elem.Set(existing) + case idx+1 == len(path) && elemType.Kind() == reflect.Interface: + // Fast path: a fresh interface element does not need to be + // materialized, the assigned value is stored directly. + elem = reflect.Zero(elemType) + default: + elem = reflect.New(elemType).Elem() + } + nv, err := d.descend(elem, path, idx+1, expr, value) + if err != nil { + return reflect.Value{}, err + } + if nv.IsValid() { + if fastKey { + // The recursion may have overwritten the key buffer. + key = d.stringMapKey(name) + } + v.SetMapIndex(key, nv) + } + return v, nil + case reflect.Struct: + plan := planForType(v.Type()) + f, found := plan.lookupBytes(part.bytes()) + if !found { + if part.node != nil { + d.strict.MissingField(expr) + } + return v, nil + } + fv, err := fieldByIndexAlloc(v, f.index) + if err != nil { + return reflect.Value{}, err + } + var nv reflect.Value + if idx+1 == len(path) { + // Leaf field: assign directly. descend's first action for a + // fully-consumed path is exactly this call, so skipping the extra + // frame is equivalent and avoids a call per scalar field. + nv, err = d.assignValue(fv, expr, value) + } else { + nv, err = d.descend(fv, path, idx+1, expr, value) + } + if err != nil { + var mm *typeMismatchError + if errors.As(err, &mm) { + err = &unstable.ParserError{ + Highlight: mm.highlight, + Message: fmt.Sprintf("cannot decode TOML %s into struct field %s.%s of type %s", + mm.toml, v.Type(), f.fieldName, mm.target), } } + return reflect.Value{}, err } - return reflect.Value{}, unstable.NewParserError(key.Node().Data, "cannot store a table in a slice") + if nv.IsValid() && fv.CanSet() { + fv.Set(nv) + } + return v, nil + case reflect.Interface: + elem := elemOrNewMap(v) + nv, err := d.descend(elem, path, idx, expr, value) + if err != nil || !nv.IsValid() { + return reflect.Value{}, err + } + return nv, nil + case reflect.Slice: + if v.Len() == 0 { + if v.IsNil() { + v = reflect.MakeSlice(v.Type(), 0, 4) + } + v = reflect.Append(v, reflect.New(v.Type().Elem()).Elem()) + } + elem := v.Index(v.Len() - 1) + nv, err := d.descend(elem, path, idx, expr, value) + if err != nil { + return reflect.Value{}, err + } + if nv.IsValid() { + elem.Set(nv) + } + return v, nil + case reflect.Array: + names := make([]string, idx) + for i := range names { + names[i] = path[i].str() + } + cnt := d.arrayCount(d.joinPath(names)) + if cnt == 0 { + cnt = 1 + } + elemIdx := cnt - 1 + if elemIdx >= v.Len() { + return reflect.Value{}, unstable.NewParserError(keyHighlight(d.p.Data(), part.node), + "cannot reach element %d of array of size %d", elemIdx, v.Len()) + } + elem := v.Index(elemIdx) + nv, err := d.descend(elem, path, idx, expr, value) + if err != nil { + return reflect.Value{}, err + } + if nv.IsValid() { + elem.Set(nv) + } + return v, nil + default: + return reflect.Value{}, d.typeMismatchError("table", v.Type(), keyHighlight(d.p.Data(), part.node)) } - if key.Next() { - // Still scoping the key - return d.handleTablePart(key, v) - } - // Done scoping the key. - // Now handle all the key-value expressions in this table. - return d.handleKeyValues(v) } -// Handle root expressions until the end of the document or the next -// non-key-value. -func (d *decoder) handleKeyValues(v reflect.Value) (reflect.Value, error) { - // Check if target implements Unmarshaler before processing key-values. - // This allows types to handle entire tables themselves. - if d.unmarshalerInterface { - vv := v - for vv.Kind() == reflect.Ptr { - if vv.IsNil() { - vv.Set(reflect.New(vv.Type().Elem())) - } - vv = vv.Elem() - } - if vv.CanAddr() && vv.Addr().CanInterface() { - if outi, ok := vv.Addr().Interface().(unstable.Unmarshaler); ok { - // Collect all key-value expressions for this table - return d.handleKeyValuesUnmarshaler(outi) - } - } +// descendStrMap assigns into a native map[string]interface{} target, following +// the remaining dotted-key parts with plain Go map operations and decoding the +// value with decodeAny. It returns the map to store back at this level: a new +// map when v was nil, otherwise v unchanged, since maps are reference types and +// are mutated in place. +func (d *decoder) descendStrMap(v reflect.Value, path []pathPart, idx int, value *unstable.Node) (reflect.Value, error) { + var m map[string]interface{} + if v.IsNil() { + m = make(map[string]interface{}) + v = reflect.ValueOf(m) + } else { + m = v.Interface().(map[string]interface{}) } - var rv reflect.Value - for d.nextExpr() { - expr := d.expr() - if expr.Kind != unstable.KeyValue { - // Stash the expression so that fromParser can just loop and use - // the right handler. - // We could just recurse ourselves here, but at least this gives a - // chance to pop the stack a bit. - d.stashExpr() - break + // Walk intermediate parts, creating or reusing nested generic maps. A + // non-map value at an intermediate key can only occur in a document the + // seen-tracker has already rejected; replacing it mirrors the reflect + // path (elemOrNewMap). + for ; idx < len(path)-1; idx++ { + name := d.partString(&path[idx]) + child, _ := m[name].(map[string]interface{}) + if child == nil { + child = make(map[string]interface{}) + m[name] = child } - - _, err := d.seen.CheckExpression(expr) - if err != nil { - return reflect.Value{}, err - } - - x, err := d.handleKeyValue(expr, v) - if err != nil { - return reflect.Value{}, err - } - if x.IsValid() { - v = x - rv = x - } - } - return rv, nil -} - -// handleKeyValuesUnmarshaler collects all key-value expressions for a table -// and passes them to the Unmarshaler as raw TOML bytes. -func (d *decoder) handleKeyValuesUnmarshaler(u unstable.Unmarshaler) (reflect.Value, error) { - // Collect raw bytes from all key-value expressions for this table. - // We use the Raw field on each KeyValue expression to preserve the - // original formatting (whitespace, quoting style, etc.) from the document. - var buf []byte - - for d.nextExpr() { - expr := d.expr() - if expr.Kind != unstable.KeyValue { - d.stashExpr() - break - } - - _, err := d.seen.CheckExpression(expr) - if err != nil { - return reflect.Value{}, err - } - - // Use the raw bytes from the original document to preserve formatting - if expr.Raw.Length > 0 { - raw := d.p.Raw(expr.Raw) - buf = append(buf, raw...) - } - buf = append(buf, '\n') + m = child } - if err := u.UnmarshalTOML(buf); err != nil { + av, err := d.decodeAny(value) + if err != nil { return reflect.Value{}, err } - - return reflect.Value{}, nil + m[d.partString(&path[idx])] = av + return v, nil } -type ( - handlerFn func(key unstable.Iterator, v reflect.Value) (reflect.Value, error) - valueMakerFn func() reflect.Value -) - -func makeMapStringInterface() reflect.Value { - return reflect.MakeMap(mapStringInterfaceType) -} - -func makeSliceInterface() reflect.Value { - return reflect.MakeSlice(sliceInterfaceType, 0, 16) -} - -func (d *decoder) handleTablePart(key unstable.Iterator, v reflect.Value) (reflect.Value, error) { - return d.handleKeyPart(key, v, d.handleTable, makeMapStringInterface) -} - -func (d *decoder) tryTextUnmarshaler(node *unstable.Node, v reflect.Value) (bool, error) { - // Special case for time, because we allow to unmarshal to it from - // different kind of AST nodes. - if v.Type() == timeType { - return false, nil +// keyHighlight returns a highlight for the given key part node, falling back +// to the start of the document. +func keyHighlight(doc []byte, node *unstable.Node) []byte { + if node == nil { + return doc[0:0] } + return doc[node.Raw.Offset : node.Raw.Offset+node.Raw.Length] +} - if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) { - err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data) - if err != nil { - return false, unstable.NewParserError(d.p.Raw(node.Raw), "%w", err) +// rawValue returns the raw bytes of the value of a key-value expression. +func (d *decoder) rawValue(expr *unstable.Node, value *unstable.Node) []byte { + if value.Kind != unstable.InlineTable && value.Kind != unstable.Array { + return d.p.Raw(value.Raw) + } + if expr == nil || expr.Kind != unstable.KeyValue { + // Inline container nested in another container: best effort. + return d.p.Raw(value.Raw) + } + // Reconstruct the span of the value: it starts after the equal sign + // following the last part of the key, and stops at the end of the + // expression. + var last unstable.Range + it := expr.Key() + for it.Next() { + last = it.Node().Raw + } + doc := d.p.Data() + i := int(last.Offset + last.Length) + for i < len(doc) && (doc[i] == ' ' || doc[i] == '\t') { + i++ + } + i++ // equal sign + for i < len(doc) && (doc[i] == ' ' || doc[i] == '\t') { + i++ + } + end := int(expr.Raw.Offset + expr.Raw.Length) + return doc[i:end] +} + +// unmarshalerOf returns the unstable.Unmarshaler implementation of v, if +// any. It allocates intermediate pointers as needed. +func unmarshalerOf(v reflect.Value) (unstable.Unmarshaler, bool) { + t := v.Type() + if t.Implements(unmarshalerType) { + if v.Kind() == reflect.Ptr && v.IsNil() { + v.Set(reflect.New(t.Elem())) } - - return true, nil + return v.Interface().(unstable.Unmarshaler), true } - - return false, nil + if v.CanAddr() && reflect.PtrTo(t).Implements(unmarshalerType) { + return v.Addr().Interface().(unstable.Unmarshaler), true + } + return nil, false } -func (d *decoder) handleValue(value *unstable.Node, v reflect.Value) error { - for v.Kind() == reflect.Ptr { - v = initAndDereferencePointer(v) +var unmarshalerType = reflect.TypeOf(new(unstable.Unmarshaler)).Elem() + +// assignValue stores the TOML value carried by the node into v. +func (d *decoder) assignValue(v reflect.Value, expr *unstable.Node, value *unstable.Node) (reflect.Value, error) { + if v.Kind() == reflect.Ptr { + if d.unmarshalerInterface { + if u, ok := unmarshalerOf(v); ok { + return v, u.UnmarshalTOML(d.rawValue(expr, value)) + } + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + nv, err := d.assignValue(v.Elem(), expr, value) + if err != nil || !nv.IsValid() { + return reflect.Value{}, err + } + v.Elem().Set(nv) + return v, nil } if d.unmarshalerInterface { - if v.CanAddr() && v.Addr().CanInterface() { - if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok { - // Pass raw bytes from the original document - return outi.UnmarshalTOML(d.p.Raw(value.Raw)) - } - } - } - - // Only try TextUnmarshaler for scalar types. For Array and InlineTable, - // fall through to struct/map unmarshaling to allow flexible unmarshaling - // where a type can implement UnmarshalText for string values but still - // be populated field-by-field from a table. See issue #974. - if value.Kind != unstable.Array && value.Kind != unstable.InlineTable { - ok, err := d.tryTextUnmarshaler(value, v) - if ok || err != nil { - return err + if u, ok := unmarshalerOf(v); ok { + return v, u.UnmarshalTOML(d.rawValue(expr, value)) } } switch value.Kind { case unstable.String: - return d.unmarshalString(value, v) + return d.assignString(v, value) case unstable.Integer: - return d.unmarshalInteger(value, v) + return d.assignInteger(v, value) case unstable.Float: - return d.unmarshalFloat(value, v) + return d.assignFloat(v, value) case unstable.Bool: - return d.unmarshalBool(value, v) + return d.assignBool(v, value) case unstable.DateTime: - return d.unmarshalDateTime(value, v) - case unstable.LocalDate: - return d.unmarshalLocalDate(value, v) - case unstable.LocalTime: - return d.unmarshalLocalTime(value, v) + return d.assignDateTime(v, value) case unstable.LocalDateTime: - return d.unmarshalLocalDateTime(value, v) - case unstable.InlineTable: - return d.unmarshalInlineTable(value, v) + return d.assignLocalDateTime(v, value) + case unstable.LocalDate: + return d.assignLocalDate(v, value) + case unstable.LocalTime: + return d.assignLocalTime(v, value) case unstable.Array: - return d.unmarshalArray(value, v) + return d.assignArray(v, expr, value) + case unstable.InlineTable: + return d.assignInlineTable(v, expr, value) default: - panic(fmt.Errorf("handleValue not implemented for %s", value.Kind)) + return reflect.Value{}, unstable.NewParserError(value.Data, "unsupported value kind %s", value.Kind) } } -func (d *decoder) unmarshalArray(array *unstable.Node, v reflect.Value) error { +func (d *decoder) assignString(v reflect.Value, value *unstable.Node) (reflect.Value, error) { switch v.Kind() { - case reflect.Slice: - if v.IsNil() { - v.Set(reflect.MakeSlice(v.Type(), 0, 16)) - } else { - v.SetLen(0) - } - case reflect.Array: - // arrays are always initialized + case reflect.String: + v.SetString(string(value.Data)) + return v, nil case reflect.Interface: - elem := v.Elem() - if !elem.IsValid() { - elem = reflect.New(sliceInterfaceType).Elem() - elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16)) - } else if elem.Kind() == reflect.Slice { - if elem.Type() != sliceInterfaceType { - elem = reflect.New(sliceInterfaceType).Elem() - elem.Set(reflect.MakeSlice(sliceInterfaceType, 0, 16)) - } else if !elem.CanSet() { - nelem := reflect.New(sliceInterfaceType).Elem() - nelem.Set(reflect.MakeSlice(sliceInterfaceType, elem.Len(), elem.Cap())) - reflect.Copy(nelem, elem) - elem = nelem - } - } - err := d.unmarshalArray(array, elem) - if err != nil { - return err - } - v.Set(elem) - return nil + return boxInto(v, reflect.ValueOf(string(value.Data))) default: - // TODO: use newDecodeError, but first the parser needs to fill - // array.Data. - return d.typeMismatchError("array", v.Type()) } - - elemType := v.Type().Elem() - - it := array.Children() - idx := 0 - for it.Next() { - n := it.Node() - - // TODO: optimize - if v.Kind() == reflect.Slice { - elem := reflect.New(elemType).Elem() - - err := d.handleValue(n, elem) - if err != nil { - return err - } - - v.Set(reflect.Append(v, elem)) - } else { // array - if idx >= v.Len() { - return nil - } - elem := v.Index(idx) - err := d.handleValue(n, elem) - if err != nil { - return err - } - idx++ + if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) { + err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(value.Data) + if err != nil { + return reflect.Value{}, unstable.NewParserError(d.p.Raw(value.Raw), "%s", err) } + return v, nil } - - return nil + return reflect.Value{}, d.typeMismatchError("string", v.Type(), d.p.Raw(value.Raw)) } -func (d *decoder) unmarshalInlineTable(itable *unstable.Node, v reflect.Value) error { - // Make sure v is an initialized object. +func (d *decoder) assignInteger(v reflect.Value, value *unstable.Node) (reflect.Value, error) { + // Integer values targeting a float field are parsed as floats: they can + // represent (approximately) numbers beyond the int64 range. + if k := v.Kind(); k == reflect.Float32 || k == reflect.Float64 { + return d.assignFloat(v, value) + } + + i, err := parseInteger(value.Data) + if err != nil { + return reflect.Value{}, err + } + switch v.Kind() { - case reflect.Map: - if v.IsNil() { - v.Set(reflect.MakeMap(v.Type())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if v.OverflowInt(i) { + return reflect.Value{}, unstable.NewParserError(value.Data, "integer value %d cannot be stored in %s", i, v.Type()) } - case reflect.Struct: - // structs are always initialized. + v.SetInt(i) + return v, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + if i < 0 { + return reflect.Value{}, unstable.NewParserError(value.Data, "negative integer value %d cannot be stored in %s", i, v.Type()) + } + if v.OverflowUint(uint64(i)) { + return reflect.Value{}, unstable.NewParserError(value.Data, "integer value %d cannot be stored in %s", i, v.Type()) + } + v.SetUint(uint64(i)) + return v, nil case reflect.Interface: - elem := v.Elem() - if !elem.IsValid() { - elem = makeMapStringInterface() - v.Set(elem) - } - return d.unmarshalInlineTable(itable, elem) + return boxInto(v, reflect.ValueOf(i)) default: - return unstable.NewParserError(d.p.Raw(itable.Raw), "cannot store inline table in Go type %s", v.Kind()) + } + if ok, err := tryTextUnmarshaler(v, value.Data); ok { + return v, err + } + return reflect.Value{}, d.typeMismatchError("integer", v.Type(), d.p.Raw(value.Raw)) +} + +// tryTextUnmarshaler attempts to deliver the raw text of a value to a target +// implementing encoding.TextUnmarshaler. +func tryTextUnmarshaler(v reflect.Value, text []byte) (bool, error) { + if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) { + return true, v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(text) + } + return false, nil +} + +func (d *decoder) assignFloat(v reflect.Value, value *unstable.Node) (reflect.Value, error) { + f, err := parseFloat(value.Data) + if err != nil { + return reflect.Value{}, err } - it := itable.Children() - for it.Next() { - n := it.Node() - - x, err := d.handleKeyValue(n, v) - if err != nil { - return err - } - if x.IsValid() { - v = x + switch v.Kind() { + case reflect.Float64: + v.SetFloat(f) + return v, nil + case reflect.Float32: + if !math.IsInf(f, 0) && math.Abs(f) > math.MaxFloat32 { + return reflect.Value{}, unstable.NewParserError(value.Data, "float value %f cannot be stored in float32", f) } + v.SetFloat(f) + return v, nil + case reflect.Interface: + return boxInto(v, reflect.ValueOf(f)) + default: } - - return nil + if ok, err := tryTextUnmarshaler(v, value.Data); ok { + return v, err + } + return reflect.Value{}, d.typeMismatchError("float", v.Type(), d.p.Raw(value.Raw)) } -func (d *decoder) unmarshalDateTime(value *unstable.Node, v reflect.Value) error { - dt, err := parseDateTime(value.Data) - if err != nil { - return err - } - - if v.Kind() != reflect.Interface && v.Type() != timeType { - return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("datetime", v.Type())) - } - v.Set(reflect.ValueOf(dt)) - return nil -} - -func (d *decoder) unmarshalLocalDate(value *unstable.Node, v reflect.Value) error { - ld, err := parseLocalDate(value.Data) - if err != nil { - return err - } - - if v.Kind() != reflect.Interface && v.Type() != timeType { - return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("local date", v.Type())) - } - if v.Type() == timeType { - v.Set(reflect.ValueOf(ld.AsTime(time.Local))) - return nil - } - v.Set(reflect.ValueOf(ld)) - return nil -} - -func (d *decoder) unmarshalLocalTime(value *unstable.Node, v reflect.Value) error { - lt, rest, err := parseLocalTime(value.Data) - if err != nil { - return err - } - - if len(rest) > 0 { - return unstable.NewParserError(rest, "extra characters at the end of a local time") - } - - if v.Kind() != reflect.Interface { - return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("local time", v.Type())) - } - v.Set(reflect.ValueOf(lt)) - return nil -} - -func (d *decoder) unmarshalLocalDateTime(value *unstable.Node, v reflect.Value) error { - ldt, rest, err := parseLocalDateTime(value.Data) - if err != nil { - return err - } - - if len(rest) > 0 { - return unstable.NewParserError(rest, "extra characters at the end of a local date time") - } - - if v.Kind() != reflect.Interface && v.Type() != timeType { - return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("local datetime", v.Type())) - } - if v.Type() == timeType { - v.Set(reflect.ValueOf(ldt.AsTime(time.Local))) - return nil - } - v.Set(reflect.ValueOf(ldt)) - return nil -} - -func (d *decoder) unmarshalBool(value *unstable.Node, v reflect.Value) error { +func (d *decoder) assignBool(v reflect.Value, value *unstable.Node) (reflect.Value, error) { b := value.Data[0] == 't' switch v.Kind() { case reflect.Bool: v.SetBool(b) + return v, nil case reflect.Interface: - v.Set(reflect.ValueOf(b)) + return boxInto(v, reflect.ValueOf(b)) default: - return unstable.NewParserError(value.Data, "cannot assign boolean to a %t", b) } - - return nil + if ok, err := tryTextUnmarshaler(v, value.Data); ok { + return v, err + } + return reflect.Value{}, d.typeMismatchError("boolean", v.Type(), d.p.Raw(value.Raw)) } -func (d *decoder) unmarshalFloat(value *unstable.Node, v reflect.Value) error { - f, err := parseFloat(value.Data) +func (d *decoder) assignDateTime(v reflect.Value, value *unstable.Node) (reflect.Value, error) { + t, err := parseDateTime(value.Data) if err != nil { - return err + return reflect.Value{}, err + } + + if v.Type() == timeType { + setConcrete(v, t) + return v, nil + } + if v.Kind() == reflect.Interface { + return boxInto(v, reflect.ValueOf(t)) + } + return reflect.Value{}, d.typeMismatchError("datetime", v.Type(), d.p.Raw(value.Raw)) +} + +// setConcrete assigns x to v, which must be a settable value of x's concrete +// type. Writing through the address avoids the heap allocation that +// v.Set(reflect.ValueOf(x)) incurs from boxing x into an interface. Settable +// implies addressable: the decoder assigns to struct fields, slice elements, +// and reflect.New-allocated temporaries (map elements are decoded into such +// temporaries), all of which are addressable. +func setConcrete[T any](v reflect.Value, x T) { + *(v.Addr().Interface().(*T)) = x +} + +func (d *decoder) assignLocalDateTime(v reflect.Value, value *unstable.Node) (reflect.Value, error) { + dt, rest, err := parseLocalDateTime(value.Data) + if err != nil { + return reflect.Value{}, err + } + if len(rest) > 0 { + return reflect.Value{}, unstable.NewParserError(rest, "extra characters at the end of a local date time") + } + + switch v.Type() { + case localDateTimeType: + setConcrete(v, dt) + return v, nil + case timeType: + setConcrete(v, dt.AsTime(time.Local)) + return v, nil + } + if v.Kind() == reflect.Interface { + return boxInto(v, reflect.ValueOf(dt)) + } + return reflect.Value{}, d.typeMismatchError("local datetime", v.Type(), d.p.Raw(value.Raw)) +} + +func (d *decoder) assignLocalDate(v reflect.Value, value *unstable.Node) (reflect.Value, error) { + date, err := parseLocalDate(value.Data) + if err != nil { + return reflect.Value{}, err + } + + switch v.Type() { + case localDateType: + setConcrete(v, date) + return v, nil + case timeType: + setConcrete(v, date.AsTime(time.Local)) + return v, nil + } + if v.Kind() == reflect.Interface { + return boxInto(v, reflect.ValueOf(date)) + } + return reflect.Value{}, d.typeMismatchError("local date", v.Type(), d.p.Raw(value.Raw)) +} + +func (d *decoder) assignLocalTime(v reflect.Value, value *unstable.Node) (reflect.Value, error) { + t, rest, err := parseLocalTime(value.Data) + if err != nil { + return reflect.Value{}, err + } + if len(rest) > 0 { + return reflect.Value{}, unstable.NewParserError(rest, "extra characters at the end of a local time") + } + + switch v.Type() { + case localTimeType: + setConcrete(v, t) + return v, nil + case timeType: + setConcrete(v, time.Date(0, 1, 1, t.Hour, t.Minute, t.Second, t.Nanosecond, time.Local)) + return v, nil + } + if v.Kind() == reflect.Interface { + return boxInto(v, reflect.ValueOf(t)) + } + return reflect.Value{}, d.typeMismatchError("local time", v.Type(), d.p.Raw(value.Raw)) +} + +func (d *decoder) assignArray(v reflect.Value, expr *unstable.Node, value *unstable.Node) (reflect.Value, error) { + // Count the elements to allocate the target in one go. + count := 0 + cit := value.Children() + for cit.Next() { + if cit.Node().Kind != unstable.Comment { + count++ + } } switch v.Kind() { - case reflect.Float64: - v.SetFloat(f) - case reflect.Float32: - if f > math.MaxFloat32 { - return unstable.NewParserError(value.Data, "number %f does not fit in a float32", f) + case reflect.Slice: + // Allocate the backing array once at its final length and assign each + // element in place. This avoids a reflect.New allocation per element + // and the repeated growth checks of reflect.Append. + slice := reflect.MakeSlice(v.Type(), count, count) + i := 0 + it := value.Children() + for it.Next() { + n := it.Node() + if n.Kind == unstable.Comment { + continue + } + elem := slice.Index(i) + nv, err := d.assignValue(elem, nil, n) + if err != nil { + return reflect.Value{}, err + } + if nv.IsValid() { + elem.Set(nv) + } + i++ } - v.SetFloat(f) + return slice, nil + case reflect.Array: + it := value.Children() + i := 0 + for it.Next() { + n := it.Node() + if n.Kind == unstable.Comment { + continue + } + if i >= v.Len() { + // Extra elements are dropped when the target array is too + // small. + break + } + elem := v.Index(i) + nv, err := d.assignValue(elem, nil, n) + if err != nil { + return reflect.Value{}, err + } + elem.Set(nv) + i++ + } + return v, nil case reflect.Interface: - v.Set(reflect.ValueOf(f)) + // Build the []interface{} natively: each element is decoded straight + // into a Go value with no intermediate addressable reflect.Value and + // no reflect round-trip, and nested arrays recurse the same way. + slice := make([]interface{}, 0, count) + it := value.Children() + for it.Next() { + n := it.Node() + if n.Kind == unstable.Comment { + continue + } + ev, err := d.decodeAny(n) + if err != nil { + return reflect.Value{}, err + } + slice = append(slice, ev) + } + return boxInto(v, reflect.ValueOf(slice)) default: - return unstable.NewParserError(value.Data, "float cannot be assigned to %s", v.Kind()) } - - return nil + return reflect.Value{}, d.typeMismatchError("array", v.Type(), d.rawValue(expr, value)) } -const ( - maxInt = int64(^uint(0) >> 1) - minInt = -maxInt - 1 -) - -// Maximum value of uint for decoding. Currently the decoder parses the integer -// into an int64. As a result, on architectures where uint is 64 bits, the -// effective maximum uint we can decode is the maximum of int64. On -// architectures where uint is 32 bits, the maximum value we can decode is -// lower: the maximum of uint32. I didn't find a way to figure out this value at -// compile time, so it is computed during initialization. -var maxUint int64 = math.MaxInt64 - -func init() { //nolint:gochecknoinits - m := uint64(^uint(0)) - // #nosec G115 - if m < uint64(maxUint) { - maxUint = int64(m) - } -} - -func (d *decoder) unmarshalInteger(value *unstable.Node, v reflect.Value) error { - kind := v.Kind() - if kind == reflect.Float32 || kind == reflect.Float64 { - return d.unmarshalFloat(value, v) - } - - i, err := parseInteger(value.Data) - if err != nil { - return err - } - - var r reflect.Value - - switch kind { - case reflect.Int64: - v.SetInt(i) - return nil - case reflect.Int32: - if i < math.MinInt32 || i > math.MaxInt32 { - return fmt.Errorf("toml: number %d does not fit in an int32", i) +// decodeAny decodes a value node into a native Go value (the representation +// used for interface{} targets), without going through reflect. Scalars and +// arrays are handled directly; inline tables still defer to the reflect-based +// path so that their dotted-key merge semantics remain identical. +func (d *decoder) decodeAny(n *unstable.Node) (interface{}, error) { + switch n.Kind { + case unstable.String: + return string(n.Data), nil + case unstable.Integer: + i, err := parseInteger(n.Data) + return i, err + case unstable.Float: + f, err := parseFloat(n.Data) + return f, err + case unstable.Bool: + return n.Data[0] == 't', nil + case unstable.Array: + count := 0 + cit := n.Children() + for cit.Next() { + if cit.Node().Kind != unstable.Comment { + count++ + } } - - r = reflect.ValueOf(int32(i)) - case reflect.Int16: - if i < math.MinInt16 || i > math.MaxInt16 { - return fmt.Errorf("toml: number %d does not fit in an int16", i) + slice := make([]interface{}, 0, count) + it := n.Children() + for it.Next() { + c := it.Node() + if c.Kind == unstable.Comment { + continue + } + ev, err := d.decodeAny(c) + if err != nil { + return nil, err + } + slice = append(slice, ev) } - - r = reflect.ValueOf(int16(i)) - case reflect.Int8: - if i < math.MinInt8 || i > math.MaxInt8 { - return fmt.Errorf("toml: number %d does not fit in an int8", i) + return slice, nil + case unstable.InlineTable: + // Build the map natively: navigate each (possibly dotted) key with + // plain Go map operations and decode each value with decodeAny. The + // seen-tracker has already rejected duplicate or conflicting keys, so + // intermediate parts can be created/merged without revalidation. + count := 0 + cit := n.Children() + for cit.Next() { + count++ } - - r = reflect.ValueOf(int8(i)) - case reflect.Int: - if i < minInt || i > maxInt { - return fmt.Errorf("toml: number %d does not fit in an int", i) + m := make(map[string]interface{}, count) + it := n.Children() + for it.Next() { + kv := it.Node() + if err := d.setAnyKey(m, kv.Key(), kv.Value()); err != nil { + return nil, err + } } - - r = reflect.ValueOf(int(i)) - case reflect.Uint64: - if i < 0 { - return fmt.Errorf("toml: negative number %d does not fit in an uint64", i) + return m, nil + case unstable.DateTime: + t, err := parseDateTime(n.Data) + return t, err + case unstable.LocalDateTime: + dt, rest, err := parseLocalDateTime(n.Data) + if err != nil { + return nil, err } - - r = reflect.ValueOf(uint64(i)) - case reflect.Uint32: - if i < 0 || i > math.MaxUint32 { - return fmt.Errorf("toml: negative number %d does not fit in an uint32", i) + if len(rest) > 0 { + return nil, unstable.NewParserError(rest, "extra characters at the end of a local date time") } - - r = reflect.ValueOf(uint32(i)) - case reflect.Uint16: - if i < 0 || i > math.MaxUint16 { - return fmt.Errorf("toml: negative number %d does not fit in an uint16", i) + return dt, nil + case unstable.LocalDate: + date, err := parseLocalDate(n.Data) + return date, err + case unstable.LocalTime: + t, rest, err := parseLocalTime(n.Data) + if err != nil { + return nil, err } - - r = reflect.ValueOf(uint16(i)) - case reflect.Uint8: - if i < 0 || i > math.MaxUint8 { - return fmt.Errorf("toml: negative number %d does not fit in an uint8", i) + if len(rest) > 0 { + return nil, unstable.NewParserError(rest, "extra characters at the end of a local time") } - - r = reflect.ValueOf(uint8(i)) - case reflect.Uint: - if i < 0 || i > maxUint { - return fmt.Errorf("toml: negative number %d does not fit in an uint", i) - } - - r = reflect.ValueOf(uint(i)) - case reflect.Interface: - r = reflect.ValueOf(i) + return t, nil default: - return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("integer", v.Type())) - } - - if !r.Type().AssignableTo(v.Type()) { - r = r.Convert(v.Type()) - } - - v.Set(r) - - return nil -} - -func (d *decoder) unmarshalString(value *unstable.Node, v reflect.Value) error { - switch v.Kind() { - case reflect.String: - v.SetString(string(value.Data)) - case reflect.Interface: - v.Set(reflect.ValueOf(string(value.Data))) - default: - return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("string", v.Type())) - } - - return nil -} - -func (d *decoder) handleKeyValue(expr *unstable.Node, v reflect.Value) (reflect.Value, error) { - d.strict.EnterKeyValue(expr) - - v, err := d.handleKeyValueInner(expr.Key(), expr.Value(), v) - if d.skipUntilTable { - d.strict.MissingField(expr) - d.skipUntilTable = false - } - - d.strict.ExitKeyValue(expr) - - return v, err -} - -func (d *decoder) handleKeyValueInner(key unstable.Iterator, value *unstable.Node, v reflect.Value) (reflect.Value, error) { - if key.Next() { - // Still scoping the key - return d.handleKeyValuePart(key, value, v) - } - // Done scoping the key. - // v is whatever Go value we need to fill. - return reflect.Value{}, d.handleValue(value, v) -} - -func (d *decoder) keyFromData(keyType reflect.Type, data []byte) (reflect.Value, error) { - switch { - case stringType.AssignableTo(keyType): - return reflect.ValueOf(string(data)), nil - - case stringType.ConvertibleTo(keyType): - return reflect.ValueOf(string(data)).Convert(keyType), nil - - case keyType.Implements(textUnmarshalerType): - mk := reflect.New(keyType.Elem()) - if err := mk.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { - return reflect.Value{}, fmt.Errorf("toml: error unmarshalling key type %s from text: %w", stringType, err) - } - return mk, nil - - case reflect.PointerTo(keyType).Implements(textUnmarshalerType): - mk := reflect.New(keyType) - if err := mk.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { - return reflect.Value{}, fmt.Errorf("toml: error unmarshalling key type %s from text: %w", stringType, err) - } - return mk.Elem(), nil - } - - switch keyType.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - key, err := strconv.ParseInt(string(data), 10, 64) - if err != nil { - return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from integer: %w", stringType, err) - } - return reflect.ValueOf(key).Convert(keyType), nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - key, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from unsigned integer: %w", stringType, err) - } - return reflect.ValueOf(key).Convert(keyType), nil - - case reflect.Float32: - key, err := strconv.ParseFloat(string(data), 32) - if err != nil { - return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from float: %w", stringType, err) - } - return reflect.ValueOf(float32(key)), nil - - case reflect.Float64: - key, err := strconv.ParseFloat(string(data), 64) - if err != nil { - return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from float: %w", stringType, err) - } - return reflect.ValueOf(float64(key)), nil - - default: - return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", stringType, keyType) + return nil, unstable.NewParserError(n.Data, "unsupported value kind %s", n.Kind) } } -func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node, v reflect.Value) (reflect.Value, error) { - // contains the replacement for v - var rv reflect.Value - - // First, dispatch over v to make sure it is a valid object. - // There is no guarantee over what it could be. +func (d *decoder) assignInlineTable(v reflect.Value, expr *unstable.Node, value *unstable.Node) (reflect.Value, error) { switch v.Kind() { case reflect.Map: - vt := v.Type() - - mk, err := d.keyFromData(vt.Key(), key.Node().Data) + // Inline tables are self-contained: they fully replace the target. + v = reflect.MakeMap(v.Type()) + case reflect.Struct: + // fields are set in place + case reflect.Interface: + elem := reflect.ValueOf(map[string]interface{}{}) + nv, err := d.assignInlineTable(elem, expr, value) if err != nil { return reflect.Value{}, err } + return boxInto(v, nv) + default: + return reflect.Value{}, d.typeMismatchError("inline table", v.Type(), d.rawValue(expr, value)) + } - // If the map does not exist, create it. - if v.IsNil() { - v = reflect.MakeMap(vt) - rv = v + it := value.Children() + for it.Next() { + kv := it.Node() + // Build the path from the key of this key-value. Keys of inline + // tables rarely have more than a few parts. + var pathBuf [4]pathPart + path := pathBuf[:0] + kit := kv.Key() + for kit.Next() { + path = append(path, pathPart{node: kit.Node()}) } - - mv := v.MapIndex(mk) - set := false - if !mv.IsValid() || key.IsLast() { - set = true - mv = reflect.New(v.Type().Elem()).Elem() - } - - nv, err := d.handleKeyValueInner(key, value, mv) + nv, err := d.descend(v, path, 0, kv, kv.Value()) if err != nil { return reflect.Value{}, err } if nv.IsValid() { - mv = nv - set = true + v = nv } + } + return v, nil +} - if set { - v.SetMapIndex(mk, mv) +// boxInto returns the value to store in place of the interface value v. The +// caller stores the result in the slot v was found in, which performs the +// interface conversion, so the concrete value can be returned as-is. +func boxInto(v reflect.Value, c reflect.Value) (reflect.Value, error) { + if !c.Type().AssignableTo(v.Type()) { + return reflect.Value{}, fmt.Errorf("toml: cannot store %s into %s", c.Type(), v.Type()) + } + return c, nil +} + +var ( + interfaceType = reflect.TypeOf(new(interface{})).Elem() + localDateType = reflect.TypeOf(LocalDate{}) + localTimeType = reflect.TypeOf(LocalTime{}) + localDateTimeType = reflect.TypeOf(LocalDateTime{}) +) + +// structPlan caches the mapping between TOML keys and the fields of a struct +// type. byFold, keyed by the lowercased name, resolves any key on its own when +// no two fields fold to the same name (the overwhelmingly common case, marked +// by hasCollision == false): TOML keys are usually lowercase and never match +// the exact (capitalized) Go field names, so the byName probe was always a +// wasted lookup. byName (the exact names) is only consulted, first, when +// fields do collide under folding, to preserve the exact-match-wins tiebreak. +type structPlan struct { + byName map[string]structField + byFold map[string]structField + hasCollision bool +} + +type structField struct { + index []int + fieldName string +} + +// foldBufSize bounds the stack buffer used to lowercase keys without +// allocating. Keys longer than this (extremely rare) take the strings.ToLower +// fallback. +const foldBufSize = 68 + +// lookup and lookupBytes keep the hot path to a single inlinable byFold lookup. +// byFold is indexed by both the exact field/tag names and their lowercased +// forms, so that lookup resolves the two common cases — a lowercase key, or a +// key matching the field's own casing — directly. byName is consulted first +// only for types whose fields collide under case-folding, to preserve the +// exact-match-wins tiebreak. The buffer-fold for other casings lives +// out-of-line so it does not bloat the hot path. +func (p *structPlan) lookup(name string) (structField, bool) { + if p.hasCollision { + if f, ok := p.byName[name]; ok { + return f, true } - case reflect.Struct: - path, found := structFieldPath(v, string(key.Node().Data)) - if !found { - // If no matching struct field is found but the target implements the - // unstable.Unmarshaler interface (and it is enabled), delegate the - // decoding of this value to the custom unmarshaler. - if d.unmarshalerInterface { - if v.CanAddr() && v.Addr().CanInterface() { - if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok { - // Pass raw bytes from the original document - return reflect.Value{}, outi.UnmarshalTOML(d.p.Raw(value.Raw)) - } - } + } + if f, ok := p.byFold[name]; ok { + return f, true + } + return p.lookupFoldStr(name) +} + +func (p *structPlan) lookupBytes(name []byte) (structField, bool) { + if p.hasCollision { + if f, ok := p.byName[string(name)]; ok { // does not allocate + return f, true + } + } + if f, ok := p.byFold[string(name)]; ok { // does not allocate + return f, true + } + return p.lookupFold(name) +} + +// lookupFold resolves keys whose casing matches neither the exact nor the +// lowercased index: it folds to lowercase (in a stack buffer for ASCII, so no +// allocation) and retries; only non-ASCII or oversized keys hit strings.ToLower. +func (p *structPlan) lookupFold(name []byte) (structField, bool) { + if len(name) <= foldBufSize { + // Fold into a stack buffer: len(name) <= cap(buf), so the append + // never reallocates and nothing escapes to the heap. + var buf [foldBufSize]byte + b := buf[:0] + ascii := true + for _, c := range name { + if c >= 0x80 { + ascii = false + break } - // Otherwise, keep previous behavior and skip until the next table. - d.skipUntilTable = true - break - } - - if d.errorContext == nil { - d.errorContext = new(errorContext) - } - t := v.Type() - d.errorContext.Struct = t - d.errorContext.Field = path - - f := fieldByIndex(v, path) - - if !f.CanAddr() { - // If the field is not addressable, need to take a slower path and - // make a copy of the struct itself to a new location. - nvp := reflect.New(v.Type()) - nvp.Elem().Set(v) - v = nvp.Elem() - _, err := d.handleKeyValuePart(key, value, v) - if err != nil { - return reflect.Value{}, err + if c >= 'A' && c <= 'Z' { + c += 'a' - 'A' } - return nvp.Elem(), nil + b = append(b, c) } - x, err := d.handleKeyValueInner(key, value, f) - if err != nil { - return reflect.Value{}, err + if ascii { + f, ok := p.byFold[string(b)] // does not allocate + return f, ok } - - if x.IsValid() { - f.Set(x) - } - d.errorContext.Struct = nil - d.errorContext.Field = nil - case reflect.Interface: - v = v.Elem() - - // Following encoding/json: decoding an object into an - // interface{}, it needs to always hold a - // map[string]interface{}. This is for the types to be - // consistent whether a previous value was set or not. - if !v.IsValid() || v.Type() != mapStringInterfaceType { - v = makeMapStringInterface() - } - - x, err := d.handleKeyValuePart(key, value, v) - if err != nil { - return reflect.Value{}, err - } - if x.IsValid() { - v = x - } - rv = v - case reflect.Ptr: - elem := v.Elem() - if !elem.IsValid() { - ptr := reflect.New(v.Type().Elem()) - v.Set(ptr) - rv = v - elem = ptr.Elem() - } - - elem2, err := d.handleKeyValuePart(key, value, elem) - if err != nil { - return reflect.Value{}, err - } - if elem2.IsValid() { - elem = elem2 - } - v.Elem().Set(elem) - default: - return reflect.Value{}, fmt.Errorf("unhandled kv part: %s", v.Kind()) } - - return rv, nil + f, ok := p.byFold[strings.ToLower(string(name))] + return f, ok } -func initAndDereferencePointer(v reflect.Value) reflect.Value { - var elem reflect.Value - if v.IsNil() { - ptr := reflect.New(v.Type().Elem()) - v.Set(ptr) - } - elem = v.Elem() - return elem -} - -// Same as reflect.Value.FieldByIndex, but creates pointers if needed. -func fieldByIndex(v reflect.Value, path []int) reflect.Value { - for _, x := range path { - v = v.Field(x) - - if v.Kind() == reflect.Ptr { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) +func (p *structPlan) lookupFoldStr(name string) (structField, bool) { + if len(name) <= foldBufSize { + // Fold into a stack buffer: len(name) <= cap(buf), so the append + // never reallocates and nothing escapes to the heap. + var buf [foldBufSize]byte + b := buf[:0] + ascii := true + for i := 0; i < len(name); i++ { + c := name[i] + if c >= 0x80 { + ascii = false + break } - v = v.Elem() + if c >= 'A' && c <= 'Z' { + c += 'a' - 'A' + } + b = append(b, c) + } + if ascii { + f, ok := p.byFold[string(b)] // does not allocate + return f, ok } } - return v + f, ok := p.byFold[strings.ToLower(name)] + return f, ok } -type fieldPathsMap = map[string][]int +var structPlans sync.Map // reflect.Type -> *structPlan -var globalFieldPathsCache atomic.Value // map[reflect.Type]fieldPathsMap - -func structFieldPath(v reflect.Value, name string) ([]int, bool) { - t := v.Type() - - cache, _ := globalFieldPathsCache.Load().(map[reflect.Type]fieldPathsMap) - fieldPaths, ok := cache[t] - - if !ok { - fieldPaths = map[string][]int{} - - forEachField(t, nil, func(name string, path []int) { - fieldPaths[name] = path - // extra copy for the case-insensitive match - fieldPaths[strings.ToLower(name)] = path - }) - - newCache := make(map[reflect.Type]fieldPathsMap, len(cache)+1) - newCache[t] = fieldPaths - for k, v := range cache { - newCache[k] = v - } - globalFieldPathsCache.Store(newCache) +func planForType(t reflect.Type) *structPlan { + if plan, ok := structPlans.Load(t); ok { + return plan.(*structPlan) } - - path, ok := fieldPaths[name] - if !ok { - path, ok = fieldPaths[strings.ToLower(name)] - } - return path, ok + plan := buildPlan(t) + structPlans.Store(t, plan) + return plan } -func forEachField(t reflect.Type, path []int, do func(name string, path []int)) { - n := t.NumField() - for i := 0; i < n; i++ { +func buildPlan(t reflect.Type) *structPlan { + plan := &structPlan{ + byName: map[string]structField{}, + byFold: map[string]structField{}, + } + addFields(plan, t, nil, map[reflect.Type]bool{}) + return plan +} + +// addFields flattens the fields of t into the plan. visited holds the types +// being flattened on the current branch: a struct type that embeds itself +// (directly or through other types) is not descended into again, mirroring +// buildEncPlan. Without this guard a recursive embedding would recurse +// forever; the repeated fields are unreachable by flattening anyway. +func addFields(plan *structPlan, t reflect.Type, prefix []int, visited map[reflect.Type]bool) { + if visited[t] { + return + } + visited[t] = true + defer delete(visited, t) + + var embedded []reflect.StructField + for i := 0; i < t.NumField(); i++ { f := t.Field(i) - - if !f.Anonymous && f.PkgPath != "" { - // only consider exported fields. - continue - } - - fieldPath := make([]int, 0, len(path)+1) - fieldPath = append(fieldPath, path...) - fieldPath = append(fieldPath, i) - fieldPath = fieldPath[:len(fieldPath):len(fieldPath)] - - name := f.Tag.Get("toml") - if name == "-" { - continue - } - - if i := strings.IndexByte(name, ','); i >= 0 { - name = name[:i] - } - - if f.Anonymous && name == "" { - t2 := f.Type - if t2.Kind() == reflect.Ptr { - t2 = t2.Elem() + tag, tagged := f.Tag.Lookup("toml") + name := f.Name + explicitName := "" + if tagged { + // A tag of exactly "-" drops the field. "-," names it "-". + if tag == "-" { + continue } - - if t2.Kind() == reflect.Struct { - forEachField(t2, fieldPath, do) + parts := strings.SplitN(tag, ",", 2) + explicitName = parts[0] + if explicitName != "" { + name = explicitName } + } + if f.Anonymous { + ft := f.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + if ft.Kind() != reflect.Struct { + // Embedded non-struct fields are not decoded into. + continue + } + if explicitName == "" { + // Embedded structs without an explicit tag name are flattened, + // even when their type is unexported: only their own exported + // fields are reachable. A tag that only sets options (e.g. + // `,inline`) still flattens, matching encoding/json and the + // encoder's behavior. + embedded = append(embedded, f) + continue + } + // An embedded struct given an explicit tag name acts as a regular + // named field. + } else if f.PkgPath != "" { + // unexported continue } - - if name == "" { - name = f.Name + index := make([]int, 0, len(prefix)+1) + index = append(index, prefix...) + index = append(index, i) + sf := structField{index: index, fieldName: f.Name} + if _, ok := plan.byName[name]; !ok { + plan.byName[name] = sf } - - do(name, fieldPath) + lower := strings.ToLower(name) + if _, ok := plan.byFold[lower]; !ok { + plan.byFold[lower] = sf + } else { + // Two distinct fields fold to the same name: case-insensitive + // matching is ambiguous, so lookups must consult byName first to + // keep the exact-match-wins tiebreak deterministic. + plan.hasCollision = true + } + // Index the exact (cased) name as well, so a key written with the + // field's own casing resolves in a single byFold lookup. Only fields + // whose name is not already lowercase need this extra entry. Any name + // that would conflict here also collides under folding (handled + // above), so byName-first preserves the exact tiebreak in that case. + if name != lower { + if _, ok := plan.byFold[name]; !ok { + plan.byFold[name] = sf + } + } + } + // Embedded structs are flattened after the regular fields, so that + // shallower fields win. + for _, f := range embedded { + ft := f.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + index := make([]int, 0, len(prefix)+1) + index = append(index, prefix...) + idx := f.Index[0] + index = append(index, idx) + addFields(plan, ft, index, visited) } } + +// fieldByIndexAlloc returns the field of v at the given index path, +// allocating intermediate embedded pointers as needed. +func fieldByIndexAlloc(v reflect.Value, index []int) (reflect.Value, error) { + // Fast path for non-embedded fields, which have a single-element index: + // no intermediate pointer dereferencing is possible. + if len(index) == 1 { + return v.Field(index[0]), nil + } + for i, x := range index { + if i > 0 { + for v.Kind() == reflect.Ptr { + if v.IsNil() { + if !v.CanSet() { + // A nil embedded pointer of unexported type cannot be + // allocated: reflect forbids setting it. Match + // encoding/json and report it instead of panicking. + return reflect.Value{}, fmt.Errorf("toml: cannot set embedded pointer to unexported struct: %s", v.Type().Elem()) + } + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + } + v = v.Field(x) + } + return v, nil +} diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go b/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go index 6b21592d6..2cf3bdb6d 100644 --- a/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go +++ b/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go @@ -17,43 +17,30 @@ import ( // // do something with n // } type Iterator struct { - nodes *[]Node - idx int32 started bool + node *Node } -// Next moves the iterator forward and returns true if points to a -// node, false otherwise. +// Next moves the iterator forward and returns true if points to a node, false +// otherwise. func (c *Iterator) Next() bool { - if c.nodes == nil { - return false - } - nodes := *c.nodes if !c.started { c.started = true - } else { - idx := c.idx - if idx >= 0 && int(idx) < len(nodes) { - c.idx = nodes[idx].next - } + } else if c.node.Valid() { + c.node = c.node.Next() } - return c.idx >= 0 && int(c.idx) < len(nodes) + return c.node.Valid() } // IsLast returns true if the current node of the iterator is the last -// one. Subsequent calls to Next() will return false. +// one. Subsequent calls to Next() will return false. func (c *Iterator) IsLast() bool { - return c.nodes == nil || c.idx < 0 || (*c.nodes)[c.idx].next < 0 + return c.node.next == 0 } // Node returns a pointer to the node pointed at by the iterator. func (c *Iterator) Node() *Node { - if c.nodes == nil || c.idx < 0 { - return nil - } - n := &(*c.nodes)[c.idx] - n.nodes = c.nodes - return n + return c.node } // Node in a TOML expression AST. @@ -64,8 +51,8 @@ func (c *Iterator) Node() *Node { // - Array have one child per element in the array. // - InlineTable have one child per key-value in the table (each of kind // InlineTable). -// - KeyValue have at least two children. The first one is the value. The rest -// make a potentially dotted key. +// - KeyValue have at least two children. The first one is the value. The +// rest make a potentially dotted key. // - Table and ArrayTable's children represent a dotted key (same as // KeyValue, but without the first node being the value). // @@ -76,68 +63,56 @@ type Node struct { Raw Range // Raw bytes from the input. Data []byte // Node value (either allocated or referencing the input). - // Absolute indices into the backing nodes slice. -1 means none. - next int32 - child int32 - - // Reference to the backing nodes slice for navigation. - nodes *[]Node -} - -// Range of bytes in the document. -type Range struct { - Offset uint32 - Length uint32 + // References to other nodes, as 1-based indexes into the parser's arena. + // 0 means no node. + parser *Parser + next int32 + child int32 } // Next returns a pointer to the next node, or nil if there is no next node. func (n *Node) Next() *Node { - if n.next < 0 { + if n.next == 0 { return nil } - next := &(*n.nodes)[n.next] - next.nodes = n.nodes - return next + return &n.parser.nodes[n.next-1] } // Child returns a pointer to the first child node of this node. Other children -// can be accessed calling Next on the first child. Returns nil if this Node -// has no child. +// can be accessed calling Next on the first child. Returns nil if there is no +// child node. func (n *Node) Child() *Node { - if n.child < 0 { + if n.child == 0 { return nil } - child := &(*n.nodes)[n.child] - child.nodes = n.nodes - return child + return &n.parser.nodes[n.child-1] } // Valid returns true if the node's kind is set (not to Invalid). func (n *Node) Valid() bool { - return n != nil + return n != nil && n.Kind != Invalid } // Key returns the children nodes making the Key on a supported node. Panics -// otherwise. They are guaranteed to be all be of the Kind Key. A simple key +// otherwise. They are guaranteed to be all be of the Kind Key. A simple key // would return just one element. func (n *Node) Key() Iterator { switch n.Kind { case KeyValue: - child := n.child - if child < 0 { + value := n.Child() + if !value.Valid() { panic(errors.New("KeyValue should have at least two children")) } - valueNode := &(*n.nodes)[child] - return Iterator{nodes: n.nodes, idx: valueNode.next} + return Iterator{node: value.Next()} case Table, ArrayTable: - return Iterator{nodes: n.nodes, idx: n.child} + return Iterator{node: n.Child()} default: panic(fmt.Errorf("Key() is not supported on a %s", n.Kind)) } } // Value returns a pointer to the value node of a KeyValue. -// Guaranteed to be non-nil. Panics if not called on a KeyValue node, +// Guaranteed to be non-nil. Panics if not called on a KeyValue node, // or if the Children are malformed. func (n *Node) Value() *Node { return n.Child() @@ -145,5 +120,5 @@ func (n *Node) Value() *Node { // Children returns an iterator over a node's children. func (n *Node) Children() Iterator { - return Iterator{nodes: n.nodes, idx: n.child} + return Iterator{node: n.Child()} } diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/bridge.go b/vendor/github.com/pelletier/go-toml/v2/unstable/bridge.go new file mode 100644 index 000000000..5482bde0b --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/v2/unstable/bridge.go @@ -0,0 +1,21 @@ +package unstable + +import "github.com/pelletier/go-toml/v2/internal/parserbridge" + +// Expose the non-AST scanners to the root toml package without committing to +// them in the public API. See internal/parserbridge for the rationale. +// +//nolint:gochecknoinits // load-time wiring of an internal bridge (see internal/parserbridge) +func init() { + parserbridge.ScanScalar = func(p any, b []byte) (kind int, raw, value, rest []byte, err error) { + k, raw, value, rest, err := p.(*Parser).scanScalar(b) + return int(k), raw, value, rest, err + } + parserbridge.ScanKey = func(p any, b []byte, dst [][]byte) (parts [][]byte, raw, rest []byte, err error) { + return p.(*Parser).scanKey(b, dst) + } + parserbridge.ScanComment = scanComment + parserbridge.ParseValue = func(p any, b []byte) (node any, rest []byte, err error) { + return p.(*Parser).parseValue(b) + } +} diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go b/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go deleted file mode 100644 index e4354985b..000000000 --- a/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go +++ /dev/null @@ -1,64 +0,0 @@ -package unstable - -// root contains a full AST. -// -// It is immutable once constructed with Builder. -type root struct { - nodes []Node -} - -func (r *root) at(idx reference) *Node { - return &r.nodes[idx] -} - -type reference int - -const invalidReference reference = -1 - -func (r reference) Valid() bool { - return r != invalidReference -} - -type builder struct { - tree root - lastIdx int -} - -func (b *builder) NodeAt(ref reference) *Node { - n := b.tree.at(ref) - n.nodes = &b.tree.nodes - return n -} - -func (b *builder) Reset() { - b.tree.nodes = b.tree.nodes[:0] - b.lastIdx = 0 -} - -func (b *builder) Push(n Node) reference { - b.lastIdx = len(b.tree.nodes) - n.next = -1 - n.child = -1 - b.tree.nodes = append(b.tree.nodes, n) - return reference(b.lastIdx) -} - -func (b *builder) PushAndChain(n Node) reference { - newIdx := len(b.tree.nodes) - n.next = -1 - n.child = -1 - b.tree.nodes = append(b.tree.nodes, n) - if b.lastIdx >= 0 { - b.tree.nodes[b.lastIdx].next = int32(newIdx) //nolint:gosec // TOML ASTs are small - } - b.lastIdx = newIdx - return reference(b.lastIdx) -} - -func (b *builder) AttachChild(parent reference, child reference) { - b.tree.nodes[parent].child = int32(child) //nolint:gosec // TOML ASTs are small -} - -func (b *builder) Chain(from reference, to reference) { - b.tree.nodes[from].next = int32(to) //nolint:gosec // TOML ASTs are small -} diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go b/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go index f87a95a78..f1912f77b 100644 --- a/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go +++ b/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go @@ -33,7 +33,7 @@ const ( Float // Integer represents an integer value. Integer - // LocalDate represents a a local date value. + // LocalDate represents a local date value. LocalDate // LocalTime represents a local time value. LocalTime @@ -79,5 +79,5 @@ func (k Kind) String() string { case DateTime: return "DateTime" } - panic(fmt.Errorf("Kind.String() not implemented for '%d'", k)) + panic(fmt.Errorf("Kind.String() not implemented for kind %d", int(k))) } diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/marshaler.go b/vendor/github.com/pelletier/go-toml/v2/unstable/marshaler.go new file mode 100644 index 000000000..40c2e9780 --- /dev/null +++ b/vendor/github.com/pelletier/go-toml/v2/unstable/marshaler.go @@ -0,0 +1,29 @@ +package unstable + +// Marshaler is implemented by types that can marshal themselves into a raw +// TOML description. The returned bytes are spliced verbatim into the encoded +// document, so they must be valid TOML for the position they end up in: +// +// - A single value (string, integer, array, inline table, …) is emitted +// inline, as in `key = `. +// - One or more key-value lines (optionally with relative sub-table headers) +// is emitted as the body of a `[key]` table. +// - At the document root, the bytes are emitted as the whole document. +// +// The encoder decides between those forms by parsing the returned bytes, and +// reports an error when they are not valid TOML for their position; see +// Encoder.EnableMarshalerInterface in the root toml package. MarshalTOML can +// be called more than once for the same value during a single encode, so it +// must be deterministic. +// +// Marshaler is the encoding counterpart of Unmarshaler. +type Marshaler interface { + MarshalTOML() ([]byte, error) +} + +// MarshalTOML implements Marshaler. It returns the raw TOML bytes verbatim, +// mirroring json.RawMessage.MarshalJSON. The value receiver means both +// RawMessage and *RawMessage satisfy Marshaler. +func (m RawMessage) MarshalTOML() ([]byte, error) { + return []byte(m), nil +} diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go b/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go index 153830123..cf72bb744 100644 --- a/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go +++ b/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go @@ -2,11 +2,10 @@ package unstable import ( "bytes" + "encoding/binary" + "errors" "fmt" - "reflect" - "unicode" - - "github.com/pelletier/go-toml/v2/internal/characters" + "unicode/utf8" ) // ParserError describes an error relative to the content of the document. @@ -43,23 +42,34 @@ func NewParserError(highlight []byte, format string, args ...interface{}) error // Don't forget to check Error() after you're done parsing. // // Each top-level expression needs to be fully processed before calling -// NextExpression() again. Otherwise, calls to various Node methods may panic if -// the parser has moved on the next expression. +// NextExpression() again. Otherwise, calls to various Node methods may panic +// if the parser has moved on the next expression. // // For performance reasons, go-toml doesn't make a copy of the input bytes to // the parser. Make sure to copy all the bytes you need to outlive the slice // given to the parser. type Parser struct { - data []byte - builder builder - ref reference - left []byte - err error - first bool - KeepComments bool + + data []byte + left []byte + nodes []Node + err error + + // nesting is the current depth of nested arrays and inline tables being + // parsed. It guards parseVal/parseValArray/parseInlineTable against + // unbounded mutual recursion, which would otherwise let a deeply nested + // document overflow the goroutine stack (an unrecoverable fatal error). + nesting int } +// maxValueNesting is the maximum depth of nested arrays and inline tables the +// parser accepts. Beyond it, parsing fails with a ParserError instead of +// risking a stack overflow. Real-world TOML documents nest only a handful of +// levels deep, so this bound is generous; it matches the limit used by the +// standard library's encoding/json. +const maxValueNesting = 10000 + // Data returns the slice provided to the last call to Reset. func (p *Parser) Data() []byte { return p.data @@ -69,35 +79,20 @@ func (p *Parser) Data() []byte { // input. If the argument is not a subslice of the parser input, this function // panics. func (p *Parser) Range(b []byte) Range { + // b is a subslice of p.data if and only if they share the same backing + // array. In that case, because subslicing cannot extend capacity, the + // number of bytes between the start of b and the end of the backing array + // (its capacity) identifies the offset of b within data. + offset := cap(p.data) - cap(b) + if offset < 0 || offset+len(b) > len(p.data) { + panic(errors.New("not a slice of the data slice")) + } return Range{ - Offset: uint32(p.subsliceOffset(b)), //nolint:gosec // TOML documents are small - Length: uint32(len(b)), //nolint:gosec // TOML documents are small + Offset: uint32(offset), //nolint:gosec // TOML documents are small + Length: uint32(len(b)), //nolint:gosec // TOML documents are small } } -// rangeOfToken computes the Range of a token given the remaining bytes after the token. -// This is used when the token was extracted from the beginning of some position, -// and 'rest' is what remains after the token. -func (p *Parser) rangeOfToken(token, rest []byte) Range { - offset := len(p.data) - len(token) - len(rest) - return Range{Offset: uint32(offset), Length: uint32(len(token))} //nolint:gosec // TOML documents are small -} - -// subsliceOffset returns the byte offset of subslice b within p.data. -// b must share the same backing array as p.data. -func (p *Parser) subsliceOffset(b []byte) int { - if len(b) == 0 { - return len(p.data) - } - dataPtr := reflect.ValueOf(p.data).Pointer() - subPtr := reflect.ValueOf(b).Pointer() - offset := int(subPtr - dataPtr) - if offset < 0 || offset > len(p.data) { - panic("subslice is not within data") - } - return offset -} - // Raw returns the slice corresponding to the bytes in the given range. func (p *Parser) Raw(raw Range) []byte { return p.data[raw.Offset : raw.Offset+raw.Length] @@ -106,58 +101,11 @@ func (p *Parser) Raw(raw Range) []byte { // Reset brings the parser to its initial state for a given input. It wipes an // reuses internal storage to reduce allocation. func (p *Parser) Reset(b []byte) { - p.builder.Reset() - p.ref = invalidReference p.data = b p.left = b + p.nodes = p.nodes[:0] p.err = nil - p.first = true -} - -// NextExpression parses the next top-level expression. If an expression was -// successfully parsed, it returns true. If the parser is at the end of the -// document or an error occurred, it returns false. -// -// Retrieve the parsed expression with Expression(). -func (p *Parser) NextExpression() bool { - if len(p.left) == 0 || p.err != nil { - return false - } - - p.builder.Reset() - p.ref = invalidReference - - for { - if len(p.left) == 0 || p.err != nil { - return false - } - - if !p.first { - p.left, p.err = p.parseNewline(p.left) - } - - if len(p.left) == 0 || p.err != nil { - return false - } - - p.ref, p.left, p.err = p.parseExpression(p.left) - - if p.err != nil { - return false - } - - p.first = false - - if p.ref.Valid() { - return true - } - } -} - -// Expression returns a pointer to the node representing the last successfully -// parsed expression. -func (p *Parser) Expression() *Node { - return p.builder.NodeAt(p.ref) + p.nesting = 0 } // Error returns any error that has occurred during parsing. @@ -165,6 +113,12 @@ func (p *Parser) Error() error { return p.err } +// Range of bytes in the document. +type Range struct { + Offset uint32 + Length uint32 +} + // Position describes a position in the input. type Position struct { // Number of bytes from the beginning of the input. @@ -181,1095 +135,1552 @@ type Shape struct { End Position } +func (p *Parser) position(offset int) Position { + pos := Position{ + Offset: offset, + Line: 1, + Column: 1, + } + b := p.data[:offset] + for { + idx := bytes.IndexByte(b, '\n') + if idx < 0 { + break + } + pos.Line++ + b = b[idx+1:] + } + pos.Column = len(b) + 1 + return pos +} + // Shape returns the shape of the given range in the input. Will // panic if the range is not a subslice of the input. func (p *Parser) Shape(r Range) Shape { + raw := p.Raw(r) return Shape{ - Start: p.positionAt(int(r.Offset)), - End: p.positionAt(int(r.Offset + r.Length)), + Start: p.position(int(r.Offset)), + End: p.position(int(r.Offset) + len(raw)), } } -// positionAt returns the position at the given byte offset in the document. -func (p *Parser) positionAt(offset int) Position { - lead := p.data[:offset] +// Expression returns a pointer to the node representing the last successfully +// parsed expression. +func (p *Parser) Expression() *Node { + if len(p.nodes) == 0 { + return nil + } + return &p.nodes[0] +} - return Position{ - Offset: offset, - Line: bytes.Count(lead, []byte{'\n'}) + 1, - Column: len(lead) - bytes.LastIndex(lead, []byte{'\n'}), +// push appends a node to the arena and returns its handle (1-based index). +func (p *Parser) push(n Node) int32 { + if len(p.nodes) == cap(p.nodes) { + // Grow by 2x: large expressions (huge arrays) would otherwise grow + // the arena in small steps, copying it repeatedly. + newCap := 2 * cap(p.nodes) + if newCap < 64 { + newCap = 64 + } + nodes := make([]Node, len(p.nodes), newCap) + copy(nodes, p.nodes) + p.nodes = nodes + } + n.parser = p + p.nodes = append(p.nodes, n) + return int32(len(p.nodes)) //nolint:gosec // node counts are bounded by document size +} + +// at returns a pointer to the node with the given handle. Only valid until +// the next call to push. +func (p *Parser) at(handle int32) *Node { + return &p.nodes[handle-1] +} + +// offsetOf returns the offset of b within the parser's data. b must be a +// subslice of p.data. +func (p *Parser) offsetOf(b []byte) int { + return cap(p.data) - cap(b) +} + +// rangeFrom returns the Range covering bytes from the start of `from` to the +// start of `to`. Both must be subslices of p.data. +func (p *Parser) rangeFrom(from, to []byte) Range { + start := p.offsetOf(from) + end := p.offsetOf(to) + return Range{ + Offset: uint32(start), //nolint:gosec // TOML documents are small + Length: uint32(end - start), //nolint:gosec // TOML documents are small } } -func (p *Parser) parseNewline(b []byte) ([]byte, error) { - if b[0] == '\n' { - return b[1:], nil +// NextExpression parses the next top-level expression. If an expression was +// successfully parsed, it returns true. If the parser is at the end of the +// document or an error occurred, it returns false. +// +// Retrieve the parsed expression with Expression(). +func (p *Parser) NextExpression() bool { + if p.err != nil { + return false } - if b[0] == '\r' { - _, rest, err := scanWindowsNewline(b) - return rest, err - } - - return nil, NewParserError(b[0:1], "expected newline but got %#U", b[0]) -} - -func (p *Parser) parseComment(b []byte) (reference, []byte, error) { - ref := invalidReference - data, rest, err := scanComment(b) - if p.KeepComments && err == nil { - ref = p.builder.Push(Node{ - Kind: Comment, - Raw: p.rangeOfToken(data, rest), - Data: data, - }) - } - return ref, rest, err -} - -func (p *Parser) parseExpression(b []byte) (reference, []byte, error) { - // expression = ws [ comment ] - // expression =/ ws keyval ws [ comment ] - // expression =/ ws table ws [ comment ] - ref := invalidReference - - b = p.parseWhitespace(b) - - if len(b) == 0 { - return ref, b, nil - } - - if b[0] == '#' { - ref, rest, err := p.parseComment(b) - return ref, rest, err - } - - if b[0] == '\n' || b[0] == '\r' { - return ref, b, nil - } - - var err error - if b[0] == '[' { - ref, b, err = p.parseTable(b) - } else { - ref, b, err = p.parseKeyval(b) - } - - if err != nil { - return ref, nil, err - } - - b = p.parseWhitespace(b) - - if len(b) > 0 && b[0] == '#' { - cref, rest, err := p.parseComment(b) - if cref != invalidReference { - p.builder.Chain(ref, cref) - } - return ref, rest, err - } - - return ref, b, nil -} - -func (p *Parser) parseTable(b []byte) (reference, []byte, error) { - // table = std-table / array-table - if len(b) > 1 && b[1] == '[' { - return p.parseArrayTable(b) - } - - return p.parseStdTable(b) -} - -func (p *Parser) parseArrayTable(b []byte) (reference, []byte, error) { - // array-table = array-table-open key array-table-close - // array-table-open = %x5B.5B ws ; [[ Double left square bracket - // array-table-close = ws %x5D.5D ; ]] Double right square bracket - ref := p.builder.Push(Node{ - Kind: ArrayTable, - }) - - b = b[2:] - b = p.parseWhitespace(b) - - k, b, err := p.parseKey(b) - if err != nil { - return ref, nil, err - } - - p.builder.AttachChild(ref, k) - b = p.parseWhitespace(b) - - b, err = expect(']', b) - if err != nil { - return ref, nil, err - } - - b, err = expect(']', b) - - return ref, b, err -} - -func (p *Parser) parseStdTable(b []byte) (reference, []byte, error) { - // std-table = std-table-open key std-table-close - // std-table-open = %x5B ws ; [ Left square bracket - // std-table-close = ws %x5D ; ] Right square bracket - ref := p.builder.Push(Node{ - Kind: Table, - }) - - b = b[1:] - b = p.parseWhitespace(b) - - key, b, err := p.parseKey(b) - if err != nil { - return ref, nil, err - } - - p.builder.AttachChild(ref, key) - - b = p.parseWhitespace(b) - - b, err = expect(']', b) - - return ref, b, err -} - -func (p *Parser) parseKeyval(b []byte) (reference, []byte, error) { - // keyval = key keyval-sep val - // Track the start position for Raw range - startB := b - - ref := p.builder.Push(Node{ - Kind: KeyValue, - }) - - key, b, err := p.parseKey(b) - if err != nil { - return invalidReference, nil, err - } - - // keyval-sep = ws %x3D ws ; = - - b = p.parseWhitespace(b) - - if len(b) == 0 { - return invalidReference, nil, NewParserError(startB[:len(startB)-len(b)], "expected = after a key, but the document ends there") - } - - b, err = expect('=', b) - if err != nil { - return invalidReference, nil, err - } - - b = p.parseWhitespace(b) - - valRef, b, err := p.parseVal(b) - if err != nil { - return ref, b, err - } - - p.builder.Chain(valRef, key) - p.builder.AttachChild(ref, valRef) - - // Set Raw to span the entire key-value expression. - // Access the node directly in the slice to avoid the write barrier - // that NodeAt's nodes-pointer setup would trigger. - p.builder.tree.nodes[ref].Raw = p.rangeOfToken(startB[:len(startB)-len(b)], b) - - return ref, b, err -} - -//nolint:cyclop,funlen -func (p *Parser) parseVal(b []byte) (reference, []byte, error) { - // val = string / boolean / array / inline-table / date-time / float / integer - ref := invalidReference - - if len(b) == 0 { - return ref, nil, NewParserError(b, "expected value, not eof") - } - - var err error - c := b[0] - - switch c { - case '"': - var raw []byte - var v []byte - if scanFollowsMultilineBasicStringDelimiter(b) { - raw, v, b, err = p.parseMultilineBasicString(b) - } else { - raw, v, b, err = p.parseBasicString(b) - } - - if err == nil { - ref = p.builder.Push(Node{ - Kind: String, - Raw: p.rangeOfToken(raw, b), - Data: v, - }) - } - - return ref, b, err - case '\'': - var raw []byte - var v []byte - if scanFollowsMultilineLiteralStringDelimiter(b) { - raw, v, b, err = p.parseMultilineLiteralString(b) - } else { - raw, v, b, err = p.parseLiteralString(b) - } - - if err == nil { - ref = p.builder.Push(Node{ - Kind: String, - Raw: p.rangeOfToken(raw, b), - Data: v, - }) - } - - return ref, b, err - case 't': - if !scanFollowsTrue(b) { - return ref, nil, NewParserError(atmost(b, 4), "expected 'true'") - } - - ref = p.builder.Push(Node{ - Kind: Bool, - Data: b[:4], - }) - - return ref, b[4:], nil - case 'f': - if !scanFollowsFalse(b) { - return ref, nil, NewParserError(atmost(b, 5), "expected 'false'") - } - - ref = p.builder.Push(Node{ - Kind: Bool, - Data: b[:5], - }) - - return ref, b[5:], nil - case '[': - return p.parseValArray(b) - case '{': - return p.parseInlineTable(b) - default: - return p.parseIntOrFloatOrDateTime(b) - } -} - -func atmost(b []byte, n int) []byte { - if n >= len(b) { - return b - } - - return b[:n] -} - -func (p *Parser) parseLiteralString(b []byte) ([]byte, []byte, []byte, error) { - v, rest, err := scanLiteralString(b) - if err != nil { - return nil, nil, nil, err - } - - return v, v[1 : len(v)-1], rest, nil -} - -func (p *Parser) parseInlineTable(b []byte) (reference, []byte, error) { - // inline-table = inline-table-open [ inline-table-keyvals ] inline-table-close - // inline-table-open = %x7B ws ; { - // inline-table-close = ws %x7D ; } - // inline-table-sep = ws %x2C ws ; , Comma - // inline-table-keyvals = keyval [ inline-table-sep inline-table-keyvals ] - parent := p.builder.Push(Node{ - Kind: InlineTable, - Raw: p.rangeOfToken(b[:1], b[1:]), - }) - - first := true - - var child reference - - b = b[1:] - - var err error - - for len(b) > 0 { - previousB := b - b = p.parseWhitespace(b) - - if len(b) == 0 { - return parent, nil, NewParserError(previousB[:1], "inline table is incomplete") - } - - if b[0] == '}' { - break - } - - if !first { - b, err = expect(',', b) - if err != nil { - return parent, nil, err - } - b = p.parseWhitespace(b) - } - - var kv reference - - kv, b, err = p.parseKeyval(b) - if err != nil { - return parent, nil, err - } - - if first { - p.builder.AttachChild(parent, kv) - } else { - p.builder.Chain(child, kv) - } - child = kv - - first = false - } - - rest, err := expect('}', b) - - return parent, rest, err -} - -//nolint:funlen,cyclop -func (p *Parser) parseValArray(b []byte) (reference, []byte, error) { - // array = array-open [ array-values ] ws-comment-newline array-close - // array-open = %x5B ; [ - // array-close = %x5D ; ] - // array-values = ws-comment-newline val ws-comment-newline array-sep array-values - // array-values =/ ws-comment-newline val ws-comment-newline [ array-sep ] - // array-sep = %x2C ; , Comma - // ws-comment-newline = *( wschar / [ comment ] newline ) - arrayStart := b - b = b[1:] - - parent := p.builder.Push(Node{ - Kind: Array, - }) - - // First indicates whether the parser is looking for the first element - // (non-comment) of the array. - first := true - - lastChild := invalidReference - - addChild := func(valueRef reference) { - if lastChild == invalidReference { - p.builder.AttachChild(parent, valueRef) - } else { - p.builder.Chain(lastChild, valueRef) - } - lastChild = valueRef - } - - var err error - for len(b) > 0 { - var cref reference - cref, b, err = p.parseOptionalWhitespaceCommentNewline(b) - if err != nil { - return parent, nil, err - } - - if cref != invalidReference { - addChild(cref) - } - - if len(b) == 0 { - return parent, nil, NewParserError(arrayStart[:1], "array is incomplete") - } - - if b[0] == ']' { - break - } - - if b[0] == ',' { - if first { - return parent, nil, NewParserError(b[0:1], "array cannot start with comma") - } - b = b[1:] - - cref, b, err = p.parseOptionalWhitespaceCommentNewline(b) - if err != nil { - return parent, nil, err - } - if cref != invalidReference { - addChild(cref) - } - } else if !first { - return parent, nil, NewParserError(b[0:1], "array elements must be separated by commas") - } - - // TOML allows trailing commas in arrays. - if len(b) > 0 && b[0] == ']' { - break - } - - var valueRef reference - valueRef, b, err = p.parseVal(b) - if err != nil { - return parent, nil, err - } - - addChild(valueRef) - - cref, b, err = p.parseOptionalWhitespaceCommentNewline(b) - if err != nil { - return parent, nil, err - } - if cref != invalidReference { - addChild(cref) - } - - first = false - } - - rest, err := expect(']', b) - - return parent, rest, err -} - -func (p *Parser) parseOptionalWhitespaceCommentNewline(b []byte) (reference, []byte, error) { - rootCommentRef := invalidReference - latestCommentRef := invalidReference - - addComment := func(ref reference) { - switch { - case rootCommentRef == invalidReference: - rootCommentRef = ref - case latestCommentRef == invalidReference: - p.builder.AttachChild(rootCommentRef, ref) - latestCommentRef = ref - default: - p.builder.Chain(latestCommentRef, ref) - latestCommentRef = ref - } - } - - for len(b) > 0 { - var err error - b = p.parseWhitespace(b) - - if len(b) > 0 && b[0] == '#' { - var ref reference - ref, b, err = p.parseComment(b) - if err != nil { - return invalidReference, nil, err - } - if ref != invalidReference { - addComment(ref) - } - } - - if len(b) == 0 { - break - } - - if b[0] == '\n' || b[0] == '\r' { - b, err = p.parseNewline(b) - if err != nil { - return invalidReference, nil, err - } - } else { - break - } - } - - return rootCommentRef, b, nil -} - -func (p *Parser) parseMultilineLiteralString(b []byte) ([]byte, []byte, []byte, error) { - token, rest, err := scanMultilineLiteralString(b) - if err != nil { - return nil, nil, nil, err - } - - i := 3 - - // skip the immediate new line - if token[i] == '\n' { - i++ - } else if token[i] == '\r' && token[i+1] == '\n' { - i += 2 - } - - return token, token[i : len(token)-3], rest, err -} - -//nolint:funlen,gocognit,cyclop -func (p *Parser) parseMultilineBasicString(b []byte) ([]byte, []byte, []byte, error) { - // ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body - // ml-basic-string-delim - // ml-basic-string-delim = 3quotation-mark - // ml-basic-body = *mlb-content *( mlb-quotes 1*mlb-content ) [ mlb-quotes ] - // - // mlb-content = mlb-char / newline / mlb-escaped-nl - // mlb-char = mlb-unescaped / escaped - // mlb-quotes = 1*2quotation-mark - // mlb-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii - // mlb-escaped-nl = escape ws newline *( wschar / newline ) - token, escaped, rest, err := scanMultilineBasicString(b) - if err != nil { - return nil, nil, nil, err - } - - i := 3 - - // skip the immediate new line - if token[i] == '\n' { - i++ - } else if token[i] == '\r' && token[i+1] == '\n' { - i += 2 - } - - // fast path - startIdx := i - endIdx := len(token) - len(`"""`) - - if !escaped { - str := token[startIdx:endIdx] - highlight := characters.Utf8TomlValidAlreadyEscaped(str) - if len(highlight) == 0 { - return token, str, rest, nil - } - return nil, nil, nil, NewParserError(highlight, "invalid UTF-8") - } - - var builder bytes.Buffer - - // The scanner ensures that the token starts and ends with quotes and that - // escapes are balanced. - for i < len(token)-3 { - c := token[i] - - //nolint:nestif - if c == '\\' { - // When the last non-whitespace character on a line is an unescaped \, - // it will be trimmed along with all whitespace (including newlines) up - // to the next non-whitespace character or closing delimiter. - - isLastNonWhitespaceOnLine := false - j := 1 - findEOLLoop: - for ; j < len(token)-3-i; j++ { - switch token[i+j] { - case ' ', '\t': - continue - case '\r': - if token[i+j+1] == '\n' { - continue - } - case '\n': - isLastNonWhitespaceOnLine = true - } - break findEOLLoop - } - if isLastNonWhitespaceOnLine { - i += j - for ; i < len(token)-3; i++ { - c := token[i] - if c != '\n' && c != '\r' && c != ' ' && c != '\t' { - i-- - break - } - } - i++ - continue - } - - // handle escaping - i++ - c = token[i] - - switch c { - case '"', '\\': - builder.WriteByte(c) - case 'b': - builder.WriteByte('\b') - case 'f': - builder.WriteByte('\f') - case 'n': - builder.WriteByte('\n') - case 'r': - builder.WriteByte('\r') - case 't': - builder.WriteByte('\t') - case 'e': - builder.WriteByte(0x1B) - case 'u': - x, err := hexToRune(atmost(token[i+1:], 4), 4) - if err != nil { - return nil, nil, nil, err - } - builder.WriteRune(x) - i += 4 - case 'U': - x, err := hexToRune(atmost(token[i+1:], 8), 8) - if err != nil { - return nil, nil, nil, err - } - - builder.WriteRune(x) - i += 8 - default: - return nil, nil, nil, NewParserError(token[i:i+1], "invalid escaped character %#U", c) - } - i++ - } else { - size := characters.Utf8ValidNext(token[i:]) - if size == 0 { - return nil, nil, nil, NewParserError(token[i:i+1], "invalid character %#U", c) - } - builder.Write(token[i : i+size]) - i += size - } - } - - return token, builder.Bytes(), rest, nil -} - -func (p *Parser) parseKey(b []byte) (reference, []byte, error) { - // key = simple-key / dotted-key - // simple-key = quoted-key / unquoted-key - // - // unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _ - // quoted-key = basic-string / literal-string - // dotted-key = simple-key 1*( dot-sep simple-key ) - // - // dot-sep = ws %x2E ws ; . Period - raw, key, b, err := p.parseSimpleKey(b) - if err != nil { - return invalidReference, nil, err - } - - ref := p.builder.Push(Node{ - Kind: Key, - Raw: p.rangeOfToken(raw, b), - Data: key, - }) + p.nodes = p.nodes[:0] for { - b = p.parseWhitespace(b) - if len(b) > 0 && b[0] == '.' { - b = p.parseWhitespace(b[1:]) + b := skipWhitespace(p.left) + if len(b) == 0 { + p.left = b + return false + } - raw, key, b, err = p.parseSimpleKey(b) - if err != nil { - return ref, nil, err + var err error + switch b[0] { + case '\n': + p.left = b[1:] + continue + case '\r': + if len(b) > 1 && b[1] == '\n' { + p.left = b[2:] + continue } - - p.builder.PushAndChain(Node{ - Kind: Key, - Raw: p.rangeOfToken(raw, b), - Data: key, - }) - } else { - break - } - } - - return ref, b, nil -} - -func (p *Parser) parseSimpleKey(b []byte) (raw, key, rest []byte, err error) { - if len(b) == 0 { - return nil, nil, nil, NewParserError(b, "expected key but found none") - } - - // simple-key = quoted-key / unquoted-key - // unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _ - // quoted-key = basic-string / literal-string - switch { - case b[0] == '\'': - return p.parseLiteralString(b) - case b[0] == '"': - return p.parseBasicString(b) - case isUnquotedKeyChar(b[0]): - key, rest = scanUnquotedKey(b) - return key, key, rest, nil - default: - return nil, nil, nil, NewParserError(b[0:1], "invalid character at start of key: %c", b[0]) - } -} - -//nolint:funlen,cyclop -func (p *Parser) parseBasicString(b []byte) ([]byte, []byte, []byte, error) { - // basic-string = quotation-mark *basic-char quotation-mark - // quotation-mark = %x22 ; " - // basic-char = basic-unescaped / escaped - // basic-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii - // escaped = escape escape-seq-char - // escape-seq-char = %x22 ; " quotation mark U+0022 - // escape-seq-char =/ %x5C ; \ reverse solidus U+005C - // escape-seq-char =/ %x62 ; b backspace U+0008 - // escape-seq-char =/ %x66 ; f form feed U+000C - // escape-seq-char =/ %x6E ; n line feed U+000A - // escape-seq-char =/ %x72 ; r carriage return U+000D - // escape-seq-char =/ %x74 ; t tab U+0009 - // escape-seq-char =/ %x75 4HEXDIG ; uXXXX U+XXXX - // escape-seq-char =/ %x55 8HEXDIG ; UXXXXXXXX U+XXXXXXXX - token, escaped, rest, err := scanBasicString(b) - if err != nil { - return nil, nil, nil, err - } - - startIdx := len(`"`) - endIdx := len(token) - len(`"`) - - // Fast path. If there is no escape sequence, the string should just be - // an UTF-8 encoded string, which is the same as Go. In that case, - // validate the string and return a direct reference to the buffer. - if !escaped { - str := token[startIdx:endIdx] - highlight := characters.Utf8TomlValidAlreadyEscaped(str) - if len(highlight) == 0 { - return token, str, rest, nil - } - return nil, nil, nil, NewParserError(highlight, "invalid UTF-8") - } - - i := startIdx - - var builder bytes.Buffer - - // The scanner ensures that the token starts and ends with quotes and that - // escapes are balanced. - for i < len(token)-1 { - c := token[i] - if c == '\\' { - i++ - c = token[i] - - switch c { - case '"', '\\': - builder.WriteByte(c) - case 'b': - builder.WriteByte('\b') - case 'f': - builder.WriteByte('\f') - case 'n': - builder.WriteByte('\n') - case 'r': - builder.WriteByte('\r') - case 't': - builder.WriteByte('\t') - case 'e': - builder.WriteByte(0x1B) - case 'u': - x, err := hexToRune(token[i+1:len(token)-1], 4) - if err != nil { - return nil, nil, nil, err + err = NewParserError(b[:1], "expected newline but got %#U", b[0]) + case '#': + var comment, rest []byte + comment, rest, err = scanComment(b) + if err == nil { + rest, err = consumeEOL(rest) + } + if err == nil { + if p.KeepComments { + p.push(Node{ + Kind: Comment, + Raw: p.Range(comment), + Data: comment, + }) + p.left = rest + return true } - - builder.WriteRune(x) - i += 4 - case 'U': - x, err := hexToRune(token[i+1:len(token)-1], 8) - if err != nil { - return nil, nil, nil, err - } - - builder.WriteRune(x) - i += 8 - default: - return nil, nil, nil, NewParserError(token[i:i+1], "invalid escaped character %#U", c) + p.left = rest + continue } - i++ - } else { - size := characters.Utf8ValidNext(token[i:]) - if size == 0 { - return nil, nil, nil, NewParserError(token[i:i+1], "invalid character %#U", c) + case '[': + var rest []byte + rest, err = p.parseExprTable(b) + if err == nil { + p.left = rest + return true } - builder.Write(token[i : i+size]) - i += size - } - } - - return token, builder.Bytes(), rest, nil -} - -func hexToRune(b []byte, length int) (rune, error) { - if len(b) < length { - return -1, NewParserError(b, "unicode point needs %d character, not %d", length, len(b)) - } - b = b[:length] - - var r uint32 - for i, c := range b { - var d uint32 - switch { - case '0' <= c && c <= '9': - d = uint32(c - '0') - case 'a' <= c && c <= 'f': - d = uint32(c - 'a' + 10) - case 'A' <= c && c <= 'F': - d = uint32(c - 'A' + 10) default: - return -1, NewParserError(b[i:i+1], "non-hex character") + var rest []byte + rest, err = p.parseExprKeyval(b) + if err == nil { + p.left = rest + return true + } } - r = r*16 + d - } - if r > unicode.MaxRune || 0xD800 <= r && r < 0xE000 { - return -1, NewParserError(b, "escape sequence is invalid Unicode code point") - } + // Errors at the end of the input have an empty highlight. Extend + // them to the last byte of the input so that they carry a usable + // position. + var perr *ParserError + if errors.As(err, &perr) && len(perr.Highlight) == 0 { + if offset := p.offsetOf(perr.Highlight); offset > 0 && offset == len(p.data) { + perr.Highlight = p.data[offset-1 : offset] + } + } - return rune(r), nil + p.err = err + return false + } } -func (p *Parser) parseWhitespace(b []byte) []byte { - // ws = *wschar - // wschar = %x20 ; Space - // wschar =/ %x09 ; Horizontal tab - _, rest := scanWhitespace(b) - - return rest -} - -//nolint:cyclop -func (p *Parser) parseIntOrFloatOrDateTime(b []byte) (reference, []byte, error) { +// consumeEOL consumes a newline (LF or CRLF) or end of input. +func consumeEOL(b []byte) ([]byte, error) { + if len(b) == 0 { + return b, nil + } switch b[0] { - case 'i': - if !scanFollowsInf(b) { - return invalidReference, nil, NewParserError(atmost(b, 3), "expected 'inf'") + case '\n': + return b[1:], nil + case '\r': + if len(b) > 1 && b[1] == '\n' { + return b[2:], nil } + } + return nil, NewParserError(b[:1], "expected newline but got %#U", b[0]) +} - return p.builder.Push(Node{ - Kind: Float, - Data: b[:3], - Raw: p.rangeOfToken(b[:3], b[3:]), - }), b[3:], nil - case 'n': - if !scanFollowsNan(b) { - return invalidReference, nil, NewParserError(atmost(b, 3), "expected 'nan'") +// finishLine handles `ws [comment] (newline|eof)` after a top-level +// expression. If a comment is present and KeepComments is set, it is attached +// as the next sibling of the expression's root node. +func (p *Parser) finishLine(root int32, b []byte) ([]byte, error) { + b = skipWhitespace(b) + if len(b) > 0 && b[0] == '#' { + comment, rest, err := scanComment(b) + if err != nil { + return nil, err } + if p.KeepComments { + h := p.push(Node{ + Kind: Comment, + Raw: p.Range(comment), + Data: comment, + }) + p.at(root).next = h + } + b = rest + } + return consumeEOL(b) +} - return p.builder.Push(Node{ - Kind: Float, - Data: b[:3], - Raw: p.rangeOfToken(b[:3], b[3:]), - }), b[3:], nil - case '+', '-': - return p.scanIntOrFloat(b) +// parseExprKeyval parses a top-level `key = value` expression, including its +// line termination. +func (p *Parser) parseExprKeyval(b []byte) ([]byte, error) { + root, rest, err := p.parseKeyval(b) + if err != nil { + return nil, err + } + return p.finishLine(root, rest) +} + +// parseExprTable parses a `[table]` or `[[array table]]` expression, +// including its line termination. b starts at '['. +func (p *Parser) parseExprTable(b []byte) ([]byte, error) { + var root int32 + var err error + var rest []byte + if len(b) > 1 && b[1] == '[' { + root, rest, err = p.parseArrayTableHeader(b) + } else { + root, rest, err = p.parseTableHeader(b) + } + if err != nil { + return nil, err + } + return p.finishLine(root, rest) +} + +// parseTableHeader parses `[ ws key ws ]`. b starts at '['. +func (p *Parser) parseTableHeader(b []byte) (int32, []byte, error) { + root := p.push(Node{Kind: Table}) + + first, b, err := p.parseKey(skipWhitespace(b[1:])) + if err != nil { + return 0, nil, err + } + p.at(root).child = first + + if len(b) == 0 || b[0] != ']' { + return 0, nil, NewParserError(highlight1(b), "expected ']' to close table name") + } + return root, b[1:], nil +} + +// parseArrayTableHeader parses `[[ ws key ws ]]`. b starts at '[['. +func (p *Parser) parseArrayTableHeader(b []byte) (int32, []byte, error) { + root := p.push(Node{Kind: ArrayTable}) + + first, b, err := p.parseKey(skipWhitespace(b[2:])) + if err != nil { + return 0, nil, err + } + p.at(root).child = first + + if len(b) < 2 || b[0] != ']' || b[1] != ']' { + return 0, nil, NewParserError(highlight1(b), "expected ']]' to close array table name") + } + return root, b[2:], nil +} + +// parseKeyval parses `key keyval-sep val`. Returns the handle to the KeyValue +// node. +func (p *Parser) parseKeyval(b []byte) (int32, []byte, error) { + root := p.push(Node{Kind: KeyValue}) + start := b + + firstKey, b, err := p.parseKey(b) + if err != nil { + return 0, nil, err } - if len(b) < 3 { - return p.scanIntOrFloat(b) + if len(b) == 0 || b[0] != '=' { + return 0, nil, NewParserError(highlight1(b), "expected '=' after key") + } + b = skipWhitespace(b[1:]) + + value, b, err := p.parseVal(b) + if err != nil { + return 0, nil, err } - s := 5 - if len(b) < s { - s = len(b) - } + p.at(root).child = value + p.at(value).next = firstKey + p.at(root).Raw = p.rangeFrom(start, b) + return root, b, nil +} - for idx, c := range b[:s] { - if isDigit(c) { +// parseKey parses a potentially dotted key. It consumes the whitespace +// following the key, so that the caller can directly check for the next +// expected character ('=', ']', ...). Returns the handle of the first Key +// node; subsequent parts are chained via next. +func (p *Parser) parseKey(b []byte) (int32, []byte, error) { + var first, last int32 + for { + h, rest, err := p.parseSimpleKey(b) + if err != nil { + return 0, nil, err + } + if first == 0 { + first = h + } else { + p.at(last).next = h + } + last = h + + b = skipWhitespace(rest) + if len(b) > 0 && b[0] == '.' { + b = skipWhitespace(b[1:]) continue } - - if idx == 2 && c == ':' || (idx == 4 && c == '-') { - return p.scanDateTime(b) - } - - break + return first, b, nil } - - return p.scanIntOrFloat(b) } -func (p *Parser) scanDateTime(b []byte) (reference, []byte, error) { - // scans for contiguous characters in [0-9T:Z.+-], and up to one space if - // followed by a digit. - hasDate := false - hasTime := false - hasTz := false - seenSpace := false +func isUnquotedKeyChar(c byte) bool { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' +} - i := 0 -byteLoop: - for ; i < len(b); i++ { - c := b[i] +// parseSimpleKey parses one key part: either a bare key or a quoted key. +func (p *Parser) parseSimpleKey(b []byte) (int32, []byte, error) { + raw, value, rest, err := p.scanSimpleKey(b) + if err != nil { + return 0, nil, err + } + h := p.push(Node{Kind: Key, Raw: p.Range(raw), Data: value}) + return h, rest, nil +} - switch { - case isDigit(c): - case c == '-': - hasDate = true - const minOffsetOfTz = 8 - if i >= minOffsetOfTz { - hasTz = true +// scanSimpleKey scans one key part (bare or quoted) without building an AST +// node. It returns the raw bytes, the decoded key value, and the rest of the +// input. +func (p *Parser) scanSimpleKey(b []byte) (raw, value, rest []byte, err error) { + if len(b) == 0 { + return nil, nil, nil, NewParserError(b, "expected key but reached end of input") + } + + switch b[0] { + case '\'': + return p.parseLiteralString(b) + case '"': + return p.parseBasicString(b) + default: + i := 0 + for i < len(b) && isUnquotedKeyChar(b[i]) { + i++ + } + if i == 0 { + return nil, nil, nil, NewParserError(b[:1], "invalid character at start of key: %#U", b[0]) + } + return b[:i], b[:i], b[i:], nil + } +} + +// parseVal parses a TOML value and returns the handle to its node. +func (p *Parser) parseVal(b []byte) (int32, []byte, error) { + if len(b) == 0 { + return 0, nil, NewParserError(b, "expected value, not end of input") + } + + c := b[0] + switch { + case c == '"': + var raw, value, rest []byte + var err error + if len(b) > 2 && b[1] == '"' && b[2] == '"' { + raw, value, rest, err = p.parseMultilineBasicString(b) + } else { + raw, value, rest, err = p.parseBasicString(b) + } + if err != nil { + return 0, nil, err + } + h := p.push(Node{Kind: String, Raw: p.Range(raw), Data: value}) + return h, rest, nil + case c == '\'': + var raw, value, rest []byte + var err error + if len(b) > 2 && b[1] == '\'' && b[2] == '\'' { + raw, value, rest, err = p.parseMultilineLiteralString(b) + } else { + raw, value, rest, err = p.parseLiteralString(b) + } + if err != nil { + return 0, nil, err + } + h := p.push(Node{Kind: String, Raw: p.Range(raw), Data: value}) + return h, rest, nil + case c == 't': + return p.parseKeyword(b, "true", Bool) + case c == 'f': + return p.parseKeyword(b, "false", Bool) + case c == 'i': + return p.parseKeyword(b, "inf", Float) + case c == 'n': + return p.parseKeyword(b, "nan", Float) + case c == '[' || c == '{': + // Arrays and inline tables recurse back into parseVal for each of + // their elements. Bound that recursion so a document with millions of + // nested brackets or braces cannot overflow the goroutine stack. + if p.nesting >= maxValueNesting { + return 0, nil, NewParserError(b[:1], "arrays and inline tables are nested more than the maximum of %d levels deep", maxValueNesting) + } + p.nesting++ + var h int32 + var rest []byte + var err error + if c == '[' { + h, rest, err = p.parseValArray(b) + } else { + h, rest, err = p.parseInlineTable(b) + } + p.nesting-- + return h, rest, err + case c == '+' || c == '-': + return p.parseIntOrFloat(b) + case c >= '0' && c <= '9': + if isDateTimeStart(b) { + return p.parseDateTime(b) + } + return p.parseIntOrFloat(b) + default: + return 0, nil, NewParserError(b[:1], "unexpected character %#U at start of value", c) + } +} + +// scanScalar scans a single scalar TOML value (string, integer, float, +// boolean, or date/time) without building any AST node. It returns the kind of +// the value, its raw bytes, its decoded value bytes (for strings: quotes +// removed and escapes resolved; identical to raw for the other kinds), and the +// rest of the input. Arrays and inline tables are not scalars and produce an +// error: use parseValue for those. +// +// It is exposed to the root toml package through internal/parserbridge for the +// fused generic-decode path; it is not part of the public API. +func (p *Parser) scanScalar(b []byte) (kind Kind, raw, value, rest []byte, err error) { + if len(b) == 0 { + return Invalid, nil, nil, nil, NewParserError(b, "expected value, not end of input") + } + + c := b[0] + switch { + case c == '"': + if len(b) > 2 && b[1] == '"' && b[2] == '"' { + raw, value, rest, err = p.parseMultilineBasicString(b) + } else { + raw, value, rest, err = p.parseBasicString(b) + } + return String, raw, value, rest, err + case c == '\'': + if len(b) > 2 && b[1] == '\'' && b[2] == '\'' { + raw, value, rest, err = p.parseMultilineLiteralString(b) + } else { + raw, value, rest, err = p.parseLiteralString(b) + } + return String, raw, value, rest, err + case c == 't': + return scanKeyword(b, "true", Bool) + case c == 'f': + return scanKeyword(b, "false", Bool) + case c == 'i': + return scanKeyword(b, "inf", Float) + case c == 'n': + return scanKeyword(b, "nan", Float) + case c == '+' || c == '-': + return scanIntOrFloat(b) + case c >= '0' && c <= '9': + if isDateTimeStart(b) { + return scanDateTime(b) + } + return scanIntOrFloat(b) + default: + return Invalid, nil, nil, nil, NewParserError(b[:1], "unexpected character %#U at start of value", c) + } +} + +// scanKey scans a potentially dotted key without building AST nodes, +// appending the decoded value of each part to dst (pass dst[:0] to reuse a +// buffer). It consumes the whitespace following the key, so the caller can +// directly check for the next expected character ('=', ']', ...). It returns +// the parts, the raw bytes spanning the whole key (from the first part to the +// end of the last one, excluding trailing whitespace, usable as an error +// highlight), the rest of the input, and any error. +// +// It is exposed to the root toml package through internal/parserbridge for the +// fused generic-decode path; it is not part of the public API. +func (p *Parser) scanKey(b []byte, dst [][]byte) (parts [][]byte, raw, rest []byte, err error) { + parts = dst + start := b + for { + _, value, r, err := p.scanSimpleKey(b) + if err != nil { + return nil, nil, nil, err + } + parts = append(parts, value) + + // r points just past the current part: the key spans from start to + // here, ignoring any whitespace that follows. + raw = start[:len(start)-len(r)] + + b = skipWhitespace(r) + if len(b) > 0 && b[0] == '.' { + b = skipWhitespace(b[1:]) + continue + } + return parts, raw, b, nil + } +} + +// parseValue parses a single TOML value, which may be an array or inline table, +// into the parser's arena. It returns the root node of the value and the rest +// of the input. It resets the arena, so any node returned by a previous call to +// parseValue, Expression, or NextExpression is invalidated. +// +// It is exposed to the root toml package through internal/parserbridge for the +// fused generic-decode path; it is not part of the public API. +func (p *Parser) parseValue(b []byte) (*Node, []byte, error) { + p.nodes = p.nodes[:0] + h, rest, err := p.parseVal(b) + if err != nil { + return nil, nil, err + } + return &p.nodes[h-1], rest, nil +} + +func (p *Parser) parseKeyword(b []byte, kw string, kind Kind) (int32, []byte, error) { + k, raw, _, rest, err := scanKeyword(b, kw, kind) + if err != nil { + return 0, nil, err + } + h := p.push(Node{Kind: k, Raw: p.Range(raw), Data: raw}) + return h, rest, nil +} + +// scanKeyword scans a keyword value (true, false, inf, nan) without building +// an AST node. raw and value are identical (the keyword bytes). +func scanKeyword(b []byte, kw string, kind Kind) (Kind, []byte, []byte, []byte, error) { + if len(b) < len(kw) || string(b[:len(kw)]) != kw { + n := len(kw) + if len(b) < n { + n = len(b) + } + return Invalid, nil, nil, nil, NewParserError(b[:n], "expected keyword %q", kw) + } + return kind, b[:len(kw)], b[:len(kw)], b[len(kw):], nil +} + +// parseValArray parses an array value. b starts at '['. +func (p *Parser) parseValArray(b []byte) (int32, []byte, error) { + arr := p.push(Node{Kind: Array}) + b = b[1:] + + var lastChild int32 + appendChild := func(h int32) { + if lastChild == 0 { + p.at(arr).child = h + } else { + p.at(lastChild).next = h + } + lastChild = h + } + + // Comments inside the array are attached as follows: the first comment + // of a "run" (consecutive comments with no value in between) becomes a + // child of the array, interleaved with values; subsequent comments of the + // run are attached as children of the first one. + var runFirst, runLast int32 + + // afterValue is true when a value has been parsed and a comma (or the + // closing bracket) is expected before the next one. + afterValue := false + for { + b = skipWhitespace(b) + if len(b) == 0 { + return 0, nil, NewParserError(b, "array is incomplete") + } + + switch b[0] { + case ']': + return arr, b[1:], nil + case '\n': + b = b[1:] + continue + case '\r': + if len(b) > 1 && b[1] == '\n' { + b = b[2:] + continue } - case c == 'T' || c == 't' || c == ':' || c == '.': - hasTime = true - case c == '+' || c == 'Z' || c == 'z': - hasTz = true - case c == ' ': - if !seenSpace && i+1 < len(b) && isDigit(b[i+1]) { - i += 2 - // Avoid reaching past the end of the document in case the time - // is malformed. See TestIssue585. - if i >= len(b) { - i-- + return 0, nil, NewParserError(b[:1], "expected newline but got %#U", b[0]) + case '#': + comment, rest, err := scanComment(b) + if err != nil { + return 0, nil, err + } + if p.KeepComments { + h := p.push(Node{Kind: Comment, Raw: p.Range(comment), Data: comment}) + switch { + case runFirst == 0: + appendChild(h) + runFirst = h + case runLast == runFirst: + p.at(runFirst).child = h + default: + p.at(runLast).next = h } - seenSpace = true - hasTime = true - } else { - break byteLoop + runLast = h } + b = rest + continue + case ',': + if !afterValue { + return 0, nil, NewParserError(b[:1], "expected value but got %#U", b[0]) + } + afterValue = false + b = b[1:] + continue default: - break byteLoop + if afterValue { + return 0, nil, NewParserError(b[:1], "expected ',' or ']' after array value") + } + h, rest, err := p.parseVal(b) + if err != nil { + return 0, nil, err + } + appendChild(h) + afterValue = true + runFirst, runLast = 0, 0 + b = rest + continue } } +} + +// parseInlineTable parses an inline table value. b starts at '{'. +// +// Per TOML v1.1.0, inline tables may span multiple lines (whitespace, +// comments and newlines are allowed between elements) and may contain a +// trailing comma. +func (p *Parser) parseInlineTable(b []byte) (int32, []byte, error) { + tbl := p.push(Node{Kind: InlineTable, Raw: p.Range(b[:1])}) + b = b[1:] + + var lastChild int32 + appendChild := func(h int32) { + if lastChild == 0 { + p.at(tbl).child = h + } else { + p.at(lastChild).next = h + } + lastChild = h + } + + // Comments are attached as in arrays: the first comment of a "run" + // (consecutive comments with no key-value in between) becomes a child of + // the table, interleaved with key-values; subsequent comments of the run + // hang off the first one. + var runFirst, runLast int32 + + // afterValue is true when a key-value has been parsed and a comma (or the + // closing brace) is expected before the next one. + afterValue := false + for { + b = skipWhitespace(b) + if len(b) == 0 { + return 0, nil, NewParserError(b, "inline table is incomplete") + } + + switch b[0] { + case '}': + return tbl, b[1:], nil + case '\n': + b = b[1:] + continue + case '\r': + if len(b) > 1 && b[1] == '\n' { + b = b[2:] + continue + } + return 0, nil, NewParserError(b[:1], "expected newline but got %#U", b[0]) + case '#': + comment, rest, err := scanComment(b) + if err != nil { + return 0, nil, err + } + if p.KeepComments { + h := p.push(Node{Kind: Comment, Raw: p.Range(comment), Data: comment}) + switch { + case runFirst == 0: + appendChild(h) + runFirst = h + case runLast == runFirst: + p.at(runFirst).child = h + default: + p.at(runLast).next = h + } + runLast = h + } + b = rest + continue + case ',': + if !afterValue { + return 0, nil, NewParserError(b[:1], "unexpected comma in inline table") + } + afterValue = false + b = b[1:] + continue + default: + if afterValue { + return 0, nil, NewParserError(b[:1], "expected ',' or '}' after inline table key-value") + } + h, rest, err := p.parseKeyval(b) + if err != nil { + return 0, nil, err + } + appendChild(h) + afterValue = true + runFirst, runLast = 0, 0 + b = rest + continue + } + } +} + +func isDigit(c byte) bool { + return c >= '0' && c <= '9' +} + +func isHexDigit(c byte) bool { + return isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') +} + +// isDateTimeStart reports whether b looks like the start of a date or time +// value instead of a number. Values starting with two digits followed by a +// colon are times; values starting with four digits followed by a dash are +// dates. +func isDateTimeStart(b []byte) bool { + if len(b) >= 3 && isDigit(b[1]) && b[2] == ':' { + return true + } + if len(b) >= 5 && isDigit(b[1]) && isDigit(b[2]) && isDigit(b[3]) && b[4] == '-' { + return true + } + return false +} + +// expectDigits checks that the n first bytes of b are digits. +// parseDateTime parses date and/or time values. b starts with a digit. +// +// The parser is lenient: it scans the characters that can be part of a date +// and/or time value to delimit and classify the token, but leaves the +// validation of its contents to the document consumer. This keeps the value +// in one piece, so that errors about its content can point at the right +// place. +func (p *Parser) parseDateTime(b []byte) (int32, []byte, error) { + kind, raw, _, rest, err := scanDateTime(b) + if err != nil { + return 0, nil, err + } + h := p.push(Node{Kind: kind, Raw: p.Range(raw), Data: raw}) + return h, rest, nil +} + +// scanDateTime classifies and delimits a date/time value without building an +// AST node. raw and value are identical (the token bytes). +func scanDateTime(b []byte) (Kind, []byte, []byte, []byte, error) { + // Greedily scan the characters that may compose a date/time value. A + // space is part of the value only when it serves as the delimiter + // between the date and the time, which is approximated by requiring a + // digit right after it. + i := 0 + delim := -1 + for i < len(b) { + c := b[i] + if isDigit(c) || c == ':' || c == '-' || c == '+' || c == '.' || c == 'Z' || c == 'z' { + i++ + continue + } + if c == 'T' || c == 't' || (c == ' ' && i+1 < len(b) && isDigit(b[i+1])) { + if delim < 0 { + delim = i + } + i++ + continue + } + break + } + tok := b[:i] var kind Kind - - if hasTime { - if hasDate { - if hasTz { - kind = DateTime - } else { - kind = LocalDateTime - } - } else { - kind = LocalTime - } - } else { + switch { + case tok[2] == ':': + kind = LocalTime + case delim < 0: kind = LocalDate + case bytes.ContainsAny(tok[delim+1:], "Zz+-"): + kind = DateTime + default: + kind = LocalDateTime } - return p.builder.Push(Node{ - Kind: kind, - Data: b[:i], - }), b[i:], nil + return kind, tok, tok, b[i:], nil } -//nolint:funlen,gocognit,cyclop -func (p *Parser) scanIntOrFloat(b []byte) (reference, []byte, error) { - i := 0 - - if len(b) > 2 && b[0] == '0' && b[1] != '.' && b[1] != 'e' && b[1] != 'E' { - var isValidRune validRuneFn - - switch b[1] { - case 'x': - isValidRune = isValidHexRune - case 'o': - isValidRune = isValidOctalRune - case 'b': - isValidRune = isValidBinaryRune - default: - i++ - } - - if isValidRune != nil { - i += 2 - for ; i < len(b); i++ { - if !isValidRune(b[i]) { - break - } - } - } - - return p.builder.Push(Node{ - Kind: Integer, - Data: b[:i], - Raw: p.rangeOfToken(b[:i], b[i:]), - }), b[i:], nil - } - - isFloat := false - - for ; i < len(b); i++ { +// scanDigitsWithUnderscores scans a run of digits potentially separated by +// underscores. b starts right after the first digit of the run. isInRange +// selects the kind of digits. Returns the index after the run. +func scanDigitsWithUnderscores(b []byte, i int, isInRange func(byte) bool) (int, error) { + for i < len(b) { c := b[i] - - if c >= '0' && c <= '9' || c == '+' || c == '-' || c == '_' { + if isInRange(c) { + i++ continue } - - if c == '.' || c == 'e' || c == 'E' { - isFloat = true - + if c == '_' { + if i+1 >= len(b) || !isInRange(b[i+1]) { + end := i + 2 + if end > len(b) { + end = len(b) + } + return 0, NewParserError(b[i:end], "number must have at least one digit between underscores") + } + i += 2 continue } - - if c == 'i' { - if scanFollowsInf(b[i:]) { - return p.builder.Push(Node{ - Kind: Float, - Data: b[:i+3], - Raw: p.rangeOfToken(b[:i+3], b[i+3:]), - }), b[i+3:], nil - } - - return invalidReference, nil, NewParserError(b[i:i+1], "unexpected character 'i' while scanning for a number") - } - - if c == 'n' { - if scanFollowsNan(b[i:]) { - return p.builder.Push(Node{ - Kind: Float, - Data: b[:i+3], - Raw: p.rangeOfToken(b[:i+3], b[i+3:]), - }), b[i+3:], nil - } - - return invalidReference, nil, NewParserError(b[i:i+1], "unexpected character 'n' while scanning for a number") - } - break } + return i, nil +} - if i == 0 { - return invalidReference, b, NewParserError(b, "incomplete number") +// parseIntOrFloat parses integer and float values, including the special +// values inf and nan with an optional sign. +func (p *Parser) parseIntOrFloat(b []byte) (int32, []byte, error) { + kind, raw, _, rest, err := scanIntOrFloat(b) + if err != nil { + return 0, nil, err + } + h := p.push(Node{Kind: kind, Raw: p.Range(raw), Data: raw}) + return h, rest, nil +} + +// scanIntOrFloat delimits and classifies an integer or float value (including +// the special floats inf and nan with an optional sign) without building an +// AST node. raw and value are identical (the token bytes). +func scanIntOrFloat(b []byte) (Kind, []byte, []byte, []byte, error) { + i := 0 + if b[i] == '+' || b[i] == '-' { + i++ + } + if i >= len(b) { + return Invalid, nil, nil, nil, NewParserError(b, "expected number after sign") + } + + // special floats + if b[i] == 'i' || b[i] == 'n' { + kw := "inf" + if b[i] == 'n' { + kw = "nan" + } + if len(b) < i+3 || string(b[i:i+3]) != kw { + return Invalid, nil, nil, nil, NewParserError(b[i:i+1], "expected %q", kw) + } + i += 3 + return Float, b[:i], b[:i], b[i:], nil + } + + if !isDigit(b[i]) { + return Invalid, nil, nil, nil, NewParserError(b[i:i+1], "expected digit but got %#U", b[i]) + } + + // radix prefixes + if b[i] == '0' && i+1 < len(b) && (b[i+1] == 'x' || b[i+1] == 'o' || b[i+1] == 'b') { + if i != 0 { + return Invalid, nil, nil, nil, NewParserError(b[:2], "sign is not allowed on numbers with a radix prefix") + } + var isInRange func(byte) bool + switch b[1] { + case 'x': + isInRange = isHexDigit + case 'o': + isInRange = func(c byte) bool { return c >= '0' && c <= '7' } + case 'b': + isInRange = func(c byte) bool { return c == '0' || c == '1' } + } + i = 2 + if i >= len(b) || !isInRange(b[i]) { + return Invalid, nil, nil, nil, NewParserError(b[:2], "radix prefix must be followed by at least one digit") + } + i++ + var err error + i, err = scanDigitsWithUnderscores(b, i, isInRange) + if err != nil { + return Invalid, nil, nil, nil, err + } + return Integer, b[:i], b[:i], b[i:], nil + } + + // decimal integer part + leadingZero := b[i] == '0' + digitsStart := i + i++ + var err error + i, err = scanDigitsWithUnderscores(b, i, isDigit) + if err != nil { + return Invalid, nil, nil, nil, err + } + if leadingZero && i > digitsStart+1 { + return Invalid, nil, nil, nil, NewParserError(b[digitsStart:digitsStart+2], "integers cannot have leading zeroes") } kind := Integer - if isFloat { + // fractional part + if i < len(b) && b[i] == '.' { + i++ + if i >= len(b) || !isDigit(b[i]) { + return Invalid, nil, nil, nil, NewParserError(highlight1(b[i:]), "decimal point must be followed by a digit") + } + i++ + i, err = scanDigitsWithUnderscores(b, i, isDigit) + if err != nil { + return Invalid, nil, nil, nil, err + } kind = Float } - return p.builder.Push(Node{ - Kind: kind, - Data: b[:i], - Raw: p.rangeOfToken(b[:i], b[i:]), - }), b[i:], nil -} - -func isDigit(r byte) bool { - return r >= '0' && r <= '9' -} - -type validRuneFn func(r byte) bool - -func isValidHexRune(r byte) bool { - return r >= 'a' && r <= 'f' || - r >= 'A' && r <= 'F' || - r >= '0' && r <= '9' || - r == '_' -} - -func isValidOctalRune(r byte) bool { - return r >= '0' && r <= '7' || r == '_' -} - -func isValidBinaryRune(r byte) bool { - return r == '0' || r == '1' || r == '_' -} - -func expect(x byte, b []byte) ([]byte, error) { - if len(b) == 0 { - return nil, NewParserError(b, "expected character %c but the document ended here", x) + // exponent + if i < len(b) && (b[i] == 'e' || b[i] == 'E') { + i++ + if i < len(b) && (b[i] == '+' || b[i] == '-') { + i++ + } + if i >= len(b) || !isDigit(b[i]) { + return Invalid, nil, nil, nil, NewParserError(highlight1(b[i:]), "exponent must contain at least one digit") + } + i++ + i, err = scanDigitsWithUnderscores(b, i, isDigit) + if err != nil { + return Invalid, nil, nil, nil, err + } + kind = Float } - if b[0] != x { - return nil, NewParserError(b[0:1], "expected character %c", x) + // A letter right after the number means it was meant to be a string that + // was left unquoted (e.g. "20s"). Report that instead of the misleading + // "expected newline" raised later (issue #413). + if i < len(b) { + if c := b[i]; (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') { + return Invalid, nil, nil, nil, NewParserError(b[i:i+1], "strings must be quoted") + } } - return b[1:], nil + return kind, b[:i], b[:i], b[i:], nil +} + +// highlight1 returns a 1-byte highlight at the start of b, or b itself if it +// is empty. +func highlight1(b []byte) []byte { + if len(b) > 0 { + return b[:1] + } + return b +} + +func skipWhitespace(b []byte) []byte { + for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') { + b = b[1:] + } + return b +} + +// Word-at-a-time byte scanning helpers. These detect, within an 8-byte word, +// the presence of bytes that need special handling, so that runs of plain +// ASCII characters can be skipped 8 bytes at a time. +const ( + lsb = 0x0101010101010101 + msb = 0x8080808080808080 +) + +// hasByteBelow reports whether any byte of the word x is strictly below n. +// Only meaningful when combined with a check that no byte has its high bit +// set. +func hasByteBelow(x uint64, n uint64) uint64 { + return (x - n*lsb) & ^x & msb +} + +// hasByteEqual reports whether any byte of the word x equals c. Only +// meaningful for bytes without their high bit set. +func hasByteEqual(x uint64, c uint64) uint64 { + y := x ^ (c * lsb) + return (y - lsb) & ^y & msb +} + +// scanComment parses a comment, starting at the '#' character. It returns the +// comment bytes (including '#', excluding the line ending) and the rest of +// the input. +func scanComment(b []byte) ([]byte, []byte, error) { + i := 1 + for i < len(b) { + // Fast path: skip 8 bytes at a time as long as they are all plain + // printable ASCII. + for i+8 <= len(b) { + x := binary.LittleEndian.Uint64(b[i:]) + if (x&msb)|hasByteBelow(x, 0x20)|hasByteEqual(x, 0x7f) != 0 { + break + } + i += 8 + } + if i >= len(b) { + break + } + + c := b[i] + if c >= 0x80 { + var ok bool + i, ok = scanUtf8Run(b, i) + if !ok { + return nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in comment") + } + continue + } + switch { + case c >= 0x20 && c < 0x7f: + i++ + case c == '\n': + return b[:i], b[i:], nil + case c == '\r': + if i+1 < len(b) && b[i+1] == '\n' { + return b[:i], b[i:], nil + } + return nil, nil, NewParserError(b[i:i+1], "carriage returns are not allowed in comments") + case c == '\t': + i++ + default: + return nil, nil, NewParserError(b[i:i+1], "control characters are not allowed in comments") + } + } + return b[:i], b[i:], nil +} + +// parseLiteralString parses a single-line literal string, starting at the +// opening quote. Returns the raw bytes (with quotes), the string value +// (without quotes) and the rest of the input. +func (p *Parser) parseLiteralString(b []byte) ([]byte, []byte, []byte, error) { + i := 1 + for { + // Fast path over plain ASCII. + for i+8 <= len(b) { + x := binary.LittleEndian.Uint64(b[i:]) + if (x&msb)|hasByteBelow(x, 0x20)|hasByteEqual(x, '\'')|hasByteEqual(x, 0x7f) != 0 { + break + } + i += 8 + } + if i >= len(b) { + return nil, nil, nil, NewParserError(b[len(b):], "unterminated literal string") + } + + c := b[i] + switch { + case c == '\'': + return b[:i+1], b[1:i], b[i+1:], nil + case c >= 0x20 && c < 0x7f: + i++ + case c == '\t': + i++ + case c == '\n' || c == '\r': + return nil, nil, nil, NewParserError(b[i:i+1], "literal strings cannot have new lines") + case c < 0x80: + return nil, nil, nil, NewParserError(b[i:i+1], "literal strings cannot have control characters") + default: + var ok bool + i, ok = scanUtf8Run(b, i) + if !ok { + return nil, nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in literal string") + } + } + } +} + +// parseMultilineLiteralString parses a multi-line literal string, starting at +// the opening triple quote. +func (p *Parser) parseMultilineLiteralString(b []byte) ([]byte, []byte, []byte, error) { + i := 3 + // trim the newline right after the opening delimiter + if i < len(b) && b[i] == '\n' { + i++ + } else if i+1 < len(b) && b[i] == '\r' && b[i+1] == '\n' { + i += 2 + } + contentStart := i + + for i < len(b) { + c := b[i] + switch { + case c == '\'': + // count consecutive quotes + j := i + for j < len(b) && b[j] == '\'' { + j++ + } + n := j - i + if n >= 3 { + if n > 5 { + return nil, nil, nil, NewParserError(b[i:j], "too many quotes at the end of a multiline literal string") + } + // n-3 quotes belong to the content; the last 3 close the + // string. + contentEnd := i + n - 3 + return b[:j], b[contentStart:contentEnd], b[j:], nil + } + i = j + case c >= 0x20 && c < 0x7f: + i++ + case c == '\t' || c == '\n': + i++ + case c == '\r': + if i+1 < len(b) && b[i+1] == '\n' { + i += 2 + continue + } + return nil, nil, nil, NewParserError(b[i:i+1], "carriage returns must be followed by a newline character") + case c < 0x80: + return nil, nil, nil, NewParserError(b[i:i+1], "multiline literal strings cannot have control characters") + default: + var ok bool + i, ok = scanUtf8Run(b, i) + if !ok { + return nil, nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in multiline literal string") + } + } + } + return nil, nil, nil, NewParserError(b[len(b):], "multiline literal string not terminated by '''") +} + +// parseBasicString parses a single-line basic string, starting at the opening +// quote. The value is a subslice of the input if the string contains no +// escape sequence, or a new allocation otherwise. +func (p *Parser) parseBasicString(b []byte) ([]byte, []byte, []byte, error) { + i := 1 + // First pass: handle strings without escape sequences without allocating. + for { + for i+8 <= len(b) { + x := binary.LittleEndian.Uint64(b[i:]) + if (x&msb)|hasByteBelow(x, 0x20)|hasByteEqual(x, '"')|hasByteEqual(x, '\\')|hasByteEqual(x, 0x7f) != 0 { + break + } + i += 8 + } + if i >= len(b) { + return nil, nil, nil, NewParserError(b[len(b):], "unterminated basic string") + } + + c := b[i] + switch { + case c == '"': + return b[:i+1], b[1:i], b[i+1:], nil + case c == '\\': + // switch to the escape-aware parser, copying what has been + // scanned so far + return p.parseBasicStringEscaped(b, i) + case c >= 0x20 && c < 0x7f: + i++ + case c == '\t': + i++ + case c == '\n' || c == '\r': + return nil, nil, nil, NewParserError(b[i:i+1], "basic strings cannot have new lines") + case c < 0x80: + return nil, nil, nil, NewParserError(b[i:i+1], "basic strings cannot have control characters") + default: + var ok bool + i, ok = scanUtf8Run(b, i) + if !ok { + return nil, nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in basic string") + } + } + } +} + +// findBasicStringEnd returns the index of the quote closing a basic string, +// or -1 if the string is not terminated. i is the index of the first +// character after the opening quote. It does not validate the content: it +// only skips over escape sequences so that escaped quotes do not terminate +// the string. +func findBasicStringEnd(b []byte, i int) int { + for i < len(b) { + switch b[i] { + case '"': + return i + case '\\': + i += 2 + default: + i++ + } + } + return -1 +} + +// parseBasicStringEscaped continues parsing a basic string that contains +// escape sequences. i is the index of the first backslash. +func (p *Parser) parseBasicStringEscaped(b []byte, i int) ([]byte, []byte, []byte, error) { + // Escape sequences only ever shrink, so the content length before + // unescaping is enough to never reallocate. + bufCap := len(b) - 1 + if end := findBasicStringEnd(b, i); end >= 0 { + bufCap = end - 1 + } + buf := make([]byte, i-1, bufCap) + copy(buf, b[1:i]) + + for i < len(b) { + c := b[i] + switch { + case c == '"': + return b[:i+1], buf, b[i+1:], nil + case c == '\\': + i++ + if i >= len(b) { + return nil, nil, nil, NewParserError(b[i-1:], `need a character after \`) + } + var err error + buf, i, err = unescape(buf, b, i) + if err != nil { + return nil, nil, nil, err + } + case c >= 0x20 && c < 0x7f: + buf = append(buf, c) + i++ + case c == '\t': + buf = append(buf, c) + i++ + case c == '\n' || c == '\r': + return nil, nil, nil, NewParserError(b[i:i+1], "basic strings cannot have new lines") + case c < 0x80: + return nil, nil, nil, NewParserError(b[i:i+1], "basic strings cannot have control characters") + default: + j, ok := scanUtf8Run(b, i) + if !ok { + return nil, nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in basic string") + } + buf = append(buf, b[i:j]...) + i = j + } + } + return nil, nil, nil, NewParserError(b[len(b):], "unterminated basic string") +} + +// unescape processes one escape sequence. i is the index of the character +// right after the backslash. It returns the updated buffer and index. +func unescape(buf []byte, b []byte, i int) ([]byte, int, error) { + c := b[i] + switch c { + case '"': + return append(buf, '"'), i + 1, nil + case '\\': + return append(buf, '\\'), i + 1, nil + case 'b': + return append(buf, '\b'), i + 1, nil + case 'f': + return append(buf, '\f'), i + 1, nil + case 'n': + return append(buf, '\n'), i + 1, nil + case 'r': + return append(buf, '\r'), i + 1, nil + case 't': + return append(buf, '\t'), i + 1, nil + case 'e': + // TOML v1.1.0: \e is the escape character (U+001B). + return append(buf, 0x1B), i + 1, nil + case 'x': + // TOML v1.1.0: \xHH is a two-digit hexadecimal code point. + return unescapeUnicode(buf, b, i+1, 2) + case 'u': + return unescapeUnicode(buf, b, i+1, 4) + case 'U': + return unescapeUnicode(buf, b, i+1, 8) + default: + return nil, 0, NewParserError(b[i-1:i+1], "invalid escape character %#U", c) + } +} + +// unescapeUnicode handles \uXXXX and \UXXXXXXXX escape sequences. i is the +// index of the first hex digit. +func unescapeUnicode(buf []byte, b []byte, i int, n int) ([]byte, int, error) { + if i+n > len(b) { + return nil, 0, NewParserError(b[i-2:], "unicode escape sequence is too short") + } + var r uint32 + for k := 0; k < n; k++ { + c := b[i+k] + var d uint32 + switch { + case c >= '0' && c <= '9': + d = uint32(c - '0') + case c >= 'a' && c <= 'f': + d = uint32(c-'a') + 10 + case c >= 'A' && c <= 'F': + d = uint32(c-'A') + 10 + default: + return nil, 0, NewParserError(b[i+k:i+k+1], "invalid hexadecimal digit in unicode escape sequence") + } + r = r<<4 | d + } + if r > utf8.MaxRune || (r >= 0xD800 && r <= 0xDFFF) { + return nil, 0, NewParserError(b[i-2:i+n], "escape sequence is not a valid unicode code point") + } + return utf8.AppendRune(buf, rune(r)), i + n, nil +} + +// parseMultilineBasicString parses a multi-line basic string, starting at the +// opening triple quote. +func (p *Parser) parseMultilineBasicString(b []byte) ([]byte, []byte, []byte, error) { + i := 3 + // trim the newline right after the opening delimiter + if i < len(b) && b[i] == '\n' { + i++ + } else if i+1 < len(b) && b[i] == '\r' && b[i+1] == '\n' { + i += 2 + } + contentStart := i + + // First pass without allocating, until an escape sequence is found. + for i < len(b) { + c := b[i] + switch { + case c == '"': + j := i + for j < len(b) && b[j] == '"' { + j++ + } + n := j - i + if n >= 3 { + if n > 5 { + return nil, nil, nil, NewParserError(b[i:j], "too many quotes at the end of a multiline basic string") + } + contentEnd := i + n - 3 + return b[:j], b[contentStart:contentEnd], b[j:], nil + } + i = j + case c == '\\': + return p.parseMultilineBasicStringEscaped(b, contentStart, i) + case c >= 0x20 && c < 0x7f: + i++ + case c == '\t' || c == '\n': + i++ + case c == '\r': + if i+1 < len(b) && b[i+1] == '\n' { + i += 2 + continue + } + return nil, nil, nil, NewParserError(b[i:i+1], "carriage returns must be followed by a newline character") + case c < 0x80: + return nil, nil, nil, NewParserError(b[i:i+1], "multiline basic strings cannot have control characters") + default: + var ok bool + i, ok = scanUtf8Run(b, i) + if !ok { + return nil, nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in multiline basic string") + } + } + } + return nil, nil, nil, NewParserError(b[len(b):], `multiline basic string not terminated by """`) +} + +// findMultilineBasicStringEnd returns the index of the first quote of the +// run of quotes closing a multi-line basic string, or -1 if the string is +// not terminated. It does not validate the content: it only skips over +// escape sequences so that escaped quotes do not terminate the string. +func findMultilineBasicStringEnd(b []byte, i int) int { + for { + j := bytes.IndexAny(b[i:], "\"\\") + if j < 0 { + return -1 + } + i += j + if b[i] == '\\' { + i += 2 + if i > len(b) { + return -1 + } + continue + } + j = i + for j < len(b) && b[j] == '"' { + j++ + } + if j-i >= 3 { + return i + } + i = j + } +} + +// parseMultilineBasicStringEscaped continues parsing a multi-line basic +// string that contains escape sequences. i is the index of the first +// backslash; content starts at contentStart. +func (p *Parser) parseMultilineBasicStringEscaped(b []byte, contentStart, i int) ([]byte, []byte, []byte, error) { + // Escape sequences only ever shrink, so the content length before + // unescaping is enough to never reallocate. The closing run of quotes + // can lend up to two quotes to the content. + bufCap := len(b) - contentStart + if end := findMultilineBasicStringEnd(b, i); end >= 0 { + bufCap = end + 2 - contentStart + } + buf := make([]byte, i-contentStart, bufCap) + copy(buf, b[contentStart:i]) + + for i < len(b) { + c := b[i] + switch { + case c == '"': + j := i + for j < len(b) && b[j] == '"' { + j++ + } + n := j - i + if n >= 3 { + if n > 5 { + return nil, nil, nil, NewParserError(b[i:j], "too many quotes at the end of a multiline basic string") + } + buf = append(buf, b[i:i+n-3]...) + return b[:j], buf, b[j:], nil + } + buf = append(buf, b[i:j]...) + i = j + case c == '\\': + i++ + if i >= len(b) { + return nil, nil, nil, NewParserError(b[i-1:], `need a character after \`) + } + // Escaped newline: backslash, optional whitespace, newline, + // then all following whitespace and newlines are trimmed. + if b[i] == ' ' || b[i] == '\t' || b[i] == '\n' || b[i] == '\r' { + j := i + for j < len(b) && (b[j] == ' ' || b[j] == '\t') { + j++ + } + if j < len(b) && b[j] == '\r' { + j++ + } + if j >= len(b) || b[j] != '\n' { + return nil, nil, nil, NewParserError(b[i-1:i+1], "invalid escape character %#U", b[i]) + } + j++ + for j < len(b) && (b[j] == ' ' || b[j] == '\t' || b[j] == '\n' || b[j] == '\r') { + // note: a lone \r not followed by \n will be caught on + // the next iteration of the outer loop. + if b[j] == '\r' { + if j+1 >= len(b) || b[j+1] != '\n' { + break + } + j++ + } + j++ + } + i = j + continue + } + var err error + buf, i, err = unescape(buf, b, i) + if err != nil { + return nil, nil, nil, err + } + case c >= 0x20 && c < 0x7f: + buf = append(buf, c) + i++ + case c == '\t' || c == '\n': + buf = append(buf, c) + i++ + case c == '\r': + if i+1 < len(b) && b[i+1] == '\n' { + buf = append(buf, '\r', '\n') + i += 2 + continue + } + return nil, nil, nil, NewParserError(b[i:i+1], "carriage returns must be followed by a newline character") + case c < 0x80: + return nil, nil, nil, NewParserError(b[i:i+1], "multiline basic strings cannot have control characters") + default: + j, ok := scanUtf8Run(b, i) + if !ok { + return nil, nil, nil, NewParserError(b[i:i+1], "invalid UTF-8 character in multiline basic string") + } + buf = append(buf, b[i:j]...) + i = j + } + } + return nil, nil, nil, NewParserError(b[len(b):], `multiline basic string not terminated by """`) +} + +// scanUtf8Run consumes a run of valid non-ASCII UTF-8 runes starting at +// b[i]. It returns the index of the first byte after the run, and whether +// the run was entirely valid. Processing whole runs amortizes the cost of +// the call compared to validating rune by rune. +func scanUtf8Run(b []byte, i int) (int, bool) { + for i < len(b) { + c := b[i] + switch { + case c < 0x80: + return i, true + case c < 0xC2: + return i, false + case c < 0xE0: + if i+1 >= len(b) || b[i+1]&0xC0 != 0x80 { + return i, false + } + i += 2 + case c < 0xF0: + if i+2 >= len(b) || b[i+2]&0xC0 != 0x80 { + return i, false + } + b1 := b[i+1] + switch c { + case 0xE0: + if b1 < 0xA0 || b1 > 0xBF { + return i, false + } + case 0xED: + // exclude surrogates + if b1 < 0x80 || b1 > 0x9F { + return i, false + } + default: + if b1&0xC0 != 0x80 { + return i, false + } + } + i += 3 + case c < 0xF5: + if i+3 >= len(b) || b[i+2]&0xC0 != 0x80 || b[i+3]&0xC0 != 0x80 { + return i, false + } + b1 := b[i+1] + switch c { + case 0xF0: + if b1 < 0x90 || b1 > 0xBF { + return i, false + } + case 0xF4: + if b1 < 0x80 || b1 > 0x8F { + return i, false + } + default: + if b1&0xC0 != 0x80 { + return i, false + } + } + i += 4 + default: + return i, false + } + } + return i, true } diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/scanner.go b/vendor/github.com/pelletier/go-toml/v2/unstable/scanner.go deleted file mode 100644 index 0512181d2..000000000 --- a/vendor/github.com/pelletier/go-toml/v2/unstable/scanner.go +++ /dev/null @@ -1,270 +0,0 @@ -package unstable - -import "github.com/pelletier/go-toml/v2/internal/characters" - -func scanFollows(b []byte, pattern string) bool { - n := len(pattern) - - return len(b) >= n && string(b[:n]) == pattern -} - -func scanFollowsMultilineBasicStringDelimiter(b []byte) bool { - return scanFollows(b, `"""`) -} - -func scanFollowsMultilineLiteralStringDelimiter(b []byte) bool { - return scanFollows(b, `'''`) -} - -func scanFollowsTrue(b []byte) bool { - return scanFollows(b, `true`) -} - -func scanFollowsFalse(b []byte) bool { - return scanFollows(b, `false`) -} - -func scanFollowsInf(b []byte) bool { - return scanFollows(b, `inf`) -} - -func scanFollowsNan(b []byte) bool { - return scanFollows(b, `nan`) -} - -func scanUnquotedKey(b []byte) ([]byte, []byte) { - // unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _ - for i := 0; i < len(b); i++ { - if !isUnquotedKeyChar(b[i]) { - return b[:i], b[i:] - } - } - - return b, b[len(b):] -} - -func isUnquotedKeyChar(r byte) bool { - return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' || r == '_' -} - -func scanLiteralString(b []byte) ([]byte, []byte, error) { - // literal-string = apostrophe *literal-char apostrophe - // apostrophe = %x27 ; ' apostrophe - // literal-char = %x09 / %x20-26 / %x28-7E / non-ascii - for i := 1; i < len(b); { - switch b[i] { - case '\'': - return b[:i+1], b[i+1:], nil - case '\n', '\r': - return nil, nil, NewParserError(b[i:i+1], "literal strings cannot have new lines") - } - size := characters.Utf8ValidNext(b[i:]) - if size == 0 { - return nil, nil, NewParserError(b[i:i+1], "invalid character") - } - i += size - } - - return nil, nil, NewParserError(b[len(b):], "unterminated literal string") -} - -func scanMultilineLiteralString(b []byte) ([]byte, []byte, error) { - // ml-literal-string = ml-literal-string-delim [ newline ] ml-literal-body - // ml-literal-string-delim - // ml-literal-string-delim = 3apostrophe - // ml-literal-body = *mll-content *( mll-quotes 1*mll-content ) [ mll-quotes ] - // - // mll-content = mll-char / newline - // mll-char = %x09 / %x20-26 / %x28-7E / non-ascii - // mll-quotes = 1*2apostrophe - for i := 3; i < len(b); { - switch b[i] { - case '\'': - if scanFollowsMultilineLiteralStringDelimiter(b[i:]) { - i += 3 - - // At that point we found 3 apostrophe, and i is the - // index of the byte after the third one. The scanner - // needs to be eager, because there can be an extra 2 - // apostrophe that can be accepted at the end of the - // string. - - if i >= len(b) || b[i] != '\'' { - return b[:i], b[i:], nil - } - i++ - - if i >= len(b) || b[i] != '\'' { - return b[:i], b[i:], nil - } - i++ - - if i < len(b) && b[i] == '\'' { - return nil, nil, NewParserError(b[i-3:i+1], "''' not allowed in multiline literal string") - } - - return b[:i], b[i:], nil - } - case '\r': - if len(b) < i+2 { - return nil, nil, NewParserError(b[len(b):], `need a \n after \r`) - } - if b[i+1] != '\n' { - return nil, nil, NewParserError(b[i:i+2], `need a \n after \r`) - } - i += 2 // skip the \n - continue - } - size := characters.Utf8ValidNext(b[i:]) - if size == 0 { - return nil, nil, NewParserError(b[i:i+1], "invalid character") - } - i += size - } - - return nil, nil, NewParserError(b[len(b):], `multiline literal string not terminated by '''`) -} - -func scanWindowsNewline(b []byte) ([]byte, []byte, error) { - const lenCRLF = 2 - if len(b) < lenCRLF { - return nil, nil, NewParserError(b, "windows new line expected") - } - - if b[1] != '\n' { - return nil, nil, NewParserError(b, `windows new line should be \r\n`) - } - - return b[:lenCRLF], b[lenCRLF:], nil -} - -func scanWhitespace(b []byte) ([]byte, []byte) { - for i := 0; i < len(b); i++ { - switch b[i] { - case ' ', '\t': - continue - default: - return b[:i], b[i:] - } - } - - return b, b[len(b):] -} - -func scanComment(b []byte) ([]byte, []byte, error) { - // comment-start-symbol = %x23 ; # - // non-ascii = %x80-D7FF / %xE000-10FFFF - // non-eol = %x09 / %x20-7F / non-ascii - // - // comment = comment-start-symbol *non-eol - - for i := 1; i < len(b); { - if b[i] == '\n' { - return b[:i], b[i:], nil - } - if b[i] == '\r' { - if i+1 < len(b) && b[i+1] == '\n' { - return b[:i+1], b[i+1:], nil - } - return nil, nil, NewParserError(b[i:i+1], "invalid character in comment") - } - size := characters.Utf8ValidNext(b[i:]) - if size == 0 { - return nil, nil, NewParserError(b[i:i+1], "invalid character in comment") - } - - i += size - } - - return b, b[len(b):], nil -} - -func scanBasicString(b []byte) ([]byte, bool, []byte, error) { - // basic-string = quotation-mark *basic-char quotation-mark - // quotation-mark = %x22 ; " - // basic-char = basic-unescaped / escaped - // basic-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii - // escaped = escape escape-seq-char - escaped := false - i := 1 - - for ; i < len(b); i++ { - switch b[i] { - case '"': - return b[:i+1], escaped, b[i+1:], nil - case '\n', '\r': - return nil, escaped, nil, NewParserError(b[i:i+1], "basic strings cannot have new lines") - case '\\': - if len(b) < i+2 { - return nil, escaped, nil, NewParserError(b[i:i+1], "need a character after \\") - } - escaped = true - i++ // skip the next character - } - } - - return nil, escaped, nil, NewParserError(b[len(b):], `basic string not terminated by "`) -} - -func scanMultilineBasicString(b []byte) ([]byte, bool, []byte, error) { - // ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body - // ml-basic-string-delim - // ml-basic-string-delim = 3quotation-mark - // ml-basic-body = *mlb-content *( mlb-quotes 1*mlb-content ) [ mlb-quotes ] - // - // mlb-content = mlb-char / newline / mlb-escaped-nl - // mlb-char = mlb-unescaped / escaped - // mlb-quotes = 1*2quotation-mark - // mlb-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii - // mlb-escaped-nl = escape ws newline *( wschar / newline ) - - escaped := false - i := 3 - - for ; i < len(b); i++ { - switch b[i] { - case '"': - if scanFollowsMultilineBasicStringDelimiter(b[i:]) { - i += 3 - - // At that point we found 3 apostrophe, and i is the - // index of the byte after the third one. The scanner - // needs to be eager, because there can be an extra 2 - // apostrophe that can be accepted at the end of the - // string. - - if i >= len(b) || b[i] != '"' { - return b[:i], escaped, b[i:], nil - } - i++ - - if i >= len(b) || b[i] != '"' { - return b[:i], escaped, b[i:], nil - } - i++ - - if i < len(b) && b[i] == '"' { - return nil, escaped, nil, NewParserError(b[i-3:i+1], `""" not allowed in multiline basic string`) - } - - return b[:i], escaped, b[i:], nil - } - case '\\': - if len(b) < i+2 { - return nil, escaped, nil, NewParserError(b[len(b):], "need a character after \\") - } - escaped = true - i++ // skip the next character - case '\r': - if len(b) < i+2 { - return nil, escaped, nil, NewParserError(b[len(b):], `need a \n after \r`) - } - if b[i+1] != '\n' { - return nil, escaped, nil, NewParserError(b[i:i+2], `need a \n after \r`) - } - i++ // skip the \n - } - } - - return nil, escaped, nil, NewParserError(b[len(b):], `multiline basic string not terminated by """`) -} diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go index 5a79da88e..c84c90ccf 100644 --- a/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go +++ b/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go @@ -1,20 +1,26 @@ package unstable -// Unmarshaler is implemented by types that can unmarshal a TOML -// description of themselves. The input is a valid TOML document -// containing the relevant portion of the parsed document. +// Unmarshaler is implemented by types that can unmarshal a TOML description +// of themselves. The input is a valid TOML document containing the relevant +// portion of the parsed document. // -// For tables (including split tables defined in multiple places), -// the data contains the raw key-value bytes from the original document -// with adjusted table headers to be relative to the unmarshaling target. +// For tables (including split tables defined in multiple places), the data +// contains the raw key-value bytes from the original document with adjusted +// table headers to be relative to the unmarshaling target. +// +// When the decoding target itself implements this interface, it receives the +// whole document — every top-level key-value as well as every table and array +// table — assembled into a single valid TOML document and delivered once. type Unmarshaler interface { UnmarshalTOML(data []byte) error } -// RawMessage is a raw encoded TOML value. It implements Unmarshaler -// and can be used to delay TOML decoding or capture raw content. +// RawMessage is a raw encoded TOML value. It implements both Unmarshaler and +// Marshaler and can be used to delay TOML decoding or capture raw content, +// similar to json.RawMessage. // -// Example usage: +// Decoding (requires Decoder.EnableUnmarshalerInterface) captures the raw TOML +// bytes for the target without decoding them: // // type Config struct { // Plugin RawMessage `toml:"plugin"` @@ -23,10 +29,15 @@ type Unmarshaler interface { // var cfg Config // toml.NewDecoder(r).EnableUnmarshalerInterface().Decode(&cfg) // // cfg.Plugin now contains the raw TOML bytes for [plugin] +// +// Encoding (requires Encoder.EnableMarshalerInterface) splices the stored bytes +// back into the document verbatim: +// +// toml.NewEncoder(w).EnableMarshalerInterface().Encode(cfg) type RawMessage []byte // UnmarshalTOML implements Unmarshaler. func (m *RawMessage) UnmarshalTOML(data []byte) error { - *m = append((*m)[0:0], data...) + *m = append((*m)[:0], data...) return 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 8547c8dfd..820bf436a 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/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go index 4ce84e7a8..7d963d3af 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 2331b8b4f..a3c92e7a4 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 de5a85629..327746f43 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 dd2eac940..41e54bf27 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 897a6e906..000000000 --- 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 6b8684731..1db1c4be0 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 c453b754a..88bae3b32 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 7bac0da33..2db270f21 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 5fe8d3b4d..a0285489a 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 76e59f128..c5cb90adf 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 b32c95fa3..2b16298f4 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 fa474289e..c08dd05f0 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 763d99e36..c28af5ce2 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 d3482c40c..024857974 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 9332b0249..9dec091ac 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 5d4383aa1..d4c0954f3 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,12 +70,30 @@ 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 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 = getExemplarFn + 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 }) } @@ -79,6 +101,8 @@ func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prom // 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/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go index c6fd2f58b..ed0681c8b 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 ac5203c6f..c12b8d13d 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 52344fef5..c1318ffb5 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 487b46656..121d2a963 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 2ed128506..697f55558 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/expfmt/expfmt.go b/vendor/github.com/prometheus/common/expfmt/expfmt.go index 4e4c13e72..10bf35708 100644 --- a/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ b/vendor/github.com/prometheus/common/expfmt/expfmt.go @@ -122,7 +122,7 @@ func NewOpenMetricsFormat(version string) (Format, error) { // removed. func (f Format) WithEscapingScheme(s model.EscapingScheme) Format { var terms []string - for _, p := range strings.Split(string(f), ";") { + for p := range strings.SplitSeq(string(f), ";") { toks := strings.Split(p, "=") if len(toks) != 2 { trimmed := strings.TrimSpace(p) @@ -194,7 +194,7 @@ func (f Format) FormatType() FormatType { // "escaping" term exists, that will be used. Otherwise, the global default will // be returned. func (f Format) ToEscapingScheme() model.EscapingScheme { - for _, p := range strings.Split(string(f), ";") { + for p := range strings.SplitSeq(string(f), ";") { toks := strings.Split(p, "=") if len(toks) != 2 { continue diff --git a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go index 21b93bca3..0480e7af5 100644 --- a/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go +++ b/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go @@ -30,7 +30,6 @@ import ( type encoderOption struct { withCreatedLines bool - withUnit bool } type EncoderOption func(*encoderOption) @@ -51,17 +50,6 @@ func WithCreatedLines() EncoderOption { } } -// WithUnit is an EncoderOption enabling a set unit to be written to the output -// and to be added to the metric name, if it's not there already, as a suffix. -// Without opting in this way, the unit will not be added to the metric name and, -// on top of that, the unit will not be passed onto the output, even if it -// were declared in the *dto.MetricFamily struct, i.e. even if in.Unit !=nil. -func WithUnit() EncoderOption { - return func(t *encoderOption) { - t.withUnit = true - } -} - // MetricFamilyToOpenMetrics converts a MetricFamily proto message into the // OpenMetrics text format and writes the resulting lines to 'out'. It returns // the number of bytes written and any error encountered. The output will have @@ -99,15 +87,6 @@ func WithUnit() EncoderOption { // its type will be set to `unknown` in that case to avoid invalid OpenMetrics // output. // -// - According to the OM specs, the `# UNIT` line is optional, but if populated, -// the unit has to be present in the metric name as its suffix: -// (see https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#unit). -// However, in order to accommodate any potential scenario where such a change in the -// metric name is not desirable, the users are here given the choice of either explicitly -// opt in, in case they wish for the unit to be included in the output AND in the metric name -// as a suffix (see the description of the WithUnit function above), -// or not to opt in, in case they don't want for any of that to happen. -// // - No support for the following (optional) features: info type, // stateset type, gaugehistogram type. // @@ -151,9 +130,6 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E if metricType == dto.MetricType_COUNTER && strings.HasSuffix(compliantName, "_total") { compliantName = name[:len(name)-6] } - if toOM.withUnit && in.Unit != nil && !strings.HasSuffix(compliantName, "_"+*in.Unit) { - compliantName = compliantName + "_" + *in.Unit - } // Comments, first HELP, then TYPE. if in.Help != nil { @@ -217,7 +193,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E if err != nil { return written, err } - if toOM.withUnit && in.Unit != nil { + if in.Unit != nil { n, err = w.WriteString("# UNIT ") written += n if err != nil { diff --git a/vendor/github.com/prometheus/common/expfmt/text_create.go b/vendor/github.com/prometheus/common/expfmt/text_create.go index 6b8978145..f4074ae9a 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_create.go +++ b/vendor/github.com/prometheus/common/expfmt/text_create.go @@ -42,12 +42,12 @@ const ( var ( bufPool = sync.Pool{ - New: func() interface{} { + New: func() any { return bufio.NewWriter(io.Discard) }, } numBufPool = sync.Pool{ - New: func() interface{} { + New: func() any { b := make([]byte, 0, initialNumBufSize) return &b }, diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go index 00c8841a1..4ce1f40b8 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -339,6 +339,16 @@ func (p *TextParser) startLabelName() stateFn { return nil // Unexpected end of input. } if p.currentByte == '}' { + if p.currentMF == nil { + // The closing brace was reached before any metric name was read, + // e.g. for the input "{}". There is no metric to attach labels to, + // so this is a malformed exposition. This mirrors the guard in + // startLabelValue. currentMF (not currentMetric) is checked because + // reset only clears currentMF between parses. + p.parseError("invalid metric name") + p.currentLabelPairs = nil + return nil + } p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) p.currentLabelPairs = nil if p.skipBlankTab(); p.err != nil { diff --git a/vendor/github.com/prometheus/common/model/labels.go b/vendor/github.com/prometheus/common/model/labels.go index dfeb34be5..29688a13c 100644 --- a/vendor/github.com/prometheus/common/model/labels.go +++ b/vendor/github.com/prometheus/common/model/labels.go @@ -124,7 +124,7 @@ func (ln LabelName) IsValidLegacy() bool { } // UnmarshalYAML implements the yaml.Unmarshaler interface. -func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (ln *LabelName) UnmarshalYAML(unmarshal func(any) error) error { var s string if err := unmarshal(&s); err != nil { return err diff --git a/vendor/github.com/prometheus/common/model/labelset.go b/vendor/github.com/prometheus/common/model/labelset.go index 9de47b256..6010b26a8 100644 --- a/vendor/github.com/prometheus/common/model/labelset.go +++ b/vendor/github.com/prometheus/common/model/labelset.go @@ -16,6 +16,7 @@ package model import ( "encoding/json" "fmt" + "maps" "sort" ) @@ -107,9 +108,7 @@ func (ls LabelSet) Before(o LabelSet) bool { // Clone returns a copy of the label set. func (ls LabelSet) Clone() LabelSet { lsn := make(LabelSet, len(ls)) - for ln, lv := range ls { - lsn[ln] = lv - } + maps.Copy(lsn, ls) return lsn } @@ -117,13 +116,9 @@ func (ls LabelSet) Clone() LabelSet { func (ls LabelSet) Merge(other LabelSet) LabelSet { result := make(LabelSet, len(ls)) - for k, v := range ls { - result[k] = v - } + maps.Copy(result, ls) - for k, v := range other { - result[k] = v - } + maps.Copy(result, other) return result } diff --git a/vendor/github.com/prometheus/common/model/metric.go b/vendor/github.com/prometheus/common/model/metric.go index 3feebf328..2fe461511 100644 --- a/vendor/github.com/prometheus/common/model/metric.go +++ b/vendor/github.com/prometheus/common/model/metric.go @@ -17,6 +17,7 @@ import ( "encoding/json" "errors" "fmt" + "maps" "regexp" "sort" "strconv" @@ -24,7 +25,6 @@ import ( "unicode/utf8" dto "github.com/prometheus/client_model/go" - "go.yaml.in/yaml/v2" "google.golang.org/protobuf/proto" ) @@ -78,14 +78,6 @@ const ( UTF8Validation ) -var _ interface { - yaml.Marshaler - yaml.Unmarshaler - json.Marshaler - json.Unmarshaler - fmt.Stringer -} = new(ValidationScheme) - // String returns the string representation of s. func (s ValidationScheme) String() string { switch s { @@ -267,9 +259,7 @@ func (m Metric) Before(o Metric) bool { // Clone returns a copy of the Metric. func (m Metric) Clone() Metric { clone := make(Metric, len(m)) - for k, v := range m { - clone[k] = v - } + maps.Copy(clone, m) return clone } diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index 1730b0fdc..0854753f4 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -123,44 +123,38 @@ func (t Time) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the json.Unmarshaler interface. func (t *Time) UnmarshalJSON(b []byte) error { - p := strings.Split(string(b), ".") - switch len(p) { - case 1: - v, err := strconv.ParseInt(p[0], 10, 64) + base, frac, found := strings.Cut(string(b), ".") + if !found { + v, err := strconv.ParseInt(base, 10, 64) if err != nil { return err } *t = Time(v * second) - - case 2: - v, err := strconv.ParseInt(p[0], 10, 64) + } else { + v, err := strconv.ParseInt(base, 10, 64) if err != nil { return err } - v *= second - prec := dotPrecision - len(p[1]) + prec := dotPrecision - len(frac) if prec < 0 { - p[1] = p[1][:dotPrecision] - } else if prec > 0 { - p[1] += strings.Repeat("0", prec) + frac = frac[:dotPrecision] } - - va, err := strconv.ParseInt(p[1], 10, 32) + va, err := strconv.ParseInt(frac, 10, 32) if err != nil { return err } - - // If the value was something like -0.1 the negative is lost in the - // parsing because of the leading zero, this ensures that we capture it. - if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 { - *t = Time(v+va) * -1 - } else { - *t = Time(v + va) + switch prec { + case 1: + va *= 10 + case 2: + va *= 100 } - default: - return fmt.Errorf("invalid time %q", string(b)) + if len(base) > 0 && base[0] == '-' { + va = -va + } + *t = Time(v*second + va) } return nil } @@ -340,12 +334,12 @@ func (d *Duration) UnmarshalText(text []byte) error { } // MarshalYAML implements the yaml.Marshaler interface. -func (d Duration) MarshalYAML() (interface{}, error) { +func (d Duration) MarshalYAML() (any, error) { return d.String(), nil } // UnmarshalYAML implements the yaml.Unmarshaler interface. -func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (d *Duration) UnmarshalYAML(unmarshal func(any) error) error { var s string if err := unmarshal(&s); err != nil { return err diff --git a/vendor/github.com/prometheus/common/model/value.go b/vendor/github.com/prometheus/common/model/value.go index a9995a37e..8dffd9c4a 100644 --- a/vendor/github.com/prometheus/common/model/value.go +++ b/vendor/github.com/prometheus/common/model/value.go @@ -259,13 +259,13 @@ func (s Scalar) String() string { // MarshalJSON implements json.Marshaler. func (s Scalar) MarshalJSON() ([]byte, error) { v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64) - return json.Marshal([...]interface{}{s.Timestamp, v}) + return json.Marshal([...]any{s.Timestamp, v}) } // UnmarshalJSON implements json.Unmarshaler. func (s *Scalar) UnmarshalJSON(b []byte) error { var f string - v := [...]interface{}{&s.Timestamp, &f} + v := [...]any{&s.Timestamp, &f} if err := json.Unmarshal(b, &v); err != nil { return err @@ -291,12 +291,12 @@ func (s *String) String() string { // MarshalJSON implements json.Marshaler. func (s String) MarshalJSON() ([]byte, error) { - return json.Marshal([]interface{}{s.Timestamp, s.Value}) + return json.Marshal([]any{s.Timestamp, s.Value}) } // UnmarshalJSON implements json.Unmarshaler. func (s *String) UnmarshalJSON(b []byte) error { - v := [...]interface{}{&s.Timestamp, &s.Value} + v := [...]any{&s.Timestamp, &s.Value} return json.Unmarshal(b, &v) } diff --git a/vendor/github.com/prometheus/common/model/value_float.go b/vendor/github.com/prometheus/common/model/value_float.go index 6bfc757d1..b7d93615e 100644 --- a/vendor/github.com/prometheus/common/model/value_float.go +++ b/vendor/github.com/prometheus/common/model/value_float.go @@ -79,7 +79,7 @@ func (s SamplePair) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil + return fmt.Appendf(nil, "[%s,%s]", t, v), nil } // UnmarshalJSON implements json.Unmarshaler. diff --git a/vendor/github.com/prometheus/common/model/value_histogram.go b/vendor/github.com/prometheus/common/model/value_histogram.go index 91ce5b7a4..f27856ccc 100644 --- a/vendor/github.com/prometheus/common/model/value_histogram.go +++ b/vendor/github.com/prometheus/common/model/value_histogram.go @@ -67,11 +67,11 @@ func (s HistogramBucket) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - return []byte(fmt.Sprintf("[%s,%s,%s,%s]", b, l, u, c)), nil + return fmt.Appendf(nil, "[%s,%s,%s,%s]", b, l, u, c), nil } func (s *HistogramBucket) UnmarshalJSON(buf []byte) error { - tmp := []interface{}{&s.Boundaries, &s.Lower, &s.Upper, &s.Count} + tmp := []any{&s.Boundaries, &s.Lower, &s.Upper, &s.Count} wantLen := len(tmp) if err := json.Unmarshal(buf, &tmp); err != nil { return err @@ -152,11 +152,11 @@ func (s SampleHistogramPair) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil + return fmt.Appendf(nil, "[%s,%s]", t, v), nil } func (s *SampleHistogramPair) UnmarshalJSON(buf []byte) error { - tmp := []interface{}{&s.Timestamp, &s.Histogram} + tmp := []any{&s.Timestamp, &s.Histogram} wantLen := len(tmp) if err := json.Unmarshal(buf, &tmp); err != nil { return err diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common index cce3ef1d1..a7c5f553e 100644 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ b/vendor/github.com/prometheus/procfs/Makefile.common @@ -55,13 +55,13 @@ ifneq ($(shell command -v gotestsum 2> /dev/null),) endif endif -PROMU_VERSION ?= 0.18.0 +PROMU_VERSION ?= 0.20.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz SKIP_GOLANGCI_LINT := GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v2.10.1 +GOLANGCI_LINT_VERSION ?= v2.11.4 GOLANGCI_FMT_OPTS ?= # golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64. # windows isn't included here because of the path separator being different. @@ -90,8 +90,8 @@ ifdef DOCKERFILE_PATH $(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile) endif -DOCKER_ARCHS ?= amd64 -DOCKERFILE_VARIANTS ?= Dockerfile $(wildcard Dockerfile.*) +DOCKER_ARCHS ?= amd64 arm64 armv7 ppc64le riscv64 s390x +DOCKERFILE_VARIANTS ?= $(wildcard Dockerfile Dockerfile.*) # Function to extract variant from Dockerfile label. # Returns the variant name from io.prometheus.image.variant label, or "default" if not found. @@ -109,24 +109,6 @@ endif # Build variant:dockerfile pairs for shell iteration. DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df)) -# Shell helper to check whether a dockerfile/arch pair is excluded. -define dockerfile_arch_is_excluded -case " $(DOCKERFILE_ARCH_EXCLUSIONS) " in \ - *" $$dockerfile:$(1) "*) true ;; \ - *) false ;; \ -esac -endef - -# Shell helper to check whether a registry/arch pair is excluded. -# Extracts registry from DOCKER_REPO (e.g., quay.io/prometheus -> quay.io) -define registry_arch_is_excluded -registry=$$(echo "$(DOCKER_REPO)" | cut -d'/' -f1); \ -case " $(DOCKER_REGISTRY_ARCH_EXCLUSIONS) " in \ - *" $$registry:$(1) "*) true ;; \ - *) false ;; \ -esac -endef - BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) @@ -268,10 +250,6 @@ $(BUILD_DOCKER_ARCHS): common-docker-%: @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ dockerfile=$${variant#*:}; \ variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping $$variant_name variant for linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ distroless_arch="$*"; \ if [ "$*" = "armv7" ]; then \ distroless_arch="arm"; \ @@ -306,14 +284,6 @@ $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ dockerfile=$${variant#*:}; \ variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping push for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$*); then \ - echo "Skipping push for $$variant_name variant on linux-$* to $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ echo "Pushing $$variant_name variant for linux-$*"; \ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ @@ -341,14 +311,6 @@ $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \ dockerfile=$${variant#*:}; \ variant_name=$${variant%%:*}; \ - if $(call dockerfile_arch_is_excluded,$*); then \ - echo "Skipping tag for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$*); then \ - echo "Skipping tag for $$variant_name variant on linux-$* for $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \ echo "Tagging $$variant_name variant for linux-$* as latest"; \ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \ @@ -370,14 +332,6 @@ common-docker-manifest: echo "Creating manifest for $$variant_name variant"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \ done; \ if [ -z "$$refs" ]; then \ @@ -391,14 +345,6 @@ common-docker-manifest: echo "Creating default variant ($$variant_name) manifest"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)"; \ done; \ if [ -z "$$refs" ]; then \ @@ -413,14 +359,6 @@ common-docker-manifest: echo "Creating manifest for $$variant_name variant version tag"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for $$variant_name version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \ done; \ if [ -z "$$refs" ]; then \ @@ -434,14 +372,6 @@ common-docker-manifest: echo "Creating default variant version tag manifest"; \ refs=""; \ for arch in $(DOCKER_ARCHS); do \ - if $(call dockerfile_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ - if $(call registry_arch_is_excluded,$$arch); then \ - echo " Skipping $$arch for default variant version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \ - continue; \ - fi; \ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)"; \ done; \ if [ -z "$$refs" ]; then \ @@ -495,9 +425,3 @@ $(1)_precheck: exit 1; \ fi endef - -govulncheck: install-govulncheck - govulncheck ./... - -install-govulncheck: - command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md index 0718239cf..363524094 100644 --- a/vendor/github.com/prometheus/procfs/README.md +++ b/vendor/github.com/prometheus/procfs/README.md @@ -7,7 +7,7 @@ metrics from the pseudo-filesystems /proc and /sys. backwards-incompatible ways without warnings. Use it at your own risk. [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/procfs.svg)](https://pkg.go.dev/github.com/prometheus/procfs) -[![CircleCI](https://circleci.com/gh/prometheus/procfs/tree/master.svg?style=svg)](https://circleci.com/gh/prometheus/procfs/tree/master) +[![Build Status](https://github.com/prometheus/procfs/actions/workflows/ci.yml/badge.svg)](https://github.com/prometheus/procfs/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs) ## Usage diff --git a/vendor/github.com/prometheus/procfs/SECURITY.md b/vendor/github.com/prometheus/procfs/SECURITY.md index fed02d85c..5e6f976db 100644 --- a/vendor/github.com/prometheus/procfs/SECURITY.md +++ b/vendor/github.com/prometheus/procfs/SECURITY.md @@ -3,4 +3,4 @@ The Prometheus security policy, including how to report vulnerabilities, can be found here: - +[https://prometheus.io/docs/operating/security/](https://prometheus.io/docs/operating/security/) diff --git a/vendor/github.com/prometheus/procfs/crypto.go b/vendor/github.com/prometheus/procfs/crypto.go index e4a5876ea..d93b712e0 100644 --- a/vendor/github.com/prometheus/procfs/crypto.go +++ b/vendor/github.com/prometheus/procfs/crypto.go @@ -48,11 +48,13 @@ type Crypto struct { Walksize *uint64 } +var cryptoFile = "crypto" + // Crypto parses an crypto-file (/proc/crypto) and returns a slice of // structs containing the relevant info. More information available here: // https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html func (fs FS) Crypto() ([]Crypto, error) { - path := fs.proc.Path("crypto") + path := fs.proc.Path(cryptoFile) b, err := util.ReadFileNoStat(path) if err != nil { return nil, fmt.Errorf("%w: Cannot read file %v: %w", ErrFileRead, b, err) @@ -82,6 +84,10 @@ func parseCrypto(r io.Reader) ([]Crypto, error) { continue } + if len(out) == 0 { + return nil, fmt.Errorf("%w: parsed invalid line before name parsed: %q", ErrFileParse, text) + } + kv := strings.Split(text, ":") if len(kv) != 2 { return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, text) diff --git a/vendor/github.com/prometheus/procfs/mountinfo.go b/vendor/github.com/prometheus/procfs/mountinfo.go index 9414a12f4..8594ae7f1 100644 --- a/vendor/github.com/prometheus/procfs/mountinfo.go +++ b/vendor/github.com/prometheus/procfs/mountinfo.go @@ -17,10 +17,10 @@ import ( "bufio" "bytes" "fmt" + "io" + "os" "strconv" "strings" - - "github.com/prometheus/procfs/internal/util" ) // A MountInfo is a type that describes the details, options @@ -160,9 +160,19 @@ func mountOptionsParser(mountOptions string) map[string]string { return opts } +// readMountInfo reads a full mountinfo file (no 1 MiB cap, unlike util.ReadFileNoStat). +func readMountInfo(path string) ([]byte, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return io.ReadAll(f) +} + // GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. func GetMounts() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat("/proc/self/mountinfo") + data, err := readMountInfo("/proc/self/mountinfo") if err != nil { return nil, err } @@ -171,7 +181,7 @@ func GetMounts() ([]*MountInfo, error) { // GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. func GetProcMounts(pid int) ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid)) + data, err := readMountInfo(fmt.Sprintf("/proc/%d/mountinfo", pid)) if err != nil { return nil, err } @@ -180,7 +190,7 @@ func GetProcMounts(pid int) ([]*MountInfo, error) { // GetMounts retrieves mountinfo information from `/proc/self/mountinfo`. func (fs FS) GetMounts() ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo")) + data, err := readMountInfo(fs.proc.Path("self/mountinfo")) if err != nil { return nil, err } @@ -189,7 +199,7 @@ func (fs FS) GetMounts() ([]*MountInfo, error) { // GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`. func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) { - data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid))) + data, err := readMountInfo(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid))) if err != nil { return nil, err } diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go index 69d079445..f74dd3bed 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 535c08d6f..7e8a12297 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/sirupsen/logrus/.golangci.yml b/vendor/github.com/sirupsen/logrus/.golangci.yml index 792db3618..c9a840e0d 100644 --- a/vendor/github.com/sirupsen/logrus/.golangci.yml +++ b/vendor/github.com/sirupsen/logrus/.golangci.yml @@ -1,12 +1,9 @@ version: "2" -run: - tests: false linters: enable: - asasalint - asciicheck - bidichk - - bodyclose - contextcheck - durationcheck - errchkjson @@ -22,46 +19,21 @@ linters: - nilerr - nilnesserr - noctx - - protogetter - reassign - recvcheck - - rowserrcheck - - spancheck - - sqlclosecheck - testifylint - unparam - - zerologlint - disable: - - prealloc - settings: - errcheck: - check-type-assertions: false - check-blank: false - lll: - line-length: 100 - tab-width: 4 - prealloc: - simple: false - range-loops: false - for-loops: false - whitespace: - multi-if: false - multi-func: false exclusions: - generated: lax presets: - - comments - - common-false-positives - legacy - std-error-handling - paths: - - third_party$ - - builtin$ - - examples$ -formatters: - exclusions: - generated: lax - paths: - - third_party$ - - builtin$ - - examples$ + rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - gosec + - musttag + - noctx # TODO: enable once we switch to Go 1.24+. + - linters: # TODO: remove once golangci-lint is updated with https://github.com/golangci/golangci-lint/pull/6584 + - gocheckcompilerdirectives + text: 'compiler directive unrecognized: //go:fix' diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml deleted file mode 100644 index c1dbd5a3a..000000000 --- a/vendor/github.com/sirupsen/logrus/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go_import_path: github.com/sirupsen/logrus -git: - depth: 1 -env: - - GO111MODULE=on -go: 1.15.x -os: linux -install: - - ./travis/install.sh -script: - - cd ci - - go run mage.go -v -w ../ crossBuild - - go run mage.go -v -w ../ lint - - go run mage.go -v -w ../ test diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md index 098608ff4..3e6675633 100644 --- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -1,90 +1,246 @@ -# 1.8.1 +# Changelog + +All notable changes to this project will be documented in this file. + +## 1.10.1 + +Fixes: + + * Fix a regression introduced in v1.10.0 where `TextFormatter` could panic + when formatting nil or panicking `error` and `fmt.Stringer` values. + * Allow function-backed implementations of `error` as field values. + +## 1.10.0 + +Fixes: + + * Fix reentrant logging deadlocks in formatter paths. + * Fix race conditions in formatter and entry handling. + * Fix generic `Log`, `Logf`, `Logln`, and `LogFn` methods unexpectedly + panicking when called with `PanicLevel`. Use the corresponding `Panic` + methods when panic behavior is desired. + * Improve concurrency safety around formatter and hook access. + +Features: + + * Add `slog` hook for forwarding Logrus entries to `log/slog`. + * Add `slog.Handler` for forwarding `log/slog` records to a Logrus logger, + including levels, fields, groups, context, time, and optional caller + reporting. The hook and handler can also be combined to help migrate + between Logrus and `log/slog`. + * Add minimal, composable logging interfaces for each log level. This enables + consumers to depend on narrower interfaces, making it easier to substitute + or adapt logging implementations. + * Allow `Entry.Caller` to be set explicitly and preserve it across derived + entries, enabling custom caller detection without Logrus overwriting + caller information when `ReportCaller` is enabled. + +Changed: + + * Raise minimum supported Go version to 1.23. + * TextFormatter now renders `[]byte` values as raw/quoted strings instead of slice-of-ints. + * TextFormatter now uses distinct dimmed colors for debug and trace output. + * TextFormatter now automatically enables colors on Windows terminals with ANSI support, + matching the behavior on other platforms. + * `Entry.HasCaller` is now deprecated in favor of checking `Entry.Caller` directly. + * Deprecated `MutexWrap`, which was unintentionally exposed as public API. + It remains available as an alias for compatibility but should not be used + directly. + +Performance: + + * Significantly improve TextFormatter performance and reduce allocations. + * Optimize common Entry and Logger hot paths. + * Reduce allocations in caller reporting. + * ~17% lower geomean runtime and ~27% higher formatter throughput overall. + * Common enabled logging paths are ~30–44% faster. + * TextFormatter paths are up to ~40% faster, with allocation counts reduced + by 25–74% across the measured formatter cases. + + +## 1.9.4 + +Fixes: + + * Remove uses of deprecated `ioutil` package + +Features: + + * Add GNU/Hurd support + * Add WASI wasip1 support + Code quality: + + * Update minimum supported Go version to 1.17 + * Documentation updates + + +## 1.9.3 + +Fixes: + + * Re-apply fix for potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376) + * Fix panic in Writer + + +## 1.9.2 + +Fixes: + + * Revert Writer DoS fix (#1376) due to regression + + +## 1.9.1 + +Fixes: + + * Fix potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376) + + +## 1.9.0 + +Fixes: + + * Multiple concurrency and race condition fixes + * Improve Windows terminal and ANSI handling + +Code quality: + + * Internal cleanups and modernization + + +## 1.8.3 + +Fixes: + + * Fix potential denial of service in logrus.Writer() when logging >64KB single-line payloads without newlines (#1376) + + +## 1.8.2 + +Features: + + * Add support for the logger private buffer pool (#1253) + +Fixes: + + * Fix race condition for SetFormatter and SetReportCaller + * Fix data race in hooks test package + +## 1.8.1 + +Code quality: + * move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer * improve timestamp format documentation Fixes: + * fix race condition on logger hooks -# 1.8.0 +## 1.8.0 Correct versioning number replacing v1.7.1. -# 1.7.1 +## 1.7.1 Beware this release has introduced a new public API and its semver is therefore incorrect. Code quality: + * use go 1.15 in travis * use magefile as task runner Fixes: + * small fixes about new go 1.13 error formatting system * Fix for long time race condiction with mutating data hooks Features: + * build support for zos -# 1.7.0 +## 1.7.0 + Fixes: + * the dependency toward a windows terminal library has been removed Features: + * a new buffer pool management API has been added * a set of `Fn()` functions have been added -# 1.6.0 +## 1.6.0 + Fixes: + * end of line cleanup * revert the entry concurrency bug fix which leads to deadlock under some circumstances * update dependency on go-windows-terminal-sequences to fix a crash with go 1.14 Features: + * add an option to the `TextFormatter` to completely disable fields quoting -# 1.5.0 +## 1.5.0 + Code quality: + * add golangci linter run on travis Fixes: + * add mutex for hooks concurrent access on `Entry` data * caller function field for go1.14 * fix build issue for gopherjs target Feature: + * add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level * add a `DisableHTMLEscape` option in the `JSONFormatter` * add `ForceQuote` and `PadLevelText` options in the `TextFormatter` -# 1.4.2 +## 1.4.2 + * Fixes build break for plan9, nacl, solaris -# 1.4.1 + +## 1.4.1 + This new release introduces: + * Enhance TextFormatter to not print caller information when they are empty (#944) * Remove dependency on golang.org/x/crypto (#932, #943) Fixes: + * Fix Entry.WithContext method to return a copy of the initial entry (#941) -# 1.4.0 +## 1.4.0 + This new release introduces: + * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848). * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911) * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919). Fixes: + * Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893). * Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903) * Fix infinite recursion on unknown `Level.String()` (#907) * Fix race condition in `getCaller` (#916). -# 1.3.0 +## 1.3.0 + This new release introduces: + * Log, Logf, Logln functions for Logger and Entry that take a Level Fixes: + * Building prometheus node_exporter on AIX (#840) * Race condition in TextFormatter (#468) * Travis CI import path (#868) @@ -92,20 +248,26 @@ Fixes: * Pointer to func as field in JSONFormatter (#870) * Properly marshal Levels (#873) -# 1.2.0 +## 1.2.0 + This new release introduces: + * A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued * A new trace level named `Trace` whose level is below `Debug` * A configurable exit function to be called upon a Fatal trace * The `Level` object now implements `encoding.TextUnmarshaler` interface -# 1.1.1 +## 1.1.1 + This is a bug fix release. + * fix the build break on Solaris * don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized -# 1.1.0 +## 1.1.0 + This new release introduces: + * several fixes: * a fix for a race condition on entry formatting * proper cleanup of previously used entries before putting them back in the pool @@ -122,9 +284,10 @@ This new release introduces: * the field sort function is now configurable for text formatter * the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater -# 1.0.6 +## 1.0.6 This new release introduces: + * a new api WithTime which allows to easily force the time of the log entry which is mostly useful for logger wrapper * a fix reverting the immutability of the entry given as parameter to the hooks @@ -134,71 +297,71 @@ This new release introduces: * a new configuration of the textformatter to configure the name of the default keys * a new configuration of the text formatter to disable the level truncation -# 1.0.5 +## 1.0.5 * Fix hooks race (#707) * Fix panic deadlock (#695) -# 1.0.4 +## 1.0.4 * Fix race when adding hooks (#612) * Fix terminal check in AppEngine (#635) -# 1.0.3 +## 1.0.3 * Replace example files with testable examples -# 1.0.2 +## 1.0.2 * bug: quote non-string values in text formatter (#583) * Make (*Logger) SetLevel a public method -# 1.0.1 +## 1.0.1 * bug: fix escaping in text formatter (#575) -# 1.0.0 +## 1.0.0 * Officially changed name to lower-case * bug: colors on Windows 10 (#541) * bug: fix race in accessing level (#512) -# 0.11.5 +## 0.11.5 * feature: add writer and writerlevel to entry (#372) -# 0.11.4 +## 0.11.4 * bug: fix undefined variable on solaris (#493) -# 0.11.3 +## 0.11.3 * formatter: configure quoting of empty values (#484) * formatter: configure quoting character (default is `"`) (#484) * bug: fix not importing io correctly in non-linux environments (#481) -# 0.11.2 +## 0.11.2 * bug: fix windows terminal detection (#476) -# 0.11.1 +## 0.11.1 * bug: fix tty detection with custom out (#471) -# 0.11.0 +## 0.11.0 * performance: Use bufferpool to allocate (#370) * terminal: terminal detection for app-engine (#343) * feature: exit handler (#375) -# 0.10.0 +## 0.10.0 * feature: Add a test hook (#180) * feature: `ParseLevel` is now case-insensitive (#326) * feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308) * performance: avoid re-allocations on `WithFields` (#335) -# 0.9.0 +## 0.9.0 * logrus/text_formatter: don't emit empty msg * logrus/hooks/airbrake: move out of main repository @@ -210,25 +373,25 @@ This new release introduces: * logrus/core: support `WithError` on logger * logrus/core: Solaris support -# 0.8.7 +## 0.8.7 * logrus/core: fix possible race (#216) * logrus/doc: small typo fixes and doc improvements -# 0.8.6 +## 0.8.6 * hooks/raven: allow passing an initialized client -# 0.8.5 +## 0.8.5 * logrus/core: revert #208 -# 0.8.4 +## 0.8.4 * formatter/text: fix data race (#218) -# 0.8.3 +## 0.8.3 * logrus/core: fix entry log level (#208) * logrus/core: improve performance of text formatter by 40% @@ -236,24 +399,24 @@ This new release introduces: * logrus/core: add support for DragonflyBSD and NetBSD * formatter/text: print structs more verbosely -# 0.8.2 +## 0.8.2 * logrus: fix more Fatal family functions -# 0.8.1 +## 0.8.1 * logrus: fix not exiting on `Fatalf` and `Fatalln` -# 0.8.0 +## 0.8.0 * logrus: defaults to stderr instead of stdout * hooks/sentry: add special field for `*http.Request` * formatter/text: ignore Windows for colors -# 0.7.3 +## 0.7.3 * formatter/\*: allow configuration of timestamp layout -# 0.7.2 +## 0.7.2 * formatter/text: Add configuration option for time format (#158) diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index cc5dab7eb..b2ff7affc 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -3,13 +3,10 @@ Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger. -**Logrus is in maintenance-mode.** We will not be introducing new features. It's -simply too hard to do in a way that won't break many people's projects, which is -the last thing you want from your Logging library (again...). - -This does not mean Logrus is dead. Logrus will continue to be maintained for -security, (backwards compatible) bug fixes, and performance (where we are -limited by the interface). +**Logrus is in maintenance mode.** The project focuses on security, bug fixes, +and performance improvements. New features are not planned, aside from changes +required to provide interoperability with other logging ecosystems (e.g., Go's +[log/slog](https://pkg.go.dev/log/slog)). I believe Logrus' biggest contribution is to have played a part in today's widespread use of structured logging in Golang. There doesn't seem to be a @@ -23,18 +20,6 @@ about structured logging in Go today. Check out, for example, [zap]: https://github.com/uber-go/zap [apex]: https://github.com/apex/log -**Seeing weird case-sensitive problems?** It's in the past been possible to -import Logrus as both upper- and lower-case. Due to the Go package environment, -this caused issues in the community and we needed a standard. Some environments -experienced problems with the upper-case variant, so the lower-case was decided. -Everything using `logrus` will need to use the lower-case: -`github.com/sirupsen/logrus`. Any package that isn't, should be changed. - -To fix Glide, see [these -comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). -For an in-depth explanation of the casing issue, see [this -comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). - Nicely color-coded in development (when a TTY is attached, otherwise just plain text): @@ -43,35 +28,27 @@ plain text): With `logrus.SetFormatter(&logrus.JSONFormatter{})`, for easy parsing by logstash or Splunk: -```text -{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the -ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} - -{"level":"warning","msg":"The group's number increased tremendously!", -"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"A giant walrus appears!", -"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", -"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} - -{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, -"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +```json lines +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} +{"level":"warning","msg":"The group's number increased tremendously!","number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} +{"animal":"walrus","level":"info","msg":"A giant walrus appears!","size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.","size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} ``` With the default `logrus.SetFormatter(&logrus.TextFormatter{})` when a TTY is not attached, the output is compatible with the [logfmt](https://pkg.go.dev/github.com/kr/logfmt) format: -```text +```bash time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 -time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true +time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" animal=orca err="It's over 9000!" number=100 omg=true size=9009 ``` + To ensure this behaviour even if a TTY is attached, set your formatter as follows: ```go @@ -88,29 +65,32 @@ If you wish to add the calling method as a field, instruct the logger via: ```go logrus.SetReportCaller(true) ``` + This adds the caller as 'method' like so: ```json -{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by", -"time":"2014-03-10 19:57:38.562543129 -0400 EDT"} +{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by","time":"2014-03-10 19:57:38.562543129 -0400 EDT"} ``` -```text +```bash time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin ``` + Note that this does add measurable overhead - the cost will depend on the version of Go, but is between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your environment via benchmarks: ```bash -go test -bench=.*CallerTracing +go test -bench=ReportCaller ``` #### Case-sensitivity -The organization's name was changed to lower-case--and this will not be changed -back. If you are getting import conflicts due to case sensitivity, please use -the lower-case import: `github.com/sirupsen/logrus`. +The organization's name was [changed to lower-case][1]. If you are getting import +conflicts due to case sensitivity, please use the lower-case import: +`github.com/sirupsen/logrus`. + +[1]: https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276 #### Example @@ -289,6 +269,7 @@ func init() { } } ``` + Note: Syslog hooks also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) @@ -367,18 +348,21 @@ Splunk or Logstash. The built-in logging formatters are: -* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise - without colors. - * *Note:* to force colored output when there is no TTY, set the `ForceColors` +* [`logrus.TextFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter) + logs the event in colors if the logger output is a TTY, otherwise without colors. + * To force colored output when there is no TTY, set the `ForceColors` field to `true`. To force no colored output even if there is a TTY set the - `DisableColors` field to `true`. For Windows, see - [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). + `DisableColors` field to `true`. + * On modern Windows terminals with ANSI (Virtual Terminal) support, TextFormatter + automatically enables colored output. + * If your environment does not support ANSI escape sequences, wrap the logger output + using [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable) + and set `ForceColors` (or `CLICOLOR_FORCE=1`) to enable colors through the wrapper. * When colors are enabled, levels are truncated to 4 characters by default. To disable truncation set the `DisableLevelTruncation` field to `true`. * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text. - * All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#TextFormatter). -* `logrus.JSONFormatter`. Logs fields as JSON. - * All options are listed in the [generated docs](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter). +* [`logrus.JSONFormatter`](https://pkg.go.dev/github.com/sirupsen/logrus#JSONFormatter) + logs fields as JSON. Third-party logging formatters: @@ -390,10 +374,12 @@ Third-party logging formatters: * [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. * [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Save log to files. * [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added. +* [`easy-logrus-formatter`](https://github.com/WeiZhixiong/easy-logrus-formatter). Provide a user-friendly formatter for logrus. +* [`redactrus`](https://github.com/ibreakthecloud/redactrus). Redacts sensitive information like password, apikeys, email, etc. from logs. You can define your formatter by implementing the `Formatter` interface, requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a -`Fields` type (`map[string]interface{}`) with all your fields as well as the +`Fields` type (`map[string]any`) with all your fields as well as the default ones (see Entries section above): ```go @@ -516,4 +502,4 @@ Situations when locking is not needed include: 2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing) - (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) + (Refer to ) diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go index 8fd189e1c..1c35cf81c 100644 --- a/vendor/github.com/sirupsen/logrus/alt_exit.go +++ b/vendor/github.com/sirupsen/logrus/alt_exit.go @@ -57,7 +57,7 @@ func Exit(code int) { // // This method is useful when a caller wishes to use logrus to log a fatal // message but also needs to gracefully shutdown. An example usecase could be -// closing database connections, or sending a alert that the application is +// closing database connections, or sending an alert that the application is // closing. func RegisterExitHandler(handler func()) { handlers = append(handlers, handler) @@ -69,7 +69,7 @@ func RegisterExitHandler(handler func()) { // // This method is useful when a caller wishes to use logrus to log a fatal // message but also needs to gracefully shutdown. An example usecase could be -// closing database connections, or sending a alert that the application is +// closing database connections, or sending an alert that the application is // closing. func DeferExitHandler(handler func()) { handlers = append([]func(){handler}, handlers...) diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go index c7787f77c..6b562d870 100644 --- a/vendor/github.com/sirupsen/logrus/buffer_pool.go +++ b/vendor/github.com/sirupsen/logrus/buffer_pool.go @@ -5,9 +5,13 @@ import ( "sync" ) -var ( - bufferPool BufferPool -) +var bufferPool BufferPool = &defaultPool{ + pool: &sync.Pool{ + New: func() any { + return new(bytes.Buffer) + }, + }, +} type BufferPool interface { Put(*bytes.Buffer) @@ -27,17 +31,7 @@ func (p *defaultPool) Get() *bytes.Buffer { } // SetBufferPool allows to replace the default logrus buffer pool -// to better meets the specific needs of an application. +// to better meet the specific needs of an application. func SetBufferPool(bp BufferPool) { bufferPool = bp } - -func init() { - SetBufferPool(&defaultPool{ - pool: &sync.Pool{ - New: func() interface{} { - return new(bytes.Buffer) - }, - }, - }) -} diff --git a/vendor/github.com/sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go index da67aba06..75186dc2d 100644 --- a/vendor/github.com/sirupsen/logrus/doc.go +++ b/vendor/github.com/sirupsen/logrus/doc.go @@ -1,25 +1,25 @@ /* Package logrus is a structured logger for Go, completely API compatible with the standard library logger. - The simplest way to use Logrus is simply the package-level exported logger: - package main + package main - import ( - log "github.com/sirupsen/logrus" - ) + import ( + log "github.com/sirupsen/logrus" + ) - func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "number": 1, - "size": 10, - }).Info("A walrus appears") - } + func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "number": 1, + "size": 10, + }).Info("A walrus appears") + } Output: - time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 + + time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 For a full guide visit https://github.com/sirupsen/logrus */ diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index 71d796d0b..82de41f9f 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -4,9 +4,11 @@ import ( "bytes" "context" "fmt" + "maps" "os" "reflect" "runtime" + "strconv" "strings" "sync" "time" @@ -17,8 +19,10 @@ var ( // qualified package name, cached at first use logrusPackage string - // Positions in the call stack when tracing to report the calling method - minimumCallerDepth int + // Positions in the call stack when tracing to report the calling method. + // + // Start at the bottom of the stack before the package-name cache is primed. + minimumCallerDepth = 1 // Used for caller information initialisation callerInitOnce sync.Once @@ -29,68 +33,116 @@ const ( knownLogrusFrames int = 4 ) -func init() { - // start at the bottom of the stack before the package-name cache is primed - minimumCallerDepth = 1 -} - // ErrorKey defines the key when adding errors using [WithError], [Logger.WithError]. var ErrorKey = "error" -// Entry is the final or intermediate Logrus logging entry. It contains all -// the fields passed with WithField{,s}. It's finally logged when Trace, Debug, -// Info, Warn, Error, Fatal or Panic is called on it. These objects can be -// reused and passed around as much as you wish to avoid field duplication. +// Entry represents a single log event. It may be either an intermediate +// entry (created via WithField(s), WithContext, etc.) or a final entry +// that is emitted when one of the level methods (Trace, Debug, Info, +// Warn, Error, Fatal, Panic) is called. // -//nolint:recvcheck // the methods of "Entry" use pointer receiver and non-pointer receiver. +// An Entry always belongs to a Logger. A nil Logger is invalid and will +// cause a panic when the entry is logged. Use [NewEntry] or Logger methods +// to construct entries. +// +// Entries are safe to reuse for adding fields and may be passed around +// to avoid field duplication. Each log operation operates on a copy +// of the Entry’s data to avoid mutation during formatting. +// +//nolint:recvcheck // Entry methods intentionally use both pointer and value receivers. type Entry struct { + // Logger is the Logger that owns this entry and is responsible for + // formatting, hooks, and output. It must not be nil. An Entry without + // a Logger is invalid and will panic when logged. Logger *Logger - // Contains all the fields set by the user. + // Data contains all user-defined fields attached to this entry. Data Fields - // Time at which the log entry was created + // Time is the timestamp for the log event. If zero when the entry is + // logged, it defaults to the current time. Time time.Time - // Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic - // This field will be set on entry firing and the value will be equal to the one in Logger struct field. + // Level is the severity of the log entry. It is set when the entry + // is fired and reflects the level used for that log call. Level Level - // Calling method, with package name + // Caller contains the calling method information. + // + // When [Logger.ReportCaller] is enabled, Caller is populated automatically at + // log time if it is nil. Hooks and formatters may inspect Caller. + // + // Applications generally should not modify Caller unless they intentionally + // want to provide custom caller information. Caller *runtime.Frame - // Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic + // Message is the log message supplied to one of the logging methods + // (Trace, Debug, Info, Warn, Error, Fatal, or Panic). It is set when + // the entry is logged. Message string - // When formatter is called in entry.log(), a Buffer may be set to entry + // Buffer is a reusable buffer provided to the formatter. It is set + // before formatting in the normal log path; when nil, formatters + // allocate their own. Buffer *bytes.Buffer - // Contains the context set by the user. Useful for hook processing etc. + // Context carries user-provided context for hooks and formatters. Context context.Context - // err may contain a field formatting error + // err contains internal field-formatting errors. err string } +// NewEntry creates a new [Entry] associated with the provided Logger. +// The logger must not be nil. Passing a nil logger results in a +// panic when a logging method (e.g., [Entry.Info], [Entry.Error], etc.) +// is called. func NewEntry(logger *Logger) *Entry { return &Entry{ Logger: logger, - // Default is three fields, plus one optional. Give a little extra room. - Data: make(Fields, 6), + // Reserve default predefined fields and a little extra room. + Data: make(Fields, defaultFields+3), } } +// Dup creates a copy of the entry for further modification. +// +// Data is cloned to avoid mutating the original entry. Other fields +// (Logger, Time, Context, etc.) are copied by value. func (entry *Entry) Dup() *Entry { - data := make(Fields, len(entry.Data)) - for k, v := range entry.Data { - data[k] = v + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + return dup +} + +// dup copies the entry fields shared by derived entries except Data, which +// callers must copy or initialize as appropriate for their use. +func (entry *Entry) dup() *Entry { + return &Entry{ + Logger: entry.Logger, + Time: entry.Time, + Caller: entry.Caller, + Context: entry.Context, + err: entry.err, } - return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err} } // Bytes returns the bytes representation of this entry from the formatter. func (entry *Entry) Bytes() ([]byte, error) { - return entry.Logger.Formatter.Format(entry) + // Snapshot the formatter under the lock to protect against concurrent + // SetFormatter calls, then release the lock before formatting. + // This avoids a data race and prevents a deadlock if Format() triggers + // reentrant logging (e.g., a field's MarshalJSON calls logrus). + // + // See: + // + // - https://github.com/sirupsen/logrus/issues/1440 + // - https://github.com/sirupsen/logrus/issues/1448 + entry.Logger.mu.Lock() + formatter := entry.Logger.Formatter + entry.Logger.mu.Unlock() + + return formatter.Format(entry) } // String returns the string representation from the reader and ultimately the @@ -112,58 +164,61 @@ func (entry *Entry) WithError(err error) *Entry { // WithContext adds a context to the Entry. func (entry *Entry) WithContext(ctx context.Context) *Entry { - dataCopy := make(Fields, len(entry.Data)) - for k, v := range entry.Data { - dataCopy[k] = v - } - return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx} + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + dup.Context = ctx + return dup } // WithField adds a single field to the Entry. -func (entry *Entry) WithField(key string, value interface{}) *Entry { - return entry.WithFields(Fields{key: value}) +func (entry *Entry) WithField(key string, value any) *Entry { + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + dup.addField(key, value) + return dup } // WithFields adds a map of fields to the Entry. func (entry *Entry) WithFields(fields Fields) *Entry { - data := make(Fields, len(entry.Data)+len(fields)) - for k, v := range entry.Data { - data[k] = v + dup := entry.dup() + dup.Data = make(Fields, len(entry.Data)+len(fields)) + maps.Copy(dup.Data, entry.Data) + + for key, value := range fields { + dup.addField(key, value) } - fieldErr := entry.err - for k, v := range fields { - isErrField := false - if t := reflect.TypeOf(v); t != nil { - switch { - case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func: - isErrField = true - } - } - if isErrField { - tmp := fmt.Sprintf("can not add field %q", k) - if fieldErr != "" { - fieldErr = entry.err + ", " + tmp - } else { - fieldErr = tmp - } - } else { - data[k] = v - } - } - return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context} + return dup } // WithTime overrides the time of the Entry. func (entry *Entry) WithTime(t time.Time) *Entry { - dataCopy := make(Fields, len(entry.Data)) - for k, v := range entry.Data { - dataCopy[k] = v + dup := entry.dup() + dup.Data = maps.Clone(entry.Data) + dup.Time = t + return dup +} + +func (entry *Entry) addField(key string, value any) { + if _, ok := value.(error); !ok { + t := reflect.TypeOf(value) + if t != nil && (t.Kind() == reflect.Func || t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Func) { + if entry.err != "" { + entry.err += ", skipping unsupported field " + strconv.Quote(key) + } else { + entry.err = "skipping unsupported field " + strconv.Quote(key) + } + return + } } - return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context} + + if entry.Data == nil { + entry.Data = make(Fields, 1) + } + entry.Data[key] = value } // getPackageName reduces a fully qualified function name to the package name -// There really ought to be to be a better way... +// There really ought to be a better way... func getPackageName(f string) string { for { lastPeriod := strings.LastIndex(f, ".") @@ -186,7 +241,7 @@ func getCaller() *runtime.Frame { _ = runtime.Callers(0, pcs) // dynamic get the package name and the minimum caller depth - for i := 0; i < maximumCallerDepth; i++ { + for i := range maximumCallerDepth { funcName := runtime.FuncForPC(pcs[i]).Name() if strings.Contains(funcName, "getCaller") { logrusPackage = getPackageName(funcName) @@ -215,16 +270,47 @@ func getCaller() *runtime.Frame { return nil } -func (entry Entry) HasCaller() (has bool) { - return entry.Logger != nil && - entry.Logger.ReportCaller && - entry.Caller != nil +// HasCaller reports whether this Entry contains caller information. +// +// Caller may be set explicitly, or populated at log time when +// [Logger.ReportCaller] is enabled. +// +// Deprecated: use [Entry.Caller] != nil instead. +// +//go:fix inline +func (entry Entry) HasCaller() bool { + return entry.Caller != nil } -func (entry *Entry) log(level Level, msg string) { - var buffer *bytes.Buffer +func (entry *Entry) logArgs(level Level, panicAfter bool, args ...any) { + entry.log(level, panicAfter, sprint(args...)) +} - newEntry := entry.Dup() +func (entry *Entry) logf(level Level, panicAfter bool, format string, args ...any) { + entry.log(level, panicAfter, fmt.Sprintf(format, args...)) +} + +// logln uses Sprintln for multiple arguments to preserve Println-style +// spacing between args, then trims the trailing newline. +func (entry *Entry) logln(level Level, panicAfter bool, args ...any) { + if len(args) <= 1 { + entry.log(level, panicAfter, sprint(args...)) + return + } + msg := fmt.Sprintln(args...) + msg = msg[:len(msg)-1] // Trim the newline added by Sprintln; logging adds its own. + entry.log(level, panicAfter, msg) +} + +// log writes msg at level. If panicAfter is true, it panics with the fully +// populated entry after hooks and output have completed. +// +// The explicit flag keeps panic behavior limited to Panic, Panicf, and +// Panicln while avoiding a return value used only as the panic value. +// See #1283 and commits f96066e and 5f8c666. +func (entry *Entry) log(level Level, panicAfter bool, msg string) { + newEntry := entry.dup() + newEntry.Data = maps.Clone(entry.Data) if newEntry.Time.IsZero() { newEntry.Time = time.Now() @@ -233,17 +319,24 @@ func (entry *Entry) log(level Level, msg string) { newEntry.Level = level newEntry.Message = msg - newEntry.Logger.mu.Lock() - reportCaller := newEntry.Logger.ReportCaller + logger := newEntry.Logger + logger.mu.Lock() + reportCaller := logger.ReportCaller bufPool := newEntry.getBufferPool() - newEntry.Logger.mu.Unlock() + logger.mu.Unlock() - if reportCaller { + // Preserve explicitly set caller information. + if reportCaller && newEntry.Caller == nil { newEntry.Caller = getCaller() } - newEntry.fireHooks() - buffer = bufPool.Get() + // Select hooks based on the level for this log call. Hooks receive the + // Entry and may mutate it, but that does not affect which hooks are + // fired for this event. + hooks := logger.hooksForLevel(level) + newEntry.fireHooks(hooks) + + buffer := bufPool.Get() defer func() { newEntry.Buffer = nil buffer.Reset() @@ -251,15 +344,12 @@ func (entry *Entry) log(level Level, msg string) { }() buffer.Reset() newEntry.Buffer = buffer - newEntry.write() - newEntry.Buffer = nil - // To avoid Entry#log() returning a value that only would make sense for - // panic() to use in Entry#Panic(), we avoid the allocation by checking - // directly here. - if level <= PanicLevel { + // Panic here so the panic value contains the fully populated entry without + // requiring log to return it to the caller. + if panicAfter { panic(newEntry) } } @@ -271,175 +361,207 @@ func (entry *Entry) getBufferPool() (pool BufferPool) { return bufferPool } -func (entry *Entry) fireHooks() { - var tmpHooks LevelHooks - entry.Logger.mu.Lock() - tmpHooks = make(LevelHooks, len(entry.Logger.Hooks)) - for k, v := range entry.Logger.Hooks { - tmpHooks[k] = v - } - entry.Logger.mu.Unlock() - - err := tmpHooks.Fire(entry.Level, entry) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) +func (entry *Entry) fireHooks(hooks []Hook) { + for _, hook := range hooks { + if err := hook.Fire(entry); err != nil { + _, _ = fmt.Fprintln(os.Stderr, "Failed to fire hook:", err) + return + } } } func (entry *Entry) write() { + // Snapshot the formatter under the lock to protect against concurrent + // SetFormatter calls, then release the lock before formatting. + // This avoids a deadlock when Format() triggers reentrant logging (e.g., + // a field's MarshalJSON calls logrus). See #1448, #1440. entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() - serialized, err := entry.Logger.Formatter.Format(entry) + formatter := entry.Logger.Formatter + entry.Logger.mu.Unlock() + + serialized, err := formatter.Format(entry) if err != nil { - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + _, _ = fmt.Fprintln(os.Stderr, "Failed to format entry:", err) return } + + // Re-acquire the lock to serialize writes to the underlying io.Writer. + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() if _, err := entry.Logger.Out.Write(serialized); err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + _, _ = fmt.Fprintln(os.Stderr, "Failed to write to log:", err) } } -// Log will log a message at the level given as parameter. -// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. -// For this behaviour Entry.Panic or Entry.Fatal should be used instead. -func (entry *Entry) Log(level Level, args ...interface{}) { +// Log logs a message at the specified level. +// +// Using Log with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Log treats the level as logging severity only; +// use [Entry.Panic] or [Entry.Fatal] when those side effects are desired. +func (entry *Entry) Log(level Level, args ...any) { + const panicAfter = false if entry.Logger.IsLevelEnabled(level) { - entry.log(level, fmt.Sprint(args...)) + entry.logArgs(level, panicAfter, args...) } } -func (entry *Entry) Trace(args ...interface{}) { +func (entry *Entry) Trace(args ...any) { entry.Log(TraceLevel, args...) } -func (entry *Entry) Debug(args ...interface{}) { +func (entry *Entry) Debug(args ...any) { entry.Log(DebugLevel, args...) } -func (entry *Entry) Print(args ...interface{}) { +func (entry *Entry) Print(args ...any) { entry.Info(args...) } -func (entry *Entry) Info(args ...interface{}) { +func (entry *Entry) Info(args ...any) { entry.Log(InfoLevel, args...) } -func (entry *Entry) Warn(args ...interface{}) { +func (entry *Entry) Warn(args ...any) { entry.Log(WarnLevel, args...) } -func (entry *Entry) Warning(args ...interface{}) { +func (entry *Entry) Warning(args ...any) { entry.Warn(args...) } -func (entry *Entry) Error(args ...interface{}) { +func (entry *Entry) Error(args ...any) { entry.Log(ErrorLevel, args...) } -func (entry *Entry) Fatal(args ...interface{}) { +func (entry *Entry) Fatal(args ...any) { entry.Log(FatalLevel, args...) entry.Logger.Exit(1) } -func (entry *Entry) Panic(args ...interface{}) { - entry.Log(PanicLevel, args...) +func (entry *Entry) Panic(args ...any) { + const panicAfter = true + if entry.Logger.IsLevelEnabled(PanicLevel) { + entry.logArgs(PanicLevel, panicAfter, args...) + } } // Entry Printf family functions -func (entry *Entry) Logf(level Level, format string, args ...interface{}) { +// Logf logs a formatted message at the specified level. +// +// Using Logf with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logf treats the level as logging severity only; +// use [Entry.Panicf] or [Entry.Fatalf] when those side effects are desired. +func (entry *Entry) Logf(level Level, format string, args ...any) { + const panicAfter = false if entry.Logger.IsLevelEnabled(level) { - entry.Log(level, fmt.Sprintf(format, args...)) + entry.logf(level, panicAfter, format, args...) } } -func (entry *Entry) Tracef(format string, args ...interface{}) { +func (entry *Entry) Tracef(format string, args ...any) { entry.Logf(TraceLevel, format, args...) } -func (entry *Entry) Debugf(format string, args ...interface{}) { +func (entry *Entry) Debugf(format string, args ...any) { entry.Logf(DebugLevel, format, args...) } -func (entry *Entry) Infof(format string, args ...interface{}) { +func (entry *Entry) Infof(format string, args ...any) { entry.Logf(InfoLevel, format, args...) } -func (entry *Entry) Printf(format string, args ...interface{}) { +func (entry *Entry) Printf(format string, args ...any) { entry.Infof(format, args...) } -func (entry *Entry) Warnf(format string, args ...interface{}) { +func (entry *Entry) Warnf(format string, args ...any) { entry.Logf(WarnLevel, format, args...) } -func (entry *Entry) Warningf(format string, args ...interface{}) { +func (entry *Entry) Warningf(format string, args ...any) { entry.Warnf(format, args...) } -func (entry *Entry) Errorf(format string, args ...interface{}) { +func (entry *Entry) Errorf(format string, args ...any) { entry.Logf(ErrorLevel, format, args...) } -func (entry *Entry) Fatalf(format string, args ...interface{}) { +func (entry *Entry) Fatalf(format string, args ...any) { entry.Logf(FatalLevel, format, args...) entry.Logger.Exit(1) } -func (entry *Entry) Panicf(format string, args ...interface{}) { - entry.Logf(PanicLevel, format, args...) +func (entry *Entry) Panicf(format string, args ...any) { + const panicAfter = true + if entry.Logger.IsLevelEnabled(PanicLevel) { + entry.logf(PanicLevel, panicAfter, format, args...) + } } // Entry Println family functions -func (entry *Entry) Logln(level Level, args ...interface{}) { +// Logln logs a message at the specified level with Println-style spacing. +// +// Using Logln with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logln treats the level as logging severity only; +// use [Entry.Panicln] or [Entry.Fatalln] when those side effects are desired. +func (entry *Entry) Logln(level Level, args ...any) { + const panicAfter = false if entry.Logger.IsLevelEnabled(level) { - entry.Log(level, entry.sprintlnn(args...)) + entry.logln(level, panicAfter, args...) } } -func (entry *Entry) Traceln(args ...interface{}) { +func (entry *Entry) Traceln(args ...any) { entry.Logln(TraceLevel, args...) } -func (entry *Entry) Debugln(args ...interface{}) { +func (entry *Entry) Debugln(args ...any) { entry.Logln(DebugLevel, args...) } -func (entry *Entry) Infoln(args ...interface{}) { +func (entry *Entry) Infoln(args ...any) { entry.Logln(InfoLevel, args...) } -func (entry *Entry) Println(args ...interface{}) { +func (entry *Entry) Println(args ...any) { entry.Infoln(args...) } -func (entry *Entry) Warnln(args ...interface{}) { +func (entry *Entry) Warnln(args ...any) { entry.Logln(WarnLevel, args...) } -func (entry *Entry) Warningln(args ...interface{}) { +func (entry *Entry) Warningln(args ...any) { entry.Warnln(args...) } -func (entry *Entry) Errorln(args ...interface{}) { +func (entry *Entry) Errorln(args ...any) { entry.Logln(ErrorLevel, args...) } -func (entry *Entry) Fatalln(args ...interface{}) { +func (entry *Entry) Fatalln(args ...any) { entry.Logln(FatalLevel, args...) entry.Logger.Exit(1) } -func (entry *Entry) Panicln(args ...interface{}) { - entry.Logln(PanicLevel, args...) +func (entry *Entry) Panicln(args ...any) { + const panicAfter = true + if entry.Logger.IsLevelEnabled(PanicLevel) { + entry.logln(PanicLevel, panicAfter, args...) + } } -// sprintlnn => Sprint no newline. This is to get the behavior of how -// fmt.Sprintln where spaces are always added between operands, regardless of -// their type. Instead of vendoring the Sprintln implementation to spare a -// string allocation, we do the simplest thing. -func (entry *Entry) sprintlnn(args ...interface{}) string { - msg := fmt.Sprintln(args...) - return msg[:len(msg)-1] +// sprint is fmt.Sprint with fast paths for zero or one string argument. +func sprint(args ...any) string { + switch len(args) { + case 0: + return "" + case 1: + if msg, ok := args[0].(string); ok { + return msg + } + } + return fmt.Sprint(args...) } diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go index 017c30ce6..8b261c124 100644 --- a/vendor/github.com/sirupsen/logrus/exported.go +++ b/vendor/github.com/sirupsen/logrus/exported.go @@ -6,11 +6,12 @@ import ( "time" ) -var ( - // std is the name of the standard logger in stdlib `log` - std = New() -) +// std is the package-level standard logger, similar to the default logger +// in the stdlib [log] package. +var std = New() +// StandardLogger returns the package-level standard logger used by +// the top-level logging functions. func StandardLogger() *Logger { return std } @@ -41,7 +42,7 @@ func GetLevel() Level { return std.GetLevel() } -// IsLevelEnabled checks if the log level of the standard logger is greater than the level param +// IsLevelEnabled checks if logging for the given level is enabled for the standard logger. func IsLevelEnabled(level Level) bool { return std.IsLevelEnabled(level) } @@ -51,9 +52,10 @@ func AddHook(hook Hook) { std.AddHook(hook) } -// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +// WithError creates an entry from the standard logger and adds an error to it, +// using the value defined in [ErrorKey] as key. func WithError(err error) *Entry { - return std.WithField(ErrorKey, err) + return std.WithError(err) } // WithContext creates an entry from the standard logger and adds a context to it. @@ -61,210 +63,203 @@ func WithContext(ctx context.Context) *Entry { return std.WithContext(ctx) } -// WithField creates an entry from the standard logger and adds a field to -// it. If you want multiple fields, use `WithFields`. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. -func WithField(key string, value interface{}) *Entry { +// WithField creates an entry from the standard logger and adds a single field. +// For multiple fields, prefer [WithFields] over chaining WithField calls. +func WithField(key string, value any) *Entry { return std.WithField(key, value) } -// WithFields creates an entry from the standard logger and adds multiple -// fields to it. This is simply a helper for `WithField`, invoking it -// once for each field. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. +// WithFields creates an entry from the standard logger and adds the fields to it. func WithFields(fields Fields) *Entry { return std.WithFields(fields) } -// WithTime creates an entry from the standard logger and overrides the time of -// logs generated with it. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. +// WithTime creates an entry from the standard logger and overrides the time +// used for logs generated with it. func WithTime(t time.Time) *Entry { return std.WithTime(t) } -// Trace logs a message at level Trace on the standard logger. -func Trace(args ...interface{}) { +// Trace logs a message at level [TraceLevel] on the standard logger. +func Trace(args ...any) { std.Trace(args...) } -// Debug logs a message at level Debug on the standard logger. -func Debug(args ...interface{}) { +// Debug logs a message at level [DebugLevel] on the standard logger. +func Debug(args ...any) { std.Debug(args...) } -// Print logs a message at level Info on the standard logger. -func Print(args ...interface{}) { +// Print logs a message at level [InfoLevel] on the standard logger. +func Print(args ...any) { std.Print(args...) } -// Info logs a message at level Info on the standard logger. -func Info(args ...interface{}) { +// Info logs a message at level [InfoLevel] on the standard logger. +func Info(args ...any) { std.Info(args...) } -// Warn logs a message at level Warn on the standard logger. -func Warn(args ...interface{}) { +// Warn logs a message at level [WarnLevel] on the standard logger. +func Warn(args ...any) { std.Warn(args...) } -// Warning logs a message at level Warn on the standard logger. -func Warning(args ...interface{}) { +// Warning logs a message at level [WarnLevel] on the standard logger. +func Warning(args ...any) { std.Warning(args...) } -// Error logs a message at level Error on the standard logger. -func Error(args ...interface{}) { +// Error logs a message at level [ErrorLevel] on the standard logger. +func Error(args ...any) { std.Error(args...) } -// Panic logs a message at level Panic on the standard logger. -func Panic(args ...interface{}) { +// Panic logs a message at level [PanicLevel] on the standard logger. +func Panic(args ...any) { std.Panic(args...) } -// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1. -func Fatal(args ...interface{}) { +// Fatal logs a message at level [FatalLevel] on the standard logger, +// then exits the process with status 1. +func Fatal(args ...any) { std.Fatal(args...) } -// TraceFn logs a message from a func at level Trace on the standard logger. +// TraceFn logs a message from a func at level [TraceLevel] on the standard logger. func TraceFn(fn LogFunction) { std.TraceFn(fn) } -// DebugFn logs a message from a func at level Debug on the standard logger. +// DebugFn logs a message from a func at level [DebugLevel] on the standard logger. func DebugFn(fn LogFunction) { std.DebugFn(fn) } -// PrintFn logs a message from a func at level Info on the standard logger. +// PrintFn logs a message from a func at level [InfoLevel] on the standard logger. func PrintFn(fn LogFunction) { std.PrintFn(fn) } -// InfoFn logs a message from a func at level Info on the standard logger. +// InfoFn logs a message from a func at level [InfoLevel] on the standard logger. func InfoFn(fn LogFunction) { std.InfoFn(fn) } -// WarnFn logs a message from a func at level Warn on the standard logger. +// WarnFn logs a message from a func at level [WarnLevel] on the standard logger. func WarnFn(fn LogFunction) { std.WarnFn(fn) } -// WarningFn logs a message from a func at level Warn on the standard logger. +// WarningFn logs a message from a func at level [WarnLevel] on the standard logger. func WarningFn(fn LogFunction) { std.WarningFn(fn) } -// ErrorFn logs a message from a func at level Error on the standard logger. +// ErrorFn logs a message from a func at level [ErrorLevel] on the standard logger. func ErrorFn(fn LogFunction) { std.ErrorFn(fn) } -// PanicFn logs a message from a func at level Panic on the standard logger. +// PanicFn logs a message from a func at level [PanicLevel] on the standard logger. func PanicFn(fn LogFunction) { std.PanicFn(fn) } -// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1. +// FatalFn logs a message from a func at level [FatalLevel] on the standard logger, +// then exits the process with status 1. func FatalFn(fn LogFunction) { std.FatalFn(fn) } -// Tracef logs a message at level Trace on the standard logger. -func Tracef(format string, args ...interface{}) { +// Tracef logs a message at level [TraceLevel] on the standard logger. +func Tracef(format string, args ...any) { std.Tracef(format, args...) } -// Debugf logs a message at level Debug on the standard logger. -func Debugf(format string, args ...interface{}) { +// Debugf logs a message at level [DebugLevel] on the standard logger. +func Debugf(format string, args ...any) { std.Debugf(format, args...) } -// Printf logs a message at level Info on the standard logger. -func Printf(format string, args ...interface{}) { +// Printf logs a message at level [InfoLevel] on the standard logger. +func Printf(format string, args ...any) { std.Printf(format, args...) } -// Infof logs a message at level Info on the standard logger. -func Infof(format string, args ...interface{}) { +// Infof logs a message at level [InfoLevel] on the standard logger. +func Infof(format string, args ...any) { std.Infof(format, args...) } -// Warnf logs a message at level Warn on the standard logger. -func Warnf(format string, args ...interface{}) { +// Warnf logs a message at level [WarnLevel] on the standard logger. +func Warnf(format string, args ...any) { std.Warnf(format, args...) } -// Warningf logs a message at level Warn on the standard logger. -func Warningf(format string, args ...interface{}) { +// Warningf logs a message at level [WarnLevel] on the standard logger. +func Warningf(format string, args ...any) { std.Warningf(format, args...) } -// Errorf logs a message at level Error on the standard logger. -func Errorf(format string, args ...interface{}) { +// Errorf logs a message at level [ErrorLevel] on the standard logger. +func Errorf(format string, args ...any) { std.Errorf(format, args...) } -// Panicf logs a message at level Panic on the standard logger. -func Panicf(format string, args ...interface{}) { +// Panicf logs a message at level [PanicLevel] on the standard logger. +func Panicf(format string, args ...any) { std.Panicf(format, args...) } -// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1. -func Fatalf(format string, args ...interface{}) { +// Fatalf logs a message at level [FatalLevel] on the standard logger, +// then exits the process with status 1. +func Fatalf(format string, args ...any) { std.Fatalf(format, args...) } -// Traceln logs a message at level Trace on the standard logger. -func Traceln(args ...interface{}) { +// Traceln logs a message at level [TraceLevel] on the standard logger. +func Traceln(args ...any) { std.Traceln(args...) } -// Debugln logs a message at level Debug on the standard logger. -func Debugln(args ...interface{}) { +// Debugln logs a message at level [DebugLevel] on the standard logger. +func Debugln(args ...any) { std.Debugln(args...) } -// Println logs a message at level Info on the standard logger. -func Println(args ...interface{}) { +// Println logs a message at level [InfoLevel] on the standard logger. +func Println(args ...any) { std.Println(args...) } -// Infoln logs a message at level Info on the standard logger. -func Infoln(args ...interface{}) { +// Infoln logs a message at level [InfoLevel] on the standard logger. +func Infoln(args ...any) { std.Infoln(args...) } -// Warnln logs a message at level Warn on the standard logger. -func Warnln(args ...interface{}) { +// Warnln logs a message at level [WarnLevel] on the standard logger. +func Warnln(args ...any) { std.Warnln(args...) } -// Warningln logs a message at level Warn on the standard logger. -func Warningln(args ...interface{}) { +// Warningln logs a message at level [WarnLevel] on the standard logger. +func Warningln(args ...any) { std.Warningln(args...) } -// Errorln logs a message at level Error on the standard logger. -func Errorln(args ...interface{}) { +// Errorln logs a message at level [ErrorLevel] on the standard logger. +func Errorln(args ...any) { std.Errorln(args...) } -// Panicln logs a message at level Panic on the standard logger. -func Panicln(args ...interface{}) { +// Panicln logs a message at level [PanicLevel] on the standard logger. +func Panicln(args ...any) { std.Panicln(args...) } -// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1. -func Fatalln(args ...interface{}) { +// Fatalln logs a message at level [FatalLevel] on the standard logger, +// then exits the process with status 1. +func Fatalln(args ...any) { std.Fatalln(args...) } diff --git a/vendor/github.com/sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go index 408883773..16f2e0e0f 100644 --- a/vendor/github.com/sirupsen/logrus/formatter.go +++ b/vendor/github.com/sirupsen/logrus/formatter.go @@ -2,27 +2,40 @@ package logrus import "time" -// Default key names for the default fields const ( + // defaultTimestampFormat is the layout used to format entry timestamps + // when a formatter has not specified a custom TimestampFormat. + // It follows time.RFC3339 and is applied unless timestamps are disabled. defaultTimestampFormat = time.RFC3339 - FieldKeyMsg = "msg" - FieldKeyLevel = "level" - FieldKeyTime = "time" - FieldKeyLogrusError = "logrus_error" - FieldKeyFunc = "func" - FieldKeyFile = "file" + + // defaultFields is the number of commonly included predefined log entry fields + // (msg, level, time). It is used as a capacity hint when constructing + // intermediate collections during formatting (for example, the fixed key list). + // + // It does not include the optional "logrus_error", "func", or "file" fields. + defaultFields = 3 ) -// The Formatter interface is used to implement a custom Formatter. It takes an -// `Entry`. It exposes all the fields, including the default ones: +// Default key names for the default fields +const ( + FieldKeyMsg = "msg" + FieldKeyLevel = "level" + FieldKeyTime = "time" + FieldKeyLogrusError = "logrus_error" + FieldKeyFunc = "func" + FieldKeyFile = "file" +) + +// Formatter is implemented by types that format log entries. It receives an +// [*Entry], which contains: // -// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. -// * `entry.Data["time"]`. The timestamp. -// * `entry.Data["level"]. The level the entry was logged at. +// - entry.Message: the message passed to logging methods such as [Info], [Warn], [Error] +// - entry.Time: the timestamp +// - entry.Level: the log level // -// Any additional fields added with `WithField` or `WithFields` are also in -// `entry.Data`. Format is expected to return an array of bytes which are then -// logged to `logger.Out`. +// Additional fields added with [WithField] or [WithFields] are available in +// [Entry.Data]. Format should return the formatted log entry as a byte slice, +// which is written to [Logger.Out]. type Formatter interface { Format(*Entry) ([]byte, error) } @@ -30,12 +43,12 @@ type Formatter interface { // This is to not silently overwrite `time`, `msg`, `func` and `level` fields when // dumping it. If this code wasn't there doing: // -// logrus.WithField("level", 1).Info("hello") +// logrus.WithField("level", 1).Info("hello") // // Would just silently drop the user provided level. Instead with this code // it'll logged as: // -// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} +// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} // // It's not exported because it's still using Data in an opinionated way. It's to // avoid code duplication between the two default formatters. diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go index c96dc5636..fac7695e9 100644 --- a/vendor/github.com/sirupsen/logrus/json_formatter.go +++ b/vendor/github.com/sirupsen/logrus/json_formatter.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "runtime" + "strconv" ) type fieldKey string @@ -20,7 +21,13 @@ func (f FieldMap) resolve(key fieldKey) string { return string(key) } -// JSONFormatter formats logs into parsable json +// JSONFormatter formats logs into parsable JSON. +// +// Fields from [Entry.Data] are included in the JSON object together with the +// standard fields derived from the entry. If a field conflicts with a standard +// field, it is prefixed with "fields.". Standard field names can be customized +// through FieldMap. When DataKey is set, fields from [Entry.Data] are nested +// under that key instead. type JSONFormatter struct { // TimestampFormat sets the format used for marshaling timestamps. // The format to use is the same than for time.Format or time.Parse from the standard @@ -61,7 +68,8 @@ type JSONFormatter struct { // Format renders a single log entry func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - data := make(Fields, len(entry.Data)+4) + caller := entry.Caller + data := make(Fields, len(entry.Data)+defaultFields) for k, v := range entry.Data { switch v := v.(type) { case error: @@ -73,13 +81,14 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } } - if f.DataKey != "" { - newData := make(Fields, 4) + if f.DataKey != "" && len(entry.Data) > 0 { + newData := make(Fields, defaultFields+1) newData[f.DataKey] = data data = newData } - prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + hasCaller := caller != nil + prefixFieldClashes(data, f.FieldMap, hasCaller) timestampFormat := f.TimestampFormat if timestampFormat == "" { @@ -94,11 +103,13 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() - if entry.HasCaller() { - funcVal := entry.Caller.Function - fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + if caller != nil { + var funcVal, fileVal string if f.CallerPrettyfier != nil { - funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + funcVal, fileVal = f.CallerPrettyfier(caller) + } else { + funcVal = caller.Function + fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10) } if funcVal != "" { data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal @@ -108,11 +119,9 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } } - var b *bytes.Buffer - if entry.Buffer != nil { - b = entry.Buffer - } else { - b = &bytes.Buffer{} + b := entry.Buffer + if b == nil { + b = new(bytes.Buffer) } encoder := json.NewEncoder(b) diff --git a/vendor/github.com/sirupsen/logrus/level.go b/vendor/github.com/sirupsen/logrus/level.go new file mode 100644 index 000000000..7bd4255d3 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/level.go @@ -0,0 +1,101 @@ +package logrus + +import ( + "strings" + "sync" +) + +const ( + ansiReset = "\x1b[0m" // reset attributes + ansiRed = "\x1b[31m" // red + ansiYellow = "\x1b[33m" // yellow + ansiCyan = "\x1b[36m" // cyan + ansiDimCyan = "\x1b[2;36m" // dim cyan + ansiDimWhite = "\x1b[2;37m" // dim white (light gray) +) + +type lvlPrefix struct { + full string + truncated string + padded string +} + +func colorize(level Level, s string) string { + color := ansiCyan + switch level { + case TraceLevel: + color = ansiDimWhite + case DebugLevel: + color = ansiDimCyan + case WarnLevel: + color = ansiYellow + case ErrorLevel, FatalLevel, PanicLevel: + color = ansiRed + case InfoLevel: + color = ansiCyan + } + return color + s + ansiReset +} + +func formatLevel(level Level, disableTrunc, pad bool, maxLen int) string { + upper := strings.ToUpper(level.String()) + + if pad && maxLen > len(upper) { + upper += strings.Repeat(" ", maxLen-len(upper)) + } + + if !pad && !disableTrunc && len(upper) > 4 { + upper = upper[:4] + } + + return colorize(level, upper) +} + +var levelPrefixOnce = sync.OnceValues(func() (map[Level]lvlPrefix, lvlPrefix) { + var maxLevel Level + maxLen := 0 + for _, lvl := range AllLevels { + if lvl > maxLevel { + maxLevel = lvl + } + if l := len(lvl.String()); l > maxLen { + maxLen = l + } + } + + prefix := make(map[Level]lvlPrefix, len(AllLevels)) + for _, lvl := range AllLevels { + prefix[lvl] = lvlPrefix{ + full: formatLevel(lvl, true, false, maxLen), + truncated: formatLevel(lvl, false, false, maxLen), + padded: formatLevel(lvl, true, true, maxLen), + } + } + + unknownLevel := maxLevel + 1 + unknown := lvlPrefix{ + full: formatLevel(unknownLevel, true, false, maxLen), + truncated: formatLevel(unknownLevel, false, false, maxLen), + padded: formatLevel(unknownLevel, true, true, maxLen), + } + + return prefix, unknown +}) + +func levelPrefix(level Level, disableTrunc, pad bool) string { + prefix, unknown := levelPrefixOnce() + + p, ok := prefix[level] + if !ok { + p = unknown + } + + switch { + case pad: + return p.padded + case !disableTrunc: + return p.truncated + default: + return p.full + } +} diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index f5b8c439e..17a46e6a6 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -12,17 +12,19 @@ import ( // LogFunction For big messages, it can be more efficient to pass a function // and only call it if the log level is actually enables rather than // generating the log message and then checking if the level is enabled -type LogFunction func() []interface{} +type LogFunction func() []any type Logger struct { // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // file, or leave it default which is `os.Stderr`. You can also set this to // something more adventurous, such as logging to Kafka. Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging // levels and log entries. For example, to send errors to an error tracking // service, log to StatsD or dump the core on fatal errors. Hooks LevelHooks + // All log entries pass through the formatter before logged to Out. The // included formatters are `TextFormatter` and `JSONFormatter` for which // TextFormatter is the default. In development (when a TTY is attached) it @@ -38,37 +40,44 @@ type Logger struct { // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be // logged. Level Level + // Used to sync writing to the log. Locking is enabled by Default - mu MutexWrap + mu mutexWrap + // Reusable empty entry entryPool sync.Pool + // Function to exit the application, defaults to `os.Exit()` - ExitFunc exitFunc + ExitFunc func(int) + // The buffer pool used to format the log. If it is nil, the default global // buffer pool will be used. BufferPool BufferPool } -type exitFunc func(int) +// MutexWrap is the mutex implementation used by [Logger]. +// +// Deprecated: MutexWrap is an implementation detail of Logger and should not be used directly. +type MutexWrap = mutexWrap -type MutexWrap struct { +type mutexWrap struct { lock sync.Mutex disabled bool } -func (mw *MutexWrap) Lock() { +func (mw *mutexWrap) Lock() { if !mw.disabled { mw.lock.Lock() } } -func (mw *MutexWrap) Unlock() { +func (mw *mutexWrap) Unlock() { if !mw.disabled { mw.lock.Unlock() } } -func (mw *MutexWrap) Disable() { +func (mw *mutexWrap) Disable() { mw.disabled = true } @@ -104,7 +113,7 @@ func (logger *Logger) newEntry() *Entry { } func (logger *Logger) releaseEntry(entry *Entry) { - entry.Data = map[string]interface{}{} + entry.Data = map[string]any{} logger.entryPool.Put(entry) } @@ -112,7 +121,7 @@ func (logger *Logger) releaseEntry(entry *Entry) { // Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to // this new returned entry. // If you want multiple fields, use `WithFields`. -func (logger *Logger) WithField(key string, value interface{}) *Entry { +func (logger *Logger) WithField(key string, value any) *Entry { entry := logger.newEntry() defer logger.releaseEntry(entry) return entry.WithField(key, value) @@ -148,7 +157,12 @@ func (logger *Logger) WithTime(t time.Time) *Entry { return entry.WithTime(t) } -func (logger *Logger) Logf(level Level, format string, args ...interface{}) { +// Logf logs a formatted message at the specified level. +// +// Using Logf with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logf treats the level as logging severity only; +// use [Logger.Panicf] or [Logger.Fatalf] when those side effects are desired. +func (logger *Logger) Logf(level Level, format string, args ...any) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() entry.Logf(level, format, args...) @@ -156,49 +170,55 @@ func (logger *Logger) Logf(level Level, format string, args ...interface{}) { } } -func (logger *Logger) Tracef(format string, args ...interface{}) { +func (logger *Logger) Tracef(format string, args ...any) { logger.Logf(TraceLevel, format, args...) } -func (logger *Logger) Debugf(format string, args ...interface{}) { +func (logger *Logger) Debugf(format string, args ...any) { logger.Logf(DebugLevel, format, args...) } -func (logger *Logger) Infof(format string, args ...interface{}) { +func (logger *Logger) Infof(format string, args ...any) { logger.Logf(InfoLevel, format, args...) } -func (logger *Logger) Printf(format string, args ...interface{}) { +func (logger *Logger) Printf(format string, args ...any) { entry := logger.newEntry() entry.Printf(format, args...) logger.releaseEntry(entry) } -func (logger *Logger) Warnf(format string, args ...interface{}) { +func (logger *Logger) Warnf(format string, args ...any) { logger.Logf(WarnLevel, format, args...) } -func (logger *Logger) Warningf(format string, args ...interface{}) { +func (logger *Logger) Warningf(format string, args ...any) { logger.Warnf(format, args...) } -func (logger *Logger) Errorf(format string, args ...interface{}) { +func (logger *Logger) Errorf(format string, args ...any) { logger.Logf(ErrorLevel, format, args...) } -func (logger *Logger) Fatalf(format string, args ...interface{}) { +func (logger *Logger) Fatalf(format string, args ...any) { logger.Logf(FatalLevel, format, args...) logger.Exit(1) } -func (logger *Logger) Panicf(format string, args ...interface{}) { - logger.Logf(PanicLevel, format, args...) +func (logger *Logger) Panicf(format string, args ...any) { + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panicf(format, args...) + } } -// Log will log a message at the level given as parameter. -// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. -// For this behaviour Logger.Panic or Logger.Fatal should be used instead. -func (logger *Logger) Log(level Level, args ...interface{}) { +// Log logs a message at the specified level. +// +// Using Log with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Log treats the level as logging severity only; +// use [Logger.Panic] or [Logger.Fatal] when those side effects are desired. +func (logger *Logger) Log(level Level, args ...any) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() entry.Log(level, args...) @@ -206,6 +226,11 @@ func (logger *Logger) Log(level Level, args ...interface{}) { } } +// LogFn logs a message returned by fn at the specified level. +// +// Using LogFn with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. LogFn treats the level as logging severity only; +// use [Logger.PanicFn] or [Logger.FatalFn] when those side effects are desired. func (logger *Logger) LogFn(level Level, fn LogFunction) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() @@ -214,43 +239,47 @@ func (logger *Logger) LogFn(level Level, fn LogFunction) { } } -func (logger *Logger) Trace(args ...interface{}) { +func (logger *Logger) Trace(args ...any) { logger.Log(TraceLevel, args...) } -func (logger *Logger) Debug(args ...interface{}) { +func (logger *Logger) Debug(args ...any) { logger.Log(DebugLevel, args...) } -func (logger *Logger) Info(args ...interface{}) { +func (logger *Logger) Info(args ...any) { logger.Log(InfoLevel, args...) } -func (logger *Logger) Print(args ...interface{}) { +func (logger *Logger) Print(args ...any) { entry := logger.newEntry() entry.Print(args...) logger.releaseEntry(entry) } -func (logger *Logger) Warn(args ...interface{}) { +func (logger *Logger) Warn(args ...any) { logger.Log(WarnLevel, args...) } -func (logger *Logger) Warning(args ...interface{}) { +func (logger *Logger) Warning(args ...any) { logger.Warn(args...) } -func (logger *Logger) Error(args ...interface{}) { +func (logger *Logger) Error(args ...any) { logger.Log(ErrorLevel, args...) } -func (logger *Logger) Fatal(args ...interface{}) { +func (logger *Logger) Fatal(args ...any) { logger.Log(FatalLevel, args...) logger.Exit(1) } -func (logger *Logger) Panic(args ...interface{}) { - logger.Log(PanicLevel, args...) +func (logger *Logger) Panic(args ...any) { + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panic(args...) + } } func (logger *Logger) TraceFn(fn LogFunction) { @@ -289,10 +318,19 @@ func (logger *Logger) FatalFn(fn LogFunction) { } func (logger *Logger) PanicFn(fn LogFunction) { - logger.LogFn(PanicLevel, fn) + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panic(fn()...) + } } -func (logger *Logger) Logln(level Level, args ...interface{}) { +// Logln logs a message at the specified level with Println-style spacing. +// +// Using Logln with [PanicLevel] or [FatalLevel] intentionally does not +// trigger a panic or exit. Logln treats the level as logging severity only; +// use [Logger.Panicln] or [Logger.Fatalln] when those side effects are desired. +func (logger *Logger) Logln(level Level, args ...any) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() entry.Logln(level, args...) @@ -300,43 +338,47 @@ func (logger *Logger) Logln(level Level, args ...interface{}) { } } -func (logger *Logger) Traceln(args ...interface{}) { +func (logger *Logger) Traceln(args ...any) { logger.Logln(TraceLevel, args...) } -func (logger *Logger) Debugln(args ...interface{}) { +func (logger *Logger) Debugln(args ...any) { logger.Logln(DebugLevel, args...) } -func (logger *Logger) Infoln(args ...interface{}) { +func (logger *Logger) Infoln(args ...any) { logger.Logln(InfoLevel, args...) } -func (logger *Logger) Println(args ...interface{}) { +func (logger *Logger) Println(args ...any) { entry := logger.newEntry() entry.Println(args...) logger.releaseEntry(entry) } -func (logger *Logger) Warnln(args ...interface{}) { +func (logger *Logger) Warnln(args ...any) { logger.Logln(WarnLevel, args...) } -func (logger *Logger) Warningln(args ...interface{}) { +func (logger *Logger) Warningln(args ...any) { logger.Warnln(args...) } -func (logger *Logger) Errorln(args ...interface{}) { +func (logger *Logger) Errorln(args ...any) { logger.Logln(ErrorLevel, args...) } -func (logger *Logger) Fatalln(args ...interface{}) { +func (logger *Logger) Fatalln(args ...any) { logger.Logln(FatalLevel, args...) logger.Exit(1) } -func (logger *Logger) Panicln(args ...interface{}) { - logger.Logln(PanicLevel, args...) +func (logger *Logger) Panicln(args ...any) { + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + entry.Panicln(args...) + } } func (logger *Logger) Exit(code int) { @@ -375,7 +417,22 @@ func (logger *Logger) AddHook(hook Hook) { logger.Hooks.Add(hook) } -// IsLevelEnabled checks if the log level of the logger is greater than the level param +// hooksForLevel returns a snapshot of the hooks registered for the given level. +// The returned slice is a shallow copy and may be used without holding logger.mu. +func (logger *Logger) hooksForLevel(level Level) []Hook { + logger.mu.Lock() + hooks := logger.Hooks[level] + if len(hooks) == 0 { + logger.mu.Unlock() + return nil + } + out := make([]Hook, len(hooks)) + copy(out, hooks) + logger.mu.Unlock() + return out +} + +// IsLevelEnabled checks if logging for the given level is enabled. func (logger *Logger) IsLevelEnabled(level Level) bool { return logger.level() >= level } @@ -394,6 +451,7 @@ func (logger *Logger) SetOutput(output io.Writer) { logger.Out = output } +// SetReportCaller sets whether the caller stack frame must be logged. func (logger *Logger) SetReportCaller(reportCaller bool) { logger.mu.Lock() defer logger.mu.Unlock() @@ -403,9 +461,9 @@ func (logger *Logger) SetReportCaller(reportCaller bool) { // ReplaceHooks replaces the logger hooks and returns the old ones func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks { logger.mu.Lock() + defer logger.mu.Unlock() oldHooks := logger.Hooks logger.Hooks = hooks - logger.mu.Unlock() return oldHooks } diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go index 37fc4fef8..d52b4ba73 100644 --- a/vendor/github.com/sirupsen/logrus/logrus.go +++ b/vendor/github.com/sirupsen/logrus/logrus.go @@ -1,13 +1,13 @@ package logrus import ( + "bytes" "fmt" "log" - "strings" ) // Fields type, used to pass to [WithFields]. -type Fields map[string]interface{} +type Fields map[string]any // Level type // @@ -16,39 +16,56 @@ type Level uint32 // Convert the Level to a string. E.g. [PanicLevel] becomes "panic". func (level Level) String() string { - if b, err := level.MarshalText(); err == nil { - return string(b) - } else { + switch level { + case TraceLevel: + return "trace" + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarnLevel: + return "warning" + case ErrorLevel: + return "error" + case FatalLevel: + return "fatal" + case PanicLevel: + return "panic" + default: return "unknown" } } // ParseLevel takes a string level and returns the Logrus log level constant. func ParseLevel(lvl string) (Level, error) { - switch strings.ToLower(lvl) { - case "panic": - return PanicLevel, nil - case "fatal": - return FatalLevel, nil - case "error": - return ErrorLevel, nil - case "warn", "warning": - return WarnLevel, nil - case "info": - return InfoLevel, nil - case "debug": - return DebugLevel, nil - case "trace": - return TraceLevel, nil - } + return parseLevel([]byte(lvl)) +} - var l Level - return l, fmt.Errorf("not a valid logrus Level: %q", lvl) +func parseLevel(b []byte) (Level, error) { + switch { + case bytes.EqualFold(b, []byte("panic")): + return PanicLevel, nil + case bytes.EqualFold(b, []byte("fatal")): + return FatalLevel, nil + case bytes.EqualFold(b, []byte("error")): + return ErrorLevel, nil + case bytes.EqualFold(b, []byte("warn")), + bytes.EqualFold(b, []byte("warning")): + return WarnLevel, nil + case bytes.EqualFold(b, []byte("info")): + return InfoLevel, nil + case bytes.EqualFold(b, []byte("debug")): + return DebugLevel, nil + case bytes.EqualFold(b, []byte("trace")): + return TraceLevel, nil + default: + return 0, fmt.Errorf("not a valid logrus Level: %q", b) + } } // UnmarshalText implements encoding.TextUnmarshaler. func (level *Level) UnmarshalText(text []byte) error { - l, err := ParseLevel(string(text)) + l, err := parseLevel(text) if err != nil { return err } @@ -60,23 +77,11 @@ func (level *Level) UnmarshalText(text []byte) error { func (level Level) MarshalText() ([]byte, error) { switch level { - case TraceLevel: - return []byte("trace"), nil - case DebugLevel: - return []byte("debug"), nil - case InfoLevel: - return []byte("info"), nil - case WarnLevel: - return []byte("warning"), nil - case ErrorLevel: - return []byte("error"), nil - case FatalLevel: - return []byte("fatal"), nil - case PanicLevel: - return []byte("panic"), nil + case TraceLevel, DebugLevel, InfoLevel, WarnLevel, ErrorLevel, FatalLevel, PanicLevel: + return []byte(level.String()), nil + default: + return nil, fmt.Errorf("not a valid logrus level %d", level) } - - return nil, fmt.Errorf("not a valid logrus level %d", level) } // AllLevels exposing all logging levels. @@ -91,7 +96,7 @@ var AllLevels = []Level{ } // These are the different logging levels. You can set the logging level to log -// on your instance of logger, obtained with `logrus.New()`. +// on your instance of logger, obtained with [logrus.New]. const ( // PanicLevel level, highest level of severity. Logs and then calls panic with the // message passed to Debug, Info, ... @@ -113,78 +118,110 @@ const ( TraceLevel ) -// Won't compile if StdLogger can't be realized by a log.Logger +// Compile-time interface assertions. var ( - _ StdLogger = &log.Logger{} - _ StdLogger = &Entry{} - _ StdLogger = &Logger{} + _ StdLogger = (*log.Logger)(nil) + _ StdLogger = (*Entry)(nil) + _ StdLogger = (*Logger)(nil) + + _ FieldLogger = (*Logger)(nil) + _ FieldLogger = (*Entry)(nil) + _ FieldLogger = Ext1FieldLogger(nil) + + _ DebugLogger = (*Logger)(nil) + _ InfoLogger = (*Logger)(nil) + _ WarnLogger = (*Logger)(nil) + _ ErrorLogger = (*Logger)(nil) + _ TraceLogger = (*Logger)(nil) + + _ DebugLogger = (*Entry)(nil) + _ InfoLogger = (*Entry)(nil) + _ WarnLogger = (*Entry)(nil) + _ ErrorLogger = (*Entry)(nil) + _ TraceLogger = (*Entry)(nil) + + _ Ext1FieldLogger = (*Logger)(nil) + _ Ext1FieldLogger = (*Entry)(nil) ) // StdLogger is what your logrus-enabled library should take, that way // it'll accept a stdlib logger ([log.Logger]) and a logrus logger. // There's no standard interface, so this is the closest we get, unfortunately. type StdLogger interface { - Print(...interface{}) - Printf(string, ...interface{}) - Println(...interface{}) + Print(args ...any) + Printf(format string, args ...any) + Println(args ...any) - Fatal(...interface{}) - Fatalf(string, ...interface{}) - Fatalln(...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) + Fatalln(args ...any) - Panic(...interface{}) - Panicf(string, ...interface{}) - Panicln(...interface{}) + Panic(args ...any) + Panicf(format string, args ...any) + Panicln(args ...any) } // FieldLogger extends the [StdLogger] interface, generalizing // the [Entry] and [Logger] types. type FieldLogger interface { - WithField(key string, value interface{}) *Entry + WithField(key string, value any) *Entry WithFields(fields Fields) *Entry WithError(err error) *Entry - Debugf(format string, args ...interface{}) - Infof(format string, args ...interface{}) - Printf(format string, args ...interface{}) - Warnf(format string, args ...interface{}) - Warningf(format string, args ...interface{}) - Errorf(format string, args ...interface{}) - Fatalf(format string, args ...interface{}) - Panicf(format string, args ...interface{}) + StdLogger + DebugLogger + InfoLogger + WarnLogger + ErrorLogger - Debug(args ...interface{}) - Info(args ...interface{}) - Print(args ...interface{}) - Warn(args ...interface{}) - Warning(args ...interface{}) - Error(args ...interface{}) - Fatal(args ...interface{}) - Panic(args ...interface{}) + // Legacy warning aliases. These are kept on FieldLogger for backwards + // compatibility, but are intentionally omitted from [WarnLogger]. - Debugln(args ...interface{}) - Infoln(args ...interface{}) - Println(args ...interface{}) - Warnln(args ...interface{}) - Warningln(args ...interface{}) - Errorln(args ...interface{}) - Fatalln(args ...interface{}) - Panicln(args ...interface{}) - - // IsDebugEnabled() bool - // IsInfoEnabled() bool - // IsWarnEnabled() bool - // IsErrorEnabled() bool - // IsFatalEnabled() bool - // IsPanicEnabled() bool + Warning(args ...any) + Warningf(format string, args ...any) + Warningln(args ...any) } -// Ext1FieldLogger (the first extension to [FieldLogger]) is superfluous, it is -// here for consistency. Do not use. Use [FieldLogger], [Logger] or [Entry] -// instead. +// DebugLogger provides convenience functions to log messages at level [DebugLevel]. +type DebugLogger interface { + Debug(args ...any) + Debugf(format string, args ...any) + Debugln(args ...any) +} + +// InfoLogger provides convenience functions to log messages at level [InfoLevel]. +type InfoLogger interface { + Info(args ...any) + Infof(format string, args ...any) + Infoln(args ...any) +} + +// WarnLogger provides convenience functions to log messages at level [WarnLevel]. +type WarnLogger interface { + Warn(args ...any) + Warnf(format string, args ...any) + Warnln(args ...any) +} + +// ErrorLogger provides convenience functions to log messages at level [ErrorLevel]. +type ErrorLogger interface { + Error(args ...any) + Errorf(format string, args ...any) + Errorln(args ...any) +} + +// TraceLogger provides convenience functions to log messages at level [TraceLevel]. +type TraceLogger interface { + Trace(args ...any) + Tracef(format string, args ...any) + Traceln(args ...any) +} + +// Ext1FieldLogger is FieldLogger extended with Trace-level methods. +// +// New code should prefer the smallest applicable interface, such as +// [FieldLogger] or [TraceLogger], or use [Logger] or [Entry] directly. type Ext1FieldLogger interface { FieldLogger - Tracef(format string, args ...interface{}) - Trace(args ...interface{}) - Traceln(args ...interface{}) + TraceLogger } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go index 2403de981..1c6202b8c 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go @@ -1,11 +1,7 @@ -// +build appengine +//go:build appengine package logrus -import ( - "io" -) - -func checkIfTerminal(w io.Writer) bool { +func checkIfTerminal(_ any) bool { return true } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go index 69956b425..ff9531ac4 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go @@ -1,5 +1,4 @@ -// +build darwin dragonfly freebsd netbsd openbsd hurd -// +build !js +//go:build (darwin || dragonfly || freebsd || netbsd || openbsd || hurd) && !tinygo package logrus diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_js.go b/vendor/github.com/sirupsen/logrus/terminal_check_js.go deleted file mode 100644 index ebdae3ec6..000000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_js.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build js - -package logrus - -func isTerminal(fd int) bool { - return false -} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go index 97af92c68..17ae9f04f 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go @@ -1,11 +1,7 @@ -// +build js nacl plan9 +//go:build js || nacl || plan9 || wasi || wasip1 || tinygo package logrus -import ( - "io" -) - -func checkIfTerminal(w io.Writer) bool { +func checkIfTerminal(_ any) bool { return false } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go index 3293fb3ca..780a42a57 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go @@ -1,4 +1,4 @@ -// +build !appengine,!js,!windows,!nacl,!plan9 +//go:build !appengine && !js && !windows && !nacl && !plan9 && !wasi && !wasip1 && !tinygo package logrus @@ -10,7 +10,11 @@ import ( func checkIfTerminal(w io.Writer) bool { switch v := w.(type) { case *os.File: - return isTerminal(int(v.Fd())) + fd := v.Fd() + if fd > uintptr(^uint(0)>>1) { + return false + } + return isTerminal(int(fd)) default: return false } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go index f6710b3bd..8d9b26fca 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_solaris.go @@ -1,3 +1,5 @@ +//go:build solaris && !tinygo + package logrus import ( diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go index c9aed267a..b161506d3 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go @@ -1,7 +1,4 @@ -//go:build (linux || aix || zos) && !js && !wasi -// +build linux aix zos -// +build !js -// +build !wasi +//go:build (linux || aix || zos) && !tinygo package logrus diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go b/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go deleted file mode 100644 index 2822b212f..000000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build wasi -// +build wasi - -package logrus - -func isTerminal(fd int) bool { - return false -} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go b/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go deleted file mode 100644 index 108a6be12..000000000 --- a/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build wasip1 -// +build wasip1 - -package logrus - -func isTerminal(fd int) bool { - return false -} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go index 2879eb50e..5fd3c4313 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go @@ -1,4 +1,4 @@ -// +build !appengine,!js,windows +//go:build windows && !appengine package logrus diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go index 6dfeb18b1..82c1f3da2 100644 --- a/vendor/github.com/sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -3,30 +3,32 @@ package logrus import ( "bytes" "fmt" + "maps" "os" + "reflect" "runtime" - "sort" + "slices" "strconv" "strings" "sync" "time" - "unicode/utf8" ) -const ( - red = 31 - yellow = 33 - blue = 36 - gray = 37 -) +var baseTimestamp = time.Now() -var baseTimestamp time.Time - -func init() { - baseTimestamp = time.Now() -} - -// TextFormatter formats logs into text +// TextFormatter formats logs into text. +// +// Output is logfmt-like: key=value pairs separated by spaces. Fields from +// [Entry.Data] are included together with the standard fields derived from the +// entry. If a field conflicts with a standard field, it is prefixed with +// "fields.". Standard field names can be customized through FieldMap. +// +// Field keys are written as-is (unquoted and unescaped) in the plain +// (non-colored) format; only field values may be quoted depending on +// DisableQuote, ForceQuote, QuoteEmptyFields, and the value content. +// +// When colors are enabled, ANSI escape sequences may be added for presentation. +// For fully escaped structured output (including safe keys), use JSONFormatter. type TextFormatter struct { // Set to true to bypass checking for a TTY before outputting colors. ForceColors bool @@ -64,7 +66,7 @@ type TextFormatter struct { // be desired. DisableSorting bool - // The keys sorting function, when uninitialized it uses sort.Strings. + // The keys sorting function, when uninitialized it uses slices.Sort. SortingFunc func([]string) // Disables the truncation of the level text to 4 characters. @@ -77,16 +79,22 @@ type TextFormatter struct { // QuoteEmptyFields will wrap empty fields in quotes if true QuoteEmptyFields bool - // Whether the logger's out is to a terminal - isTerminal bool + // Whether the logger's out is to a terminal. Don't use this field + // directly; use TextFormatter.isTerminal instead. + terminal bool // FieldMap allows users to customize the names of keys for default fields. + // Mapped keys are written as-is, so they should be safe for plain-text output. + // // As an example: + // // formatter := &TextFormatter{ - // FieldMap: FieldMap{ - // FieldKeyTime: "@timestamp", - // FieldKeyLevel: "@level", - // FieldKeyMsg: "@message"}} + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message", + // }, + // } FieldMap FieldMap // CallerPrettyfier can be set by the user to modify the content @@ -96,54 +104,78 @@ type TextFormatter struct { CallerPrettyfier func(*runtime.Frame) (function string, file string) terminalInitOnce sync.Once - - // The max length of the level text, generated dynamically on init - levelTextMaxLength int } -func (f *TextFormatter) init(entry *Entry) { - if entry.Logger != nil { - f.isTerminal = checkIfTerminal(entry.Logger.Out) - } - // Get the max length of the level text - for _, level := range AllLevels { - levelTextLength := utf8.RuneCount([]byte(level.String())) - if levelTextLength > f.levelTextMaxLength { - f.levelTextMaxLength = levelTextLength - } +func (f *TextFormatter) isTerminal(entry *Entry) bool { + if entry == nil || entry.Logger == nil { + // Don't run the terminalInitOnce without a logger, otherwise we'd + // cache the default (false) forever even if a logger is attached + // later. + return false } + + f.terminalInitOnce.Do(func() { + entry.Logger.mu.Lock() + out := entry.Logger.Out + entry.Logger.mu.Unlock() + + f.terminal = checkIfTerminal(out) + }) + + return f.terminal } -func (f *TextFormatter) isColored() bool { - isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) - - if f.EnvironmentOverrideColors { - switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); { - case ok && force != "0": - isColored = true - case ok && force == "0", os.Getenv("CLICOLOR") == "0": - isColored = false - } +func (f *TextFormatter) isColored(isTerminal bool) bool { + if f.DisableColors { + return false } - return isColored && !f.DisableColors + colored := f.ForceColors || isTerminal + if !f.EnvironmentOverrideColors { + return colored + } + if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok { + return force != "0" + } + if os.Getenv("CLICOLOR") == "0" { + return false + } + return colored } // Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - data := make(Fields) - for k, v := range entry.Data { - data[k] = v - } - prefixFieldClashes(data, f.FieldMap, entry.HasCaller()) + data := make(Fields, len(entry.Data)) + maps.Copy(data, entry.Data) + isColored := f.isColored(f.isTerminal(entry)) + + caller := entry.Caller + hasCaller := caller != nil + prefixFieldClashes(data, f.FieldMap, hasCaller) keys := make([]string, 0, len(data)) for k := range data { keys = append(keys, k) } - var funcVal, fileVal string + b := entry.Buffer + if b == nil { + b = new(bytes.Buffer) + } - fixedKeys := make([]string, 0, 4+len(data)) + if isColored { + f.printColored(b, entry, keys, data) + } else { + f.printPlain(b, entry, keys, data) + } + + return b.Bytes(), nil +} + +func (f *TextFormatter) printPlain(b *bytes.Buffer, entry *Entry, keys []string, data Fields) { + caller := entry.Caller + hasCaller := caller != nil + + fixedKeys := make([]string, 0, len(keys)+defaultFields) if !f.DisableTimestamp { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime)) } @@ -154,12 +186,14 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { if entry.err != "" { fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError)) } - if entry.HasCaller() { + + var funcVal, fileVal string + if caller != nil { if f.CallerPrettyfier != nil { - funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + funcVal, fileVal = f.CallerPrettyfier(caller) } else { - funcVal = entry.Caller.Function - fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) + funcVal = caller.Function + fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10) } if funcVal != "" { @@ -172,152 +206,108 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { if !f.DisableSorting { if f.SortingFunc == nil { - sort.Strings(keys) + // Default sorting does not sort the "fixed keys"; + // see https://github.com/sirupsen/logrus/commit/73bc94e60c753099e8bae902f81fbd6e7dd95f26 + slices.Sort(keys) fixedKeys = append(fixedKeys, keys...) } else { - if !f.isColored() { - fixedKeys = append(fixedKeys, keys...) - f.SortingFunc(fixedKeys) - } else { - f.SortingFunc(keys) - } + fixedKeys = append(fixedKeys, keys...) + f.SortingFunc(fixedKeys) } } else { fixedKeys = append(fixedKeys, keys...) } - var b *bytes.Buffer - if entry.Buffer != nil { - b = entry.Buffer - } else { - b = &bytes.Buffer{} - } - - f.terminalInitOnce.Do(func() { f.init(entry) }) - - timestampFormat := f.TimestampFormat - if timestampFormat == "" { - timestampFormat = defaultTimestampFormat - } - if f.isColored() { - f.printColored(b, entry, keys, data, timestampFormat) - } else { - - for _, key := range fixedKeys { - var value interface{} - switch { - case key == f.FieldMap.resolve(FieldKeyTime): - value = entry.Time.Format(timestampFormat) - case key == f.FieldMap.resolve(FieldKeyLevel): - value = entry.Level.String() - case key == f.FieldMap.resolve(FieldKeyMsg): - value = entry.Message - case key == f.FieldMap.resolve(FieldKeyLogrusError): - value = entry.err - case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller(): - value = funcVal - case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller(): - value = fileVal - default: - value = data[key] + for _, key := range fixedKeys { + var value any + switch { + case key == f.FieldMap.resolve(FieldKeyTime): + if f.TimestampFormat == "" { + value = entry.Time.Format(defaultTimestampFormat) + } else { + value = entry.Time.Format(f.TimestampFormat) } - f.appendKeyValue(b, key, value) + case key == f.FieldMap.resolve(FieldKeyLevel): + value = entry.Level.String() + case key == f.FieldMap.resolve(FieldKeyMsg): + value = entry.Message + case key == f.FieldMap.resolve(FieldKeyLogrusError): + value = entry.err + case key == f.FieldMap.resolve(FieldKeyFunc) && hasCaller: + value = funcVal + case key == f.FieldMap.resolve(FieldKeyFile) && hasCaller: + value = fileVal + default: + value = data[key] } + f.appendKeyValue(b, key, value) } b.WriteByte('\n') - return b.Bytes(), nil } -func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) { - var levelColor int - switch entry.Level { - case DebugLevel, TraceLevel: - levelColor = gray - case WarnLevel: - levelColor = yellow - case ErrorLevel, FatalLevel, PanicLevel: - levelColor = red - case InfoLevel: - levelColor = blue - default: - levelColor = blue - } - - levelText := strings.ToUpper(entry.Level.String()) - if !f.DisableLevelTruncation && !f.PadLevelText { - levelText = levelText[0:4] - } - if f.PadLevelText { - // Generates the format string used in the next line, for example "%-6s" or "%-7s". - // Based on the max level text length. - formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s" - // Formats the level text by appending spaces up to the max length, for example: - // - "INFO " - // - "WARNING" - levelText = fmt.Sprintf(formatString, levelText) - } - +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields) { // Remove a single newline if it already exists in the message to keep // the behavior of logrus text_formatter the same as the stdlib log package entry.Message = strings.TrimSuffix(entry.Message, "\n") - caller := "" - if entry.HasCaller() { - funcVal := fmt.Sprintf("%s()", entry.Caller.Function) - fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line) - + var callerText string + if caller := entry.Caller; caller != nil { + var funcVal, fileVal string if f.CallerPrettyfier != nil { - funcVal, fileVal = f.CallerPrettyfier(entry.Caller) + funcVal, fileVal = f.CallerPrettyfier(caller) + } else { + if caller.Function != "" { + funcVal = caller.Function + "()" + } + fileVal = caller.File + ":" + strconv.FormatInt(int64(caller.Line), 10) } if fileVal == "" { - caller = funcVal + callerText = funcVal } else if funcVal == "" { - caller = fileVal + callerText = fileVal } else { - caller = fileVal + " " + funcVal + callerText = fileVal + " " + funcVal } } + levelText := levelPrefix(entry.Level, f.DisableLevelTruncation, f.PadLevelText) switch { case f.DisableTimestamp: - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message) + _, _ = fmt.Fprintf(b, "%s%s %-44s ", levelText, callerText, entry.Message) case !f.FullTimestamp: - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message) + _, _ = fmt.Fprintf(b, "%s[%04d]%s %-44s ", levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), callerText, entry.Message) default: - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = defaultTimestampFormat + } + _, _ = fmt.Fprintf(b, "%s[%s]%s %-44s ", levelText, entry.Time.Format(timestampFormat), callerText, entry.Message) } - for _, k := range keys { - v := data[k] - fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) - f.appendValue(b, v) - } -} -func (f *TextFormatter) needsQuoting(text string) bool { - if f.ForceQuote { - return true - } - if f.QuoteEmptyFields && len(text) == 0 { - return true - } - if f.DisableQuote { - return false - } - for _, ch := range text { - //nolint:staticcheck // QF1001: could apply De Morgan's law - if !((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') { - return true + if !f.DisableSorting { + if f.SortingFunc == nil { + slices.Sort(keys) + } else { + f.SortingFunc(keys) } } - return false + + // Keys use the same color as the level-prefix. + for _, k := range keys { + b.WriteByte(' ') + b.WriteString(colorize(entry.Level, k)) + b.WriteByte('=') + f.appendValue(b, data[k]) + } + + b.WriteByte('\n') } -func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { +// appendKeyValue writes key=value. Keys are written verbatim (unquoted/unescaped); +// values are subject to quoting/escaping. +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value any) { if b.Len() > 0 { b.WriteByte(' ') } @@ -326,15 +316,168 @@ func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interf f.appendValue(b, value) } -func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { - stringVal, ok := value.(string) - if !ok { - stringVal = fmt.Sprint(value) +func (f *TextFormatter) appendValue(b *bytes.Buffer, value any) { + // Fast paths. + switch v := value.(type) { + case string: + f.appendString(b, v) + return + case []byte: + f.appendBytes(b, v) + return + case bool: + var raw [8]byte + f.appendBytes(b, strconv.AppendBool(raw[:0], v)) + return + case error: + f.appendError(b, v) + return + case fmt.Stringer: + f.appendStringer(b, v) + return } - if !f.needsQuoting(stringVal) { - b.WriteString(stringVal) - } else { - fmt.Fprintf(b, "%q", stringVal) + // Handle common primitives. + var raw [64]byte + var num []byte + + switch v := value.(type) { + case int: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int8: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int16: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int32: + num = strconv.AppendInt(raw[:0], int64(v), 10) + case int64: + num = strconv.AppendInt(raw[:0], v, 10) + + case uint: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint8: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint16: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint32: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + case uint64: + num = strconv.AppendUint(raw[:0], v, 10) + case uintptr: + num = strconv.AppendUint(raw[:0], uint64(v), 10) + + case float32: + num = strconv.AppendFloat(raw[:0], float64(v), 'g', -1, 32) + case float64: + num = strconv.AppendFloat(raw[:0], v, 'g', -1, 64) + + default: + f.appendString(b, fmt.Sprint(value)) + return + } + + f.appendNumeric(b, num) +} + +func (f *TextFormatter) appendString(b *bytes.Buffer, s string) { + quote := f.ForceQuote || (f.QuoteEmptyFields && len(s) == 0) || (!f.DisableQuote && needsQuoting(s)) + if !quote { + b.WriteString(s) + return + } + if len(s) == 0 { + b.WriteString(`""`) + return + } + + var tmp [128]byte + b.Write(strconv.AppendQuote(tmp[:0], s)) +} + +func (f *TextFormatter) appendBytes(b *bytes.Buffer, bs []byte) { + quote := f.ForceQuote || (f.QuoteEmptyFields && len(bs) == 0) || (!f.DisableQuote && needsQuotingBytes(bs)) + if !quote { + b.Write(bs) + return + } + if len(bs) == 0 { + b.WriteString(`""`) + return + } + + var tmp [128]byte + b.Write(strconv.AppendQuote(tmp[:0], string(bs))) +} + +func (f *TextFormatter) appendNumeric(b *bytes.Buffer, out []byte) { + if f.ForceQuote { + var tmp [128]byte + b.Write(strconv.AppendQuote(tmp[:0], string(out))) + return + } + b.Write(out) +} + +func (f *TextFormatter) appendError(b *bytes.Buffer, v error) { + defer f.recoverValue(b, v, "Error") + + f.appendString(b, v.Error()) +} + +func (f *TextFormatter) appendStringer(b *bytes.Buffer, v fmt.Stringer) { + defer f.recoverValue(b, v, "String") + + f.appendString(b, v.String()) +} + +func (f *TextFormatter) recoverValue(b *bytes.Buffer, v any, method string) { + if r := recover(); r != nil { + rv := reflect.ValueOf(v) + if rv.Kind() == reflect.Pointer && rv.IsNil() { + f.appendString(b, "") + } else { + f.appendString(b, fmt.Sprintf("%%!v(PANIC=%s method: %v)", method, r)) + } + } +} + +// needsQuoting returns true if the string contains any byte that +// requires quoting. It returns false when every byte is "safe" according +// to isSafeByte. +func needsQuoting(s string) bool { + // use an index loop (avoid rune decoding). + for i := range len(s) { + c := s[i] + if !isSafeByte(c) { + return true + } + } + return false +} + +// needsQuotingBytes returns true if the byte slice contains any byte that +// requires quoting. It returns false when every byte is "safe" according +// to isSafeByte. +func needsQuotingBytes(bs []byte) bool { + for _, c := range bs { + if !isSafeByte(c) { + return true + } + } + return false +} + +// isSafeByte returns true if the byte is allowed unquoted (ASCII and in the allowlist). +// It purposely uses byte arithmetic (no runes) for performance. +func isSafeByte(ch byte) bool { + ok := ch < 0x80 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) + if ok { + return true + } + switch ch { + case '-', '.', '_', '/', '@', '^', '+': + return true + default: + return false } } diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go index 074fd4b8b..30e34cda7 100644 --- a/vendor/github.com/sirupsen/logrus/writer.go +++ b/vendor/github.com/sirupsen/logrus/writer.go @@ -30,7 +30,7 @@ func (entry *Entry) Writer() *io.PipeWriter { func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { reader, writer := io.Pipe() - var printFunc func(args ...interface{}) + printFunc := entry.Print // Determine which log function to use based on the specified log level switch level { @@ -48,8 +48,6 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { printFunc = entry.Fatal case PanicLevel: printFunc = entry.Panic - default: - printFunc = entry.Print } // Start a new goroutine to scan the input and write it to the logger using the specified print function. @@ -63,7 +61,7 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { } // writerScanner scans the input from the reader and writes it to the logger -func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { +func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...any)) { scanner := bufio.NewScanner(reader) // Set the buffer size to the maximum token size to avoid buffer overflows diff --git a/vendor/go.opencensus.io/.gitignore b/vendor/go.opencensus.io/.gitignore deleted file mode 100644 index 74a6db472..000000000 --- a/vendor/go.opencensus.io/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.idea/ - -# go.opencensus.io/exporter/aws -/exporter/aws/ - -# Exclude vendor, use dep ensure after checkout: -/vendor/github.com/ -/vendor/golang.org/ -/vendor/google.golang.org/ diff --git a/vendor/go.opencensus.io/AUTHORS b/vendor/go.opencensus.io/AUTHORS deleted file mode 100644 index e491a9e7f..000000000 --- a/vendor/go.opencensus.io/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Google Inc. diff --git a/vendor/go.opencensus.io/CONTRIBUTING.md b/vendor/go.opencensus.io/CONTRIBUTING.md deleted file mode 100644 index 1ba3962c8..000000000 --- a/vendor/go.opencensus.io/CONTRIBUTING.md +++ /dev/null @@ -1,63 +0,0 @@ -# How to contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution, -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult [GitHub Help] for more -information on using pull requests. - -[GitHub Help]: https://help.github.com/articles/about-pull-requests/ - -## Instructions - -Fork the repo, checkout the upstream repo to your GOPATH by: - -``` -$ go get -d go.opencensus.io -``` - -Add your fork as an origin: - -``` -cd $(go env GOPATH)/src/go.opencensus.io -git remote add fork git@github.com:YOUR_GITHUB_USERNAME/opencensus-go.git -``` - -Run tests: - -``` -$ make install-tools # Only first time. -$ make -``` - -Checkout a new branch, make modifications and push the branch to your fork: - -``` -$ git checkout -b feature -# edit files -$ git commit -$ git push fork feature -``` - -Open a pull request against the main opencensus-go repo. - -## General Notes -This project uses Appveyor and Travis for CI. - -The dependencies are managed with `go mod` if you work with the sources under your -`$GOPATH` you need to set the environment variable `GO111MODULE=on`. \ No newline at end of file diff --git a/vendor/go.opencensus.io/LICENSE b/vendor/go.opencensus.io/LICENSE deleted file mode 100644 index 7a4a3ea24..000000000 --- a/vendor/go.opencensus.io/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - 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. \ No newline at end of file diff --git a/vendor/go.opencensus.io/Makefile b/vendor/go.opencensus.io/Makefile deleted file mode 100644 index d896edc99..000000000 --- a/vendor/go.opencensus.io/Makefile +++ /dev/null @@ -1,97 +0,0 @@ -# TODO: Fix this on windows. -ALL_SRC := $(shell find . -name '*.go' \ - -not -path './vendor/*' \ - -not -path '*/gen-go/*' \ - -type f | sort) -ALL_PKGS := $(shell go list $(sort $(dir $(ALL_SRC)))) - -GOTEST_OPT?=-v -race -timeout 30s -GOTEST_OPT_WITH_COVERAGE = $(GOTEST_OPT) -coverprofile=coverage.txt -covermode=atomic -GOTEST=go test -GOIMPORTS=goimports -GOLINT=golint -GOVET=go vet -EMBEDMD=embedmd -# TODO decide if we need to change these names. -TRACE_ID_LINT_EXCEPTION="type name will be used as trace.TraceID by other packages" -TRACE_OPTION_LINT_EXCEPTION="type name will be used as trace.TraceOptions by other packages" -README_FILES := $(shell find . -name '*README.md' | sort | tr '\n' ' ') - -.DEFAULT_GOAL := imports-lint-vet-embedmd-test - -.PHONY: imports-lint-vet-embedmd-test -imports-lint-vet-embedmd-test: imports lint vet embedmd test - -# TODO enable test-with-coverage in tavis -.PHONY: travis-ci -travis-ci: imports lint vet embedmd test test-386 - -all-pkgs: - @echo $(ALL_PKGS) | tr ' ' '\n' | sort - -all-srcs: - @echo $(ALL_SRC) | tr ' ' '\n' | sort - -.PHONY: test -test: - $(GOTEST) $(GOTEST_OPT) $(ALL_PKGS) - -.PHONY: test-386 -test-386: - GOARCH=386 $(GOTEST) -v -timeout 30s $(ALL_PKGS) - -.PHONY: test-with-coverage -test-with-coverage: - $(GOTEST) $(GOTEST_OPT_WITH_COVERAGE) $(ALL_PKGS) - -.PHONY: imports -imports: - @IMPORTSOUT=`$(GOIMPORTS) -l $(ALL_SRC) 2>&1`; \ - if [ "$$IMPORTSOUT" ]; then \ - echo "$(GOIMPORTS) FAILED => goimports the following files:\n"; \ - echo "$$IMPORTSOUT\n"; \ - exit 1; \ - else \ - echo "Imports finished successfully"; \ - fi - -.PHONY: lint -lint: - @LINTOUT=`$(GOLINT) $(ALL_PKGS) | grep -v $(TRACE_ID_LINT_EXCEPTION) | grep -v $(TRACE_OPTION_LINT_EXCEPTION) 2>&1`; \ - if [ "$$LINTOUT" ]; then \ - echo "$(GOLINT) FAILED => clean the following lint errors:\n"; \ - echo "$$LINTOUT\n"; \ - exit 1; \ - else \ - echo "Lint finished successfully"; \ - fi - -.PHONY: vet -vet: - # TODO: Understand why go vet downloads "github.com/google/go-cmp v0.2.0" - @VETOUT=`$(GOVET) ./... | grep -v "go: downloading" 2>&1`; \ - if [ "$$VETOUT" ]; then \ - echo "$(GOVET) FAILED => go vet the following files:\n"; \ - echo "$$VETOUT\n"; \ - exit 1; \ - else \ - echo "Vet finished successfully"; \ - fi - -.PHONY: embedmd -embedmd: - @EMBEDMDOUT=`$(EMBEDMD) -d $(README_FILES) 2>&1`; \ - if [ "$$EMBEDMDOUT" ]; then \ - echo "$(EMBEDMD) FAILED => embedmd the following files:\n"; \ - echo "$$EMBEDMDOUT\n"; \ - exit 1; \ - else \ - echo "Embedmd finished successfully"; \ - fi - -.PHONY: install-tools -install-tools: - go install golang.org/x/lint/golint@latest - go install golang.org/x/tools/cmd/cover@latest - go install golang.org/x/tools/cmd/goimports@latest - go install github.com/rakyll/embedmd@latest diff --git a/vendor/go.opencensus.io/README.md b/vendor/go.opencensus.io/README.md deleted file mode 100644 index 1d7e83711..000000000 --- a/vendor/go.opencensus.io/README.md +++ /dev/null @@ -1,267 +0,0 @@ -# OpenCensus Libraries for Go - -[![Build Status][travis-image]][travis-url] -[![Windows Build Status][appveyor-image]][appveyor-url] -[![GoDoc][godoc-image]][godoc-url] -[![Gitter chat][gitter-image]][gitter-url] - -OpenCensus Go is a Go implementation of OpenCensus, a toolkit for -collecting application performance and behavior monitoring data. -Currently it consists of three major components: tags, stats and tracing. - -#### OpenCensus and OpenTracing have merged to form OpenTelemetry, which serves as the next major version of OpenCensus and OpenTracing. OpenTelemetry will offer backwards compatibility with existing OpenCensus integrations, and we will continue to make security patches to existing OpenCensus libraries for two years. Read more about the merger [here](https://medium.com/opentracing/a-roadmap-to-convergence-b074e5815289). - -## Installation - -``` -$ go get -u go.opencensus.io -``` - -The API of this project is still evolving, see: [Deprecation Policy](#deprecation-policy). -The use of vendoring or a dependency management tool is recommended. - -## Prerequisites - -OpenCensus Go libraries require Go 1.8 or later. - -## Getting Started - -The easiest way to get started using OpenCensus in your application is to use an existing -integration with your RPC framework: - -* [net/http](https://godoc.org/go.opencensus.io/plugin/ochttp) -* [gRPC](https://godoc.org/go.opencensus.io/plugin/ocgrpc) -* [database/sql](https://godoc.org/github.com/opencensus-integrations/ocsql) -* [Go kit](https://godoc.org/github.com/go-kit/kit/tracing/opencensus) -* [Groupcache](https://godoc.org/github.com/orijtech/groupcache) -* [Caddy webserver](https://godoc.org/github.com/orijtech/caddy) -* [MongoDB](https://godoc.org/github.com/orijtech/mongo-go-driver) -* [Redis gomodule/redigo](https://godoc.org/github.com/orijtech/redigo) -* [Redis goredis/redis](https://godoc.org/github.com/orijtech/redis) -* [Memcache](https://godoc.org/github.com/orijtech/gomemcache) - -If you're using a framework not listed here, you could either implement your own middleware for your -framework or use [custom stats](#stats) and [spans](#spans) directly in your application. - -## Exporters - -OpenCensus can export instrumentation data to various backends. -OpenCensus has exporter implementations for the following, users -can implement their own exporters by implementing the exporter interfaces -([stats](https://godoc.org/go.opencensus.io/stats/view#Exporter), -[trace](https://godoc.org/go.opencensus.io/trace#Exporter)): - -* [Prometheus][exporter-prom] for stats -* [OpenZipkin][exporter-zipkin] for traces -* [Stackdriver][exporter-stackdriver] Monitoring for stats and Trace for traces -* [Jaeger][exporter-jaeger] for traces -* [AWS X-Ray][exporter-xray] for traces -* [Datadog][exporter-datadog] for stats and traces -* [Graphite][exporter-graphite] for stats -* [Honeycomb][exporter-honeycomb] for traces -* [New Relic][exporter-newrelic] for stats and traces - -## Overview - -![OpenCensus Overview](https://i.imgur.com/cf4ElHE.jpg) - -In a microservices environment, a user request may go through -multiple services until there is a response. OpenCensus allows -you to instrument your services and collect diagnostics data all -through your services end-to-end. - -## Tags - -Tags represent propagated key-value pairs. They are propagated using `context.Context` -in the same process or can be encoded to be transmitted on the wire. Usually, this will -be handled by an integration plugin, e.g. `ocgrpc.ServerHandler` and `ocgrpc.ClientHandler` -for gRPC. - -Package `tag` allows adding or modifying tags in the current context. - -[embedmd]:# (internal/readme/tags.go new) -```go -ctx, err := tag.New(ctx, - tag.Insert(osKey, "macOS-10.12.5"), - tag.Upsert(userIDKey, "cde36753ed"), -) -if err != nil { - log.Fatal(err) -} -``` - -## Stats - -OpenCensus is a low-overhead framework even if instrumentation is always enabled. -In order to be so, it is optimized to make recording of data points fast -and separate from the data aggregation. - -OpenCensus stats collection happens in two stages: - -* Definition of measures and recording of data points -* Definition of views and aggregation of the recorded data - -### Recording - -Measurements are data points associated with a measure. -Recording implicitly tags the set of Measurements with the tags from the -provided context: - -[embedmd]:# (internal/readme/stats.go record) -```go -stats.Record(ctx, videoSize.M(102478)) -``` - -### Views - -Views are how Measures are aggregated. You can think of them as queries over the -set of recorded data points (measurements). - -Views have two parts: the tags to group by and the aggregation type used. - -Currently three types of aggregations are supported: -* CountAggregation is used to count the number of times a sample was recorded. -* DistributionAggregation is used to provide a histogram of the values of the samples. -* SumAggregation is used to sum up all sample values. - -[embedmd]:# (internal/readme/stats.go aggs) -```go -distAgg := view.Distribution(1<<32, 2<<32, 3<<32) -countAgg := view.Count() -sumAgg := view.Sum() -``` - -Here we create a view with the DistributionAggregation over our measure. - -[embedmd]:# (internal/readme/stats.go view) -```go -if err := view.Register(&view.View{ - Name: "example.com/video_size_distribution", - Description: "distribution of processed video size over time", - Measure: videoSize, - Aggregation: view.Distribution(1<<32, 2<<32, 3<<32), -}); err != nil { - log.Fatalf("Failed to register view: %v", err) -} -``` - -Register begins collecting data for the view. Registered views' data will be -exported via the registered exporters. - -## Traces - -A distributed trace tracks the progression of a single user request as -it is handled by the services and processes that make up an application. -Each step is called a span in the trace. Spans include metadata about the step, -including especially the time spent in the step, called the span’s latency. - -Below you see a trace and several spans underneath it. - -![Traces and spans](https://i.imgur.com/7hZwRVj.png) - -### Spans - -Span is the unit step in a trace. Each span has a name, latency, status and -additional metadata. - -Below we are starting a span for a cache read and ending it -when we are done: - -[embedmd]:# (internal/readme/trace.go startend) -```go -ctx, span := trace.StartSpan(ctx, "cache.Get") -defer span.End() - -// Do work to get from cache. -``` - -### Propagation - -Spans can have parents or can be root spans if they don't have any parents. -The current span is propagated in-process and across the network to allow associating -new child spans with the parent. - -In the same process, `context.Context` is used to propagate spans. -`trace.StartSpan` creates a new span as a root if the current context -doesn't contain a span. Or, it creates a child of the span that is -already in current context. The returned context can be used to keep -propagating the newly created span in the current context. - -[embedmd]:# (internal/readme/trace.go startend) -```go -ctx, span := trace.StartSpan(ctx, "cache.Get") -defer span.End() - -// Do work to get from cache. -``` - -Across the network, OpenCensus provides different propagation -methods for different protocols. - -* gRPC integrations use the OpenCensus' [binary propagation format](https://godoc.org/go.opencensus.io/trace/propagation). -* HTTP integrations use Zipkin's [B3](https://github.com/openzipkin/b3-propagation) - by default but can be configured to use a custom propagation method by setting another - [propagation.HTTPFormat](https://godoc.org/go.opencensus.io/trace/propagation#HTTPFormat). - -## Execution Tracer - -With Go 1.11, OpenCensus Go will support integration with the Go execution tracer. -See [Debugging Latency in Go](https://medium.com/observability/debugging-latency-in-go-1-11-9f97a7910d68) -for an example of their mutual use. - -## Profiles - -OpenCensus tags can be applied as profiler labels -for users who are on Go 1.9 and above. - -[embedmd]:# (internal/readme/tags.go profiler) -```go -ctx, err = tag.New(ctx, - tag.Insert(osKey, "macOS-10.12.5"), - tag.Insert(userIDKey, "fff0989878"), -) -if err != nil { - log.Fatal(err) -} -tag.Do(ctx, func(ctx context.Context) { - // Do work. - // When profiling is on, samples will be - // recorded with the key/values from the tag map. -}) -``` - -A screenshot of the CPU profile from the program above: - -![CPU profile](https://i.imgur.com/jBKjlkw.png) - -## Deprecation Policy - -Before version 1.0.0, the following deprecation policy will be observed: - -No backwards-incompatible changes will be made except for the removal of symbols that have -been marked as *Deprecated* for at least one minor release (e.g. 0.9.0 to 0.10.0). A release -removing the *Deprecated* functionality will be made no sooner than 28 days after the first -release in which the functionality was marked *Deprecated*. - -[travis-image]: https://travis-ci.org/census-instrumentation/opencensus-go.svg?branch=master -[travis-url]: https://travis-ci.org/census-instrumentation/opencensus-go -[appveyor-image]: https://ci.appveyor.com/api/projects/status/vgtt29ps1783ig38?svg=true -[appveyor-url]: https://ci.appveyor.com/project/opencensusgoteam/opencensus-go/branch/master -[godoc-image]: https://godoc.org/go.opencensus.io?status.svg -[godoc-url]: https://godoc.org/go.opencensus.io -[gitter-image]: https://badges.gitter.im/census-instrumentation/lobby.svg -[gitter-url]: https://gitter.im/census-instrumentation/lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - - -[new-ex]: https://godoc.org/go.opencensus.io/tag#example-NewMap -[new-replace-ex]: https://godoc.org/go.opencensus.io/tag#example-NewMap--Replace - -[exporter-prom]: https://godoc.org/contrib.go.opencensus.io/exporter/prometheus -[exporter-stackdriver]: https://godoc.org/contrib.go.opencensus.io/exporter/stackdriver -[exporter-zipkin]: https://godoc.org/contrib.go.opencensus.io/exporter/zipkin -[exporter-jaeger]: https://godoc.org/contrib.go.opencensus.io/exporter/jaeger -[exporter-xray]: https://github.com/census-ecosystem/opencensus-go-exporter-aws -[exporter-datadog]: https://github.com/DataDog/opencensus-go-exporter-datadog -[exporter-graphite]: https://github.com/census-ecosystem/opencensus-go-exporter-graphite -[exporter-honeycomb]: https://github.com/honeycombio/opencensus-exporter -[exporter-newrelic]: https://github.com/newrelic/newrelic-opencensus-exporter-go diff --git a/vendor/go.opencensus.io/appveyor.yml b/vendor/go.opencensus.io/appveyor.yml deleted file mode 100644 index d08f0edaf..000000000 --- a/vendor/go.opencensus.io/appveyor.yml +++ /dev/null @@ -1,24 +0,0 @@ -version: "{build}" - -platform: x64 - -clone_folder: c:\gopath\src\go.opencensus.io - -environment: - GOPATH: 'c:\gopath' - GO111MODULE: 'on' - CGO_ENABLED: '0' # See: https://github.com/appveyor/ci/issues/2613 - -stack: go 1.11 - -before_test: - - go version - - go env - -build: false -deploy: false - -test_script: - - cd %APPVEYOR_BUILD_FOLDER% - - go build -v .\... - - go test -v .\... # No -race because cgo is disabled diff --git a/vendor/go.opencensus.io/internal/internal.go b/vendor/go.opencensus.io/internal/internal.go deleted file mode 100644 index 81dc7183e..000000000 --- a/vendor/go.opencensus.io/internal/internal.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package internal // import "go.opencensus.io/internal" - -import ( - "fmt" - "time" - - opencensus "go.opencensus.io" -) - -// UserAgent is the user agent to be added to the outgoing -// requests from the exporters. -var UserAgent = fmt.Sprintf("opencensus-go/%s", opencensus.Version()) - -// MonotonicEndTime returns the end time at present -// but offset from start, monotonically. -// -// The monotonic clock is used in subtractions hence -// the duration since start added back to start gives -// end as a monotonic time. -// See https://golang.org/pkg/time/#hdr-Monotonic_Clocks -func MonotonicEndTime(start time.Time) time.Time { - return start.Add(time.Since(start)) -} diff --git a/vendor/go.opencensus.io/internal/sanitize.go b/vendor/go.opencensus.io/internal/sanitize.go deleted file mode 100644 index de8ccf236..000000000 --- a/vendor/go.opencensus.io/internal/sanitize.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package internal - -import ( - "strings" - "unicode" -) - -const labelKeySizeLimit = 100 - -// Sanitize returns a string that is trunacated to 100 characters if it's too -// long, and replaces non-alphanumeric characters to underscores. -func Sanitize(s string) string { - if len(s) == 0 { - return s - } - if len(s) > labelKeySizeLimit { - s = s[:labelKeySizeLimit] - } - s = strings.Map(sanitizeRune, s) - if unicode.IsDigit(rune(s[0])) { - s = "key_" + s - } - if s[0] == '_' { - s = "key" + s - } - return s -} - -// converts anything that is not a letter or digit to an underscore -func sanitizeRune(r rune) rune { - if unicode.IsLetter(r) || unicode.IsDigit(r) { - return r - } - // Everything else turns into an underscore - return '_' -} diff --git a/vendor/go.opencensus.io/internal/traceinternals.go b/vendor/go.opencensus.io/internal/traceinternals.go deleted file mode 100644 index 073af7b47..000000000 --- a/vendor/go.opencensus.io/internal/traceinternals.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package internal - -import ( - "time" -) - -// Trace allows internal access to some trace functionality. -// TODO(#412): remove this -var Trace interface{} - -// LocalSpanStoreEnabled true if the local span store is enabled. -var LocalSpanStoreEnabled bool - -// BucketConfiguration stores the number of samples to store for span buckets -// for successful and failed spans for a particular span name. -type BucketConfiguration struct { - Name string - MaxRequestsSucceeded int - MaxRequestsErrors int -} - -// PerMethodSummary is a summary of the spans stored for a single span name. -type PerMethodSummary struct { - Active int - LatencyBuckets []LatencyBucketSummary - ErrorBuckets []ErrorBucketSummary -} - -// LatencyBucketSummary is a summary of a latency bucket. -type LatencyBucketSummary struct { - MinLatency, MaxLatency time.Duration - Size int -} - -// ErrorBucketSummary is a summary of an error bucket. -type ErrorBucketSummary struct { - ErrorCode int32 - Size int -} diff --git a/vendor/go.opencensus.io/opencensus.go b/vendor/go.opencensus.io/opencensus.go deleted file mode 100644 index 11e31f421..000000000 --- a/vendor/go.opencensus.io/opencensus.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -// Package opencensus contains Go support for OpenCensus. -package opencensus // import "go.opencensus.io" - -// Version is the current release version of OpenCensus in use. -func Version() string { - return "0.24.0" -} diff --git a/vendor/go.opencensus.io/trace/basetypes.go b/vendor/go.opencensus.io/trace/basetypes.go deleted file mode 100644 index c8e26ed63..000000000 --- a/vendor/go.opencensus.io/trace/basetypes.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package trace - -import ( - "fmt" - "time" -) - -type ( - // TraceID is a 16-byte identifier for a set of spans. - TraceID [16]byte - - // SpanID is an 8-byte identifier for a single span. - SpanID [8]byte -) - -func (t TraceID) String() string { - return fmt.Sprintf("%02x", t[:]) -} - -func (s SpanID) String() string { - return fmt.Sprintf("%02x", s[:]) -} - -// Annotation represents a text annotation with a set of attributes and a timestamp. -type Annotation struct { - Time time.Time - Message string - Attributes map[string]interface{} -} - -// Attribute represents a key-value pair on a span, link or annotation. -// Construct with one of: BoolAttribute, Int64Attribute, or StringAttribute. -type Attribute struct { - key string - value interface{} -} - -// Key returns the attribute's key -func (a *Attribute) Key() string { - return a.key -} - -// Value returns the attribute's value -func (a *Attribute) Value() interface{} { - return a.value -} - -// BoolAttribute returns a bool-valued attribute. -func BoolAttribute(key string, value bool) Attribute { - return Attribute{key: key, value: value} -} - -// Int64Attribute returns an int64-valued attribute. -func Int64Attribute(key string, value int64) Attribute { - return Attribute{key: key, value: value} -} - -// Float64Attribute returns a float64-valued attribute. -func Float64Attribute(key string, value float64) Attribute { - return Attribute{key: key, value: value} -} - -// StringAttribute returns a string-valued attribute. -func StringAttribute(key string, value string) Attribute { - return Attribute{key: key, value: value} -} - -// LinkType specifies the relationship between the span that had the link -// added, and the linked span. -type LinkType int32 - -// LinkType values. -const ( - LinkTypeUnspecified LinkType = iota // The relationship of the two spans is unknown. - LinkTypeChild // The linked span is a child of the current span. - LinkTypeParent // The linked span is the parent of the current span. -) - -// Link represents a reference from one span to another span. -type Link struct { - TraceID TraceID - SpanID SpanID - Type LinkType - // Attributes is a set of attributes on the link. - Attributes map[string]interface{} -} - -// MessageEventType specifies the type of message event. -type MessageEventType int32 - -// MessageEventType values. -const ( - MessageEventTypeUnspecified MessageEventType = iota // Unknown event type. - MessageEventTypeSent // Indicates a sent RPC message. - MessageEventTypeRecv // Indicates a received RPC message. -) - -// MessageEvent represents an event describing a message sent or received on the network. -type MessageEvent struct { - Time time.Time - EventType MessageEventType - MessageID int64 - UncompressedByteSize int64 - CompressedByteSize int64 -} - -// Status is the status of a Span. -type Status struct { - // Code is a status code. Zero indicates success. - // - // If Code will be propagated to Google APIs, it ideally should be a value from - // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto . - Code int32 - Message string -} diff --git a/vendor/go.opencensus.io/trace/config.go b/vendor/go.opencensus.io/trace/config.go deleted file mode 100644 index 775f8274f..000000000 --- a/vendor/go.opencensus.io/trace/config.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018, OpenCensus 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. - -package trace - -import ( - "sync" - - "go.opencensus.io/trace/internal" -) - -// Config represents the global tracing configuration. -type Config struct { - // DefaultSampler is the default sampler used when creating new spans. - DefaultSampler Sampler - - // IDGenerator is for internal use only. - IDGenerator internal.IDGenerator - - // MaxAnnotationEventsPerSpan is max number of annotation events per span - MaxAnnotationEventsPerSpan int - - // MaxMessageEventsPerSpan is max number of message events per span - MaxMessageEventsPerSpan int - - // MaxAnnotationEventsPerSpan is max number of attributes per span - MaxAttributesPerSpan int - - // MaxLinksPerSpan is max number of links per span - MaxLinksPerSpan int -} - -var configWriteMu sync.Mutex - -const ( - // DefaultMaxAnnotationEventsPerSpan is default max number of annotation events per span - DefaultMaxAnnotationEventsPerSpan = 32 - - // DefaultMaxMessageEventsPerSpan is default max number of message events per span - DefaultMaxMessageEventsPerSpan = 128 - - // DefaultMaxAttributesPerSpan is default max number of attributes per span - DefaultMaxAttributesPerSpan = 32 - - // DefaultMaxLinksPerSpan is default max number of links per span - DefaultMaxLinksPerSpan = 32 -) - -// ApplyConfig applies changes to the global tracing configuration. -// -// Fields not provided in the given config are going to be preserved. -func ApplyConfig(cfg Config) { - configWriteMu.Lock() - defer configWriteMu.Unlock() - c := *config.Load().(*Config) - if cfg.DefaultSampler != nil { - c.DefaultSampler = cfg.DefaultSampler - } - if cfg.IDGenerator != nil { - c.IDGenerator = cfg.IDGenerator - } - if cfg.MaxAnnotationEventsPerSpan > 0 { - c.MaxAnnotationEventsPerSpan = cfg.MaxAnnotationEventsPerSpan - } - if cfg.MaxMessageEventsPerSpan > 0 { - c.MaxMessageEventsPerSpan = cfg.MaxMessageEventsPerSpan - } - if cfg.MaxAttributesPerSpan > 0 { - c.MaxAttributesPerSpan = cfg.MaxAttributesPerSpan - } - if cfg.MaxLinksPerSpan > 0 { - c.MaxLinksPerSpan = cfg.MaxLinksPerSpan - } - config.Store(&c) -} diff --git a/vendor/go.opencensus.io/trace/doc.go b/vendor/go.opencensus.io/trace/doc.go deleted file mode 100644 index 7a1616a55..000000000 --- a/vendor/go.opencensus.io/trace/doc.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -/* -Package trace contains support for OpenCensus distributed tracing. - -The following assumes a basic familiarity with OpenCensus concepts. -See http://opencensus.io - -# Exporting Traces - -To export collected tracing data, register at least one exporter. You can use -one of the provided exporters or write your own. - - trace.RegisterExporter(exporter) - -By default, traces will be sampled relatively rarely. To change the sampling -frequency for your entire program, call ApplyConfig. Use a ProbabilitySampler -to sample a subset of traces, or use AlwaysSample to collect a trace on every run: - - trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) - -Be careful about using trace.AlwaysSample in a production application with -significant traffic: a new trace will be started and exported for every request. - -# Adding Spans to a Trace - -A trace consists of a tree of spans. In Go, the current span is carried in a -context.Context. - -It is common to want to capture all the activity of a function call in a span. For -this to work, the function must take a context.Context as a parameter. Add these two -lines to the top of the function: - - ctx, span := trace.StartSpan(ctx, "example.com/Run") - defer span.End() - -StartSpan will create a new top-level span if the context -doesn't contain another span, otherwise it will create a child span. -*/ -package trace // import "go.opencensus.io/trace" diff --git a/vendor/go.opencensus.io/trace/evictedqueue.go b/vendor/go.opencensus.io/trace/evictedqueue.go deleted file mode 100644 index ffc264f23..000000000 --- a/vendor/go.opencensus.io/trace/evictedqueue.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019, OpenCensus 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. - -package trace - -type evictedQueue struct { - queue []interface{} - capacity int - droppedCount int -} - -func newEvictedQueue(capacity int) *evictedQueue { - eq := &evictedQueue{ - capacity: capacity, - queue: make([]interface{}, 0), - } - - return eq -} - -func (eq *evictedQueue) add(value interface{}) { - if len(eq.queue) == eq.capacity { - eq.queue = eq.queue[1:] - eq.droppedCount++ - } - eq.queue = append(eq.queue, value) -} diff --git a/vendor/go.opencensus.io/trace/export.go b/vendor/go.opencensus.io/trace/export.go deleted file mode 100644 index e0d9a4b99..000000000 --- a/vendor/go.opencensus.io/trace/export.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package trace - -import ( - "sync" - "sync/atomic" - "time" -) - -// Exporter is a type for functions that receive sampled trace spans. -// -// The ExportSpan method should be safe for concurrent use and should return -// quickly; if an Exporter takes a significant amount of time to process a -// SpanData, that work should be done on another goroutine. -// -// The SpanData should not be modified, but a pointer to it can be kept. -type Exporter interface { - ExportSpan(s *SpanData) -} - -type exportersMap map[Exporter]struct{} - -var ( - exporterMu sync.Mutex - exporters atomic.Value -) - -// RegisterExporter adds to the list of Exporters that will receive sampled -// trace spans. -// -// Binaries can register exporters, libraries shouldn't register exporters. -func RegisterExporter(e Exporter) { - exporterMu.Lock() - new := make(exportersMap) - if old, ok := exporters.Load().(exportersMap); ok { - for k, v := range old { - new[k] = v - } - } - new[e] = struct{}{} - exporters.Store(new) - exporterMu.Unlock() -} - -// UnregisterExporter removes from the list of Exporters the Exporter that was -// registered with the given name. -func UnregisterExporter(e Exporter) { - exporterMu.Lock() - new := make(exportersMap) - if old, ok := exporters.Load().(exportersMap); ok { - for k, v := range old { - new[k] = v - } - } - delete(new, e) - exporters.Store(new) - exporterMu.Unlock() -} - -// SpanData contains all the information collected by a Span. -type SpanData struct { - SpanContext - ParentSpanID SpanID - SpanKind int - Name string - StartTime time.Time - // The wall clock time of EndTime will be adjusted to always be offset - // from StartTime by the duration of the span. - EndTime time.Time - // The values of Attributes each have type string, bool, or int64. - Attributes map[string]interface{} - Annotations []Annotation - MessageEvents []MessageEvent - Status - Links []Link - HasRemoteParent bool - DroppedAttributeCount int - DroppedAnnotationCount int - DroppedMessageEventCount int - DroppedLinkCount int - - // ChildSpanCount holds the number of child span created for this span. - ChildSpanCount int -} diff --git a/vendor/go.opencensus.io/trace/internal/internal.go b/vendor/go.opencensus.io/trace/internal/internal.go deleted file mode 100644 index 7e808d8f3..000000000 --- a/vendor/go.opencensus.io/trace/internal/internal.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018, OpenCensus 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. - -// Package internal provides trace internals. -package internal - -// IDGenerator allows custom generators for TraceId and SpanId. -type IDGenerator interface { - NewTraceID() [16]byte - NewSpanID() [8]byte -} diff --git a/vendor/go.opencensus.io/trace/lrumap.go b/vendor/go.opencensus.io/trace/lrumap.go deleted file mode 100644 index 80095a5f6..000000000 --- a/vendor/go.opencensus.io/trace/lrumap.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2019, OpenCensus 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. - -package trace - -import ( - "github.com/golang/groupcache/lru" -) - -// A simple lru.Cache wrapper that tracks the keys of the current contents and -// the cumulative number of evicted items. -type lruMap struct { - cacheKeys map[lru.Key]bool - cache *lru.Cache - droppedCount int -} - -func newLruMap(size int) *lruMap { - lm := &lruMap{ - cacheKeys: make(map[lru.Key]bool), - cache: lru.New(size), - droppedCount: 0, - } - lm.cache.OnEvicted = func(key lru.Key, value interface{}) { - delete(lm.cacheKeys, key) - lm.droppedCount++ - } - return lm -} - -func (lm lruMap) len() int { - return lm.cache.Len() -} - -func (lm lruMap) keys() []interface{} { - keys := make([]interface{}, 0, len(lm.cacheKeys)) - for k := range lm.cacheKeys { - keys = append(keys, k) - } - return keys -} - -func (lm *lruMap) add(key, value interface{}) { - lm.cacheKeys[lru.Key(key)] = true - lm.cache.Add(lru.Key(key), value) -} - -func (lm *lruMap) get(key interface{}) (interface{}, bool) { - return lm.cache.Get(key) -} diff --git a/vendor/go.opencensus.io/trace/sampling.go b/vendor/go.opencensus.io/trace/sampling.go deleted file mode 100644 index 71c10f9e3..000000000 --- a/vendor/go.opencensus.io/trace/sampling.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package trace - -import ( - "encoding/binary" -) - -const defaultSamplingProbability = 1e-4 - -// Sampler decides whether a trace should be sampled and exported. -type Sampler func(SamplingParameters) SamplingDecision - -// SamplingParameters contains the values passed to a Sampler. -type SamplingParameters struct { - ParentContext SpanContext - TraceID TraceID - SpanID SpanID - Name string - HasRemoteParent bool -} - -// SamplingDecision is the value returned by a Sampler. -type SamplingDecision struct { - Sample bool -} - -// ProbabilitySampler returns a Sampler that samples a given fraction of traces. -// -// It also samples spans whose parents are sampled. -func ProbabilitySampler(fraction float64) Sampler { - if !(fraction >= 0) { - fraction = 0 - } else if fraction >= 1 { - return AlwaysSample() - } - - traceIDUpperBound := uint64(fraction * (1 << 63)) - return Sampler(func(p SamplingParameters) SamplingDecision { - if p.ParentContext.IsSampled() { - return SamplingDecision{Sample: true} - } - x := binary.BigEndian.Uint64(p.TraceID[0:8]) >> 1 - return SamplingDecision{Sample: x < traceIDUpperBound} - }) -} - -// AlwaysSample returns a Sampler that samples every trace. -// Be careful about using this sampler in a production application with -// significant traffic: a new trace will be started and exported for every -// request. -func AlwaysSample() Sampler { - return func(p SamplingParameters) SamplingDecision { - return SamplingDecision{Sample: true} - } -} - -// NeverSample returns a Sampler that samples no traces. -func NeverSample() Sampler { - return func(p SamplingParameters) SamplingDecision { - return SamplingDecision{Sample: false} - } -} diff --git a/vendor/go.opencensus.io/trace/spanbucket.go b/vendor/go.opencensus.io/trace/spanbucket.go deleted file mode 100644 index fbabad34c..000000000 --- a/vendor/go.opencensus.io/trace/spanbucket.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package trace - -import ( - "time" -) - -// samplePeriod is the minimum time between accepting spans in a single bucket. -const samplePeriod = time.Second - -// defaultLatencies contains the default latency bucket bounds. -// TODO: consider defaults, make configurable -var defaultLatencies = [...]time.Duration{ - 10 * time.Microsecond, - 100 * time.Microsecond, - time.Millisecond, - 10 * time.Millisecond, - 100 * time.Millisecond, - time.Second, - 10 * time.Second, - time.Minute, -} - -// bucket is a container for a set of spans for a particular error code or latency range. -type bucket struct { - nextTime time.Time // next time we can accept a span - buffer []*SpanData // circular buffer of spans - nextIndex int // location next SpanData should be placed in buffer - overflow bool // whether the circular buffer has wrapped around -} - -func makeBucket(bufferSize int) bucket { - return bucket{ - buffer: make([]*SpanData, bufferSize), - } -} - -// add adds a span to the bucket, if nextTime has been reached. -func (b *bucket) add(s *SpanData) { - if s.EndTime.Before(b.nextTime) { - return - } - if len(b.buffer) == 0 { - return - } - b.nextTime = s.EndTime.Add(samplePeriod) - b.buffer[b.nextIndex] = s - b.nextIndex++ - if b.nextIndex == len(b.buffer) { - b.nextIndex = 0 - b.overflow = true - } -} - -// size returns the number of spans in the bucket. -func (b *bucket) size() int { - if b.overflow { - return len(b.buffer) - } - return b.nextIndex -} - -// span returns the ith span in the bucket. -func (b *bucket) span(i int) *SpanData { - if !b.overflow { - return b.buffer[i] - } - if i < len(b.buffer)-b.nextIndex { - return b.buffer[b.nextIndex+i] - } - return b.buffer[b.nextIndex+i-len(b.buffer)] -} - -// resize changes the size of the bucket to n, keeping up to n existing spans. -func (b *bucket) resize(n int) { - cur := b.size() - newBuffer := make([]*SpanData, n) - if cur < n { - for i := 0; i < cur; i++ { - newBuffer[i] = b.span(i) - } - b.buffer = newBuffer - b.nextIndex = cur - b.overflow = false - return - } - for i := 0; i < n; i++ { - newBuffer[i] = b.span(i + cur - n) - } - b.buffer = newBuffer - b.nextIndex = 0 - b.overflow = true -} - -// latencyBucket returns the appropriate bucket number for a given latency. -func latencyBucket(latency time.Duration) int { - i := 0 - for i < len(defaultLatencies) && latency >= defaultLatencies[i] { - i++ - } - return i -} - -// latencyBucketBounds returns the lower and upper bounds for a latency bucket -// number. -// -// The lower bound is inclusive, the upper bound is exclusive (except for the -// last bucket.) -func latencyBucketBounds(index int) (lower time.Duration, upper time.Duration) { - if index == 0 { - return 0, defaultLatencies[index] - } - if index == len(defaultLatencies) { - return defaultLatencies[index-1], 1<<63 - 1 - } - return defaultLatencies[index-1], defaultLatencies[index] -} diff --git a/vendor/go.opencensus.io/trace/spanstore.go b/vendor/go.opencensus.io/trace/spanstore.go deleted file mode 100644 index e601f76f2..000000000 --- a/vendor/go.opencensus.io/trace/spanstore.go +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package trace - -import ( - "sync" - "time" - - "go.opencensus.io/internal" -) - -const ( - maxBucketSize = 100000 - defaultBucketSize = 10 -) - -var ( - ssmu sync.RWMutex // protects spanStores - spanStores = make(map[string]*spanStore) -) - -// This exists purely to avoid exposing internal methods used by z-Pages externally. -type internalOnly struct{} - -func init() { - //TODO(#412): remove - internal.Trace = &internalOnly{} -} - -// ReportActiveSpans returns the active spans for the given name. -func (i internalOnly) ReportActiveSpans(name string) []*SpanData { - s := spanStoreForName(name) - if s == nil { - return nil - } - var out []*SpanData - s.mu.Lock() - defer s.mu.Unlock() - for activeSpan := range s.active { - if s, ok := activeSpan.(*span); ok { - out = append(out, s.makeSpanData()) - } - } - return out -} - -// ReportSpansByError returns a sample of error spans. -// -// If code is nonzero, only spans with that status code are returned. -func (i internalOnly) ReportSpansByError(name string, code int32) []*SpanData { - s := spanStoreForName(name) - if s == nil { - return nil - } - var out []*SpanData - s.mu.Lock() - defer s.mu.Unlock() - if code != 0 { - if b, ok := s.errors[code]; ok { - for _, sd := range b.buffer { - if sd == nil { - break - } - out = append(out, sd) - } - } - } else { - for _, b := range s.errors { - for _, sd := range b.buffer { - if sd == nil { - break - } - out = append(out, sd) - } - } - } - return out -} - -// ConfigureBucketSizes sets the number of spans to keep per latency and error -// bucket for different span names. -func (i internalOnly) ConfigureBucketSizes(bcs []internal.BucketConfiguration) { - for _, bc := range bcs { - latencyBucketSize := bc.MaxRequestsSucceeded - if latencyBucketSize < 0 { - latencyBucketSize = 0 - } - if latencyBucketSize > maxBucketSize { - latencyBucketSize = maxBucketSize - } - errorBucketSize := bc.MaxRequestsErrors - if errorBucketSize < 0 { - errorBucketSize = 0 - } - if errorBucketSize > maxBucketSize { - errorBucketSize = maxBucketSize - } - spanStoreSetSize(bc.Name, latencyBucketSize, errorBucketSize) - } -} - -// ReportSpansPerMethod returns a summary of what spans are being stored for each span name. -func (i internalOnly) ReportSpansPerMethod() map[string]internal.PerMethodSummary { - out := make(map[string]internal.PerMethodSummary) - ssmu.RLock() - defer ssmu.RUnlock() - for name, s := range spanStores { - s.mu.Lock() - p := internal.PerMethodSummary{ - Active: len(s.active), - } - for code, b := range s.errors { - p.ErrorBuckets = append(p.ErrorBuckets, internal.ErrorBucketSummary{ - ErrorCode: code, - Size: b.size(), - }) - } - for i, b := range s.latency { - min, max := latencyBucketBounds(i) - p.LatencyBuckets = append(p.LatencyBuckets, internal.LatencyBucketSummary{ - MinLatency: min, - MaxLatency: max, - Size: b.size(), - }) - } - s.mu.Unlock() - out[name] = p - } - return out -} - -// ReportSpansByLatency returns a sample of successful spans. -// -// minLatency is the minimum latency of spans to be returned. -// maxLatency, if nonzero, is the maximum latency of spans to be returned. -func (i internalOnly) ReportSpansByLatency(name string, minLatency, maxLatency time.Duration) []*SpanData { - s := spanStoreForName(name) - if s == nil { - return nil - } - var out []*SpanData - s.mu.Lock() - defer s.mu.Unlock() - for i, b := range s.latency { - min, max := latencyBucketBounds(i) - if i+1 != len(s.latency) && max <= minLatency { - continue - } - if maxLatency != 0 && maxLatency < min { - continue - } - for _, sd := range b.buffer { - if sd == nil { - break - } - if minLatency != 0 || maxLatency != 0 { - d := sd.EndTime.Sub(sd.StartTime) - if d < minLatency { - continue - } - if maxLatency != 0 && d > maxLatency { - continue - } - } - out = append(out, sd) - } - } - return out -} - -// spanStore keeps track of spans stored for a particular span name. -// -// It contains all active spans; a sample of spans for failed requests, -// categorized by error code; and a sample of spans for successful requests, -// bucketed by latency. -type spanStore struct { - mu sync.Mutex // protects everything below. - active map[SpanInterface]struct{} - errors map[int32]*bucket - latency []bucket - maxSpansPerErrorBucket int -} - -// newSpanStore creates a span store. -func newSpanStore(name string, latencyBucketSize int, errorBucketSize int) *spanStore { - s := &spanStore{ - active: make(map[SpanInterface]struct{}), - latency: make([]bucket, len(defaultLatencies)+1), - maxSpansPerErrorBucket: errorBucketSize, - } - for i := range s.latency { - s.latency[i] = makeBucket(latencyBucketSize) - } - return s -} - -// spanStoreForName returns the spanStore for the given name. -// -// It returns nil if it doesn't exist. -func spanStoreForName(name string) *spanStore { - var s *spanStore - ssmu.RLock() - s, _ = spanStores[name] - ssmu.RUnlock() - return s -} - -// spanStoreForNameCreateIfNew returns the spanStore for the given name. -// -// It creates it if it didn't exist. -func spanStoreForNameCreateIfNew(name string) *spanStore { - ssmu.RLock() - s, ok := spanStores[name] - ssmu.RUnlock() - if ok { - return s - } - ssmu.Lock() - defer ssmu.Unlock() - s, ok = spanStores[name] - if ok { - return s - } - s = newSpanStore(name, defaultBucketSize, defaultBucketSize) - spanStores[name] = s - return s -} - -// spanStoreSetSize resizes the spanStore for the given name. -// -// It creates it if it didn't exist. -func spanStoreSetSize(name string, latencyBucketSize int, errorBucketSize int) { - ssmu.RLock() - s, ok := spanStores[name] - ssmu.RUnlock() - if ok { - s.resize(latencyBucketSize, errorBucketSize) - return - } - ssmu.Lock() - defer ssmu.Unlock() - s, ok = spanStores[name] - if ok { - s.resize(latencyBucketSize, errorBucketSize) - return - } - s = newSpanStore(name, latencyBucketSize, errorBucketSize) - spanStores[name] = s -} - -func (s *spanStore) resize(latencyBucketSize int, errorBucketSize int) { - s.mu.Lock() - for i := range s.latency { - s.latency[i].resize(latencyBucketSize) - } - for _, b := range s.errors { - b.resize(errorBucketSize) - } - s.maxSpansPerErrorBucket = errorBucketSize - s.mu.Unlock() -} - -// add adds a span to the active bucket of the spanStore. -func (s *spanStore) add(span SpanInterface) { - s.mu.Lock() - s.active[span] = struct{}{} - s.mu.Unlock() -} - -// finished removes a span from the active set, and adds a corresponding -// SpanData to a latency or error bucket. -func (s *spanStore) finished(span SpanInterface, sd *SpanData) { - latency := sd.EndTime.Sub(sd.StartTime) - if latency < 0 { - latency = 0 - } - code := sd.Status.Code - - s.mu.Lock() - delete(s.active, span) - if code == 0 { - s.latency[latencyBucket(latency)].add(sd) - } else { - if s.errors == nil { - s.errors = make(map[int32]*bucket) - } - if b := s.errors[code]; b != nil { - b.add(sd) - } else { - b := makeBucket(s.maxSpansPerErrorBucket) - s.errors[code] = &b - b.add(sd) - } - } - s.mu.Unlock() -} diff --git a/vendor/go.opencensus.io/trace/status_codes.go b/vendor/go.opencensus.io/trace/status_codes.go deleted file mode 100644 index ec60effd1..000000000 --- a/vendor/go.opencensus.io/trace/status_codes.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2018, OpenCensus 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. - -package trace - -// Status codes for use with Span.SetStatus. These correspond to the status -// codes used by gRPC defined here: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto -const ( - StatusCodeOK = 0 - StatusCodeCancelled = 1 - StatusCodeUnknown = 2 - StatusCodeInvalidArgument = 3 - StatusCodeDeadlineExceeded = 4 - StatusCodeNotFound = 5 - StatusCodeAlreadyExists = 6 - StatusCodePermissionDenied = 7 - StatusCodeResourceExhausted = 8 - StatusCodeFailedPrecondition = 9 - StatusCodeAborted = 10 - StatusCodeOutOfRange = 11 - StatusCodeUnimplemented = 12 - StatusCodeInternal = 13 - StatusCodeUnavailable = 14 - StatusCodeDataLoss = 15 - StatusCodeUnauthenticated = 16 -) diff --git a/vendor/go.opencensus.io/trace/trace.go b/vendor/go.opencensus.io/trace/trace.go deleted file mode 100644 index 861df9d39..000000000 --- a/vendor/go.opencensus.io/trace/trace.go +++ /dev/null @@ -1,595 +0,0 @@ -// Copyright 2017, OpenCensus 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. - -package trace - -import ( - "context" - crand "crypto/rand" - "encoding/binary" - "fmt" - "math/rand" - "sync" - "sync/atomic" - "time" - - "go.opencensus.io/internal" - "go.opencensus.io/trace/tracestate" -) - -type tracer struct{} - -var _ Tracer = &tracer{} - -// Span represents a span of a trace. It has an associated SpanContext, and -// stores data accumulated while the span is active. -// -// Ideally users should interact with Spans by calling the functions in this -// package that take a Context parameter. -type span struct { - // data contains information recorded about the span. - // - // It will be non-nil if we are exporting the span or recording events for it. - // Otherwise, data is nil, and the Span is simply a carrier for the - // SpanContext, so that the trace ID is propagated. - data *SpanData - mu sync.Mutex // protects the contents of *data (but not the pointer value.) - spanContext SpanContext - - // lruAttributes are capped at configured limit. When the capacity is reached an oldest entry - // is removed to create room for a new entry. - lruAttributes *lruMap - - // annotations are stored in FIFO queue capped by configured limit. - annotations *evictedQueue - - // messageEvents are stored in FIFO queue capped by configured limit. - messageEvents *evictedQueue - - // links are stored in FIFO queue capped by configured limit. - links *evictedQueue - - // spanStore is the spanStore this span belongs to, if any, otherwise it is nil. - *spanStore - endOnce sync.Once - - executionTracerTaskEnd func() // ends the execution tracer span -} - -// IsRecordingEvents returns true if events are being recorded for this span. -// Use this check to avoid computing expensive annotations when they will never -// be used. -func (s *span) IsRecordingEvents() bool { - if s == nil { - return false - } - return s.data != nil -} - -// TraceOptions contains options associated with a trace span. -type TraceOptions uint32 - -// IsSampled returns true if the span will be exported. -func (sc SpanContext) IsSampled() bool { - return sc.TraceOptions.IsSampled() -} - -// setIsSampled sets the TraceOptions bit that determines whether the span will be exported. -func (sc *SpanContext) setIsSampled(sampled bool) { - if sampled { - sc.TraceOptions |= 1 - } else { - sc.TraceOptions &= ^TraceOptions(1) - } -} - -// IsSampled returns true if the span will be exported. -func (t TraceOptions) IsSampled() bool { - return t&1 == 1 -} - -// SpanContext contains the state that must propagate across process boundaries. -// -// SpanContext is not an implementation of context.Context. -// TODO: add reference to external Census docs for SpanContext. -type SpanContext struct { - TraceID TraceID - SpanID SpanID - TraceOptions TraceOptions - Tracestate *tracestate.Tracestate -} - -type contextKey struct{} - -// FromContext returns the Span stored in a context, or nil if there isn't one. -func (t *tracer) FromContext(ctx context.Context) *Span { - s, _ := ctx.Value(contextKey{}).(*Span) - return s -} - -// NewContext returns a new context with the given Span attached. -func (t *tracer) NewContext(parent context.Context, s *Span) context.Context { - return context.WithValue(parent, contextKey{}, s) -} - -// All available span kinds. Span kind must be either one of these values. -const ( - SpanKindUnspecified = iota - SpanKindServer - SpanKindClient -) - -// StartOptions contains options concerning how a span is started. -type StartOptions struct { - // Sampler to consult for this Span. If provided, it is always consulted. - // - // If not provided, then the behavior differs based on whether - // the parent of this Span is remote, local, or there is no parent. - // In the case of a remote parent or no parent, the - // default sampler (see Config) will be consulted. Otherwise, - // when there is a non-remote parent, no new sampling decision will be made: - // we will preserve the sampling of the parent. - Sampler Sampler - - // SpanKind represents the kind of a span. If none is set, - // SpanKindUnspecified is used. - SpanKind int -} - -// StartOption apply changes to StartOptions. -type StartOption func(*StartOptions) - -// WithSpanKind makes new spans to be created with the given kind. -func WithSpanKind(spanKind int) StartOption { - return func(o *StartOptions) { - o.SpanKind = spanKind - } -} - -// WithSampler makes new spans to be be created with a custom sampler. -// Otherwise, the global sampler is used. -func WithSampler(sampler Sampler) StartOption { - return func(o *StartOptions) { - o.Sampler = sampler - } -} - -// StartSpan starts a new child span of the current span in the context. If -// there is no span in the context, creates a new trace and span. -// -// Returned context contains the newly created span. You can use it to -// propagate the returned span in process. -func (t *tracer) StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) { - var opts StartOptions - var parent SpanContext - if p := t.FromContext(ctx); p != nil { - if ps, ok := p.internal.(*span); ok { - ps.addChild() - } - parent = p.SpanContext() - } - for _, op := range o { - op(&opts) - } - span := startSpanInternal(name, parent != SpanContext{}, parent, false, opts) - - ctx, end := startExecutionTracerTask(ctx, name) - span.executionTracerTaskEnd = end - extSpan := NewSpan(span) - return t.NewContext(ctx, extSpan), extSpan -} - -// StartSpanWithRemoteParent starts a new child span of the span from the given parent. -// -// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is -// preferred for cases where the parent is propagated via an incoming request. -// -// Returned context contains the newly created span. You can use it to -// propagate the returned span in process. -func (t *tracer) StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) { - var opts StartOptions - for _, op := range o { - op(&opts) - } - span := startSpanInternal(name, parent != SpanContext{}, parent, true, opts) - ctx, end := startExecutionTracerTask(ctx, name) - span.executionTracerTaskEnd = end - extSpan := NewSpan(span) - return t.NewContext(ctx, extSpan), extSpan -} - -func startSpanInternal(name string, hasParent bool, parent SpanContext, remoteParent bool, o StartOptions) *span { - s := &span{} - s.spanContext = parent - - cfg := config.Load().(*Config) - if gen, ok := cfg.IDGenerator.(*defaultIDGenerator); ok { - // lazy initialization - gen.init() - } - - if !hasParent { - s.spanContext.TraceID = cfg.IDGenerator.NewTraceID() - } - s.spanContext.SpanID = cfg.IDGenerator.NewSpanID() - sampler := cfg.DefaultSampler - - if !hasParent || remoteParent || o.Sampler != nil { - // If this span is the child of a local span and no Sampler is set in the - // options, keep the parent's TraceOptions. - // - // Otherwise, consult the Sampler in the options if it is non-nil, otherwise - // the default sampler. - if o.Sampler != nil { - sampler = o.Sampler - } - s.spanContext.setIsSampled(sampler(SamplingParameters{ - ParentContext: parent, - TraceID: s.spanContext.TraceID, - SpanID: s.spanContext.SpanID, - Name: name, - HasRemoteParent: remoteParent}).Sample) - } - - if !internal.LocalSpanStoreEnabled && !s.spanContext.IsSampled() { - return s - } - - s.data = &SpanData{ - SpanContext: s.spanContext, - StartTime: time.Now(), - SpanKind: o.SpanKind, - Name: name, - HasRemoteParent: remoteParent, - } - s.lruAttributes = newLruMap(cfg.MaxAttributesPerSpan) - s.annotations = newEvictedQueue(cfg.MaxAnnotationEventsPerSpan) - s.messageEvents = newEvictedQueue(cfg.MaxMessageEventsPerSpan) - s.links = newEvictedQueue(cfg.MaxLinksPerSpan) - - if hasParent { - s.data.ParentSpanID = parent.SpanID - } - if internal.LocalSpanStoreEnabled { - var ss *spanStore - ss = spanStoreForNameCreateIfNew(name) - if ss != nil { - s.spanStore = ss - ss.add(s) - } - } - - return s -} - -// End ends the span. -func (s *span) End() { - if s == nil { - return - } - if s.executionTracerTaskEnd != nil { - s.executionTracerTaskEnd() - } - if !s.IsRecordingEvents() { - return - } - s.endOnce.Do(func() { - exp, _ := exporters.Load().(exportersMap) - mustExport := s.spanContext.IsSampled() && len(exp) > 0 - if s.spanStore != nil || mustExport { - sd := s.makeSpanData() - sd.EndTime = internal.MonotonicEndTime(sd.StartTime) - if s.spanStore != nil { - s.spanStore.finished(s, sd) - } - if mustExport { - for e := range exp { - e.ExportSpan(sd) - } - } - } - }) -} - -// makeSpanData produces a SpanData representing the current state of the Span. -// It requires that s.data is non-nil. -func (s *span) makeSpanData() *SpanData { - var sd SpanData - s.mu.Lock() - sd = *s.data - if s.lruAttributes.len() > 0 { - sd.Attributes = s.lruAttributesToAttributeMap() - sd.DroppedAttributeCount = s.lruAttributes.droppedCount - } - if len(s.annotations.queue) > 0 { - sd.Annotations = s.interfaceArrayToAnnotationArray() - sd.DroppedAnnotationCount = s.annotations.droppedCount - } - if len(s.messageEvents.queue) > 0 { - sd.MessageEvents = s.interfaceArrayToMessageEventArray() - sd.DroppedMessageEventCount = s.messageEvents.droppedCount - } - if len(s.links.queue) > 0 { - sd.Links = s.interfaceArrayToLinksArray() - sd.DroppedLinkCount = s.links.droppedCount - } - s.mu.Unlock() - return &sd -} - -// SpanContext returns the SpanContext of the span. -func (s *span) SpanContext() SpanContext { - if s == nil { - return SpanContext{} - } - return s.spanContext -} - -// SetName sets the name of the span, if it is recording events. -func (s *span) SetName(name string) { - if !s.IsRecordingEvents() { - return - } - s.mu.Lock() - s.data.Name = name - s.mu.Unlock() -} - -// SetStatus sets the status of the span, if it is recording events. -func (s *span) SetStatus(status Status) { - if !s.IsRecordingEvents() { - return - } - s.mu.Lock() - s.data.Status = status - s.mu.Unlock() -} - -func (s *span) interfaceArrayToLinksArray() []Link { - linksArr := make([]Link, 0, len(s.links.queue)) - for _, value := range s.links.queue { - linksArr = append(linksArr, value.(Link)) - } - return linksArr -} - -func (s *span) interfaceArrayToMessageEventArray() []MessageEvent { - messageEventArr := make([]MessageEvent, 0, len(s.messageEvents.queue)) - for _, value := range s.messageEvents.queue { - messageEventArr = append(messageEventArr, value.(MessageEvent)) - } - return messageEventArr -} - -func (s *span) interfaceArrayToAnnotationArray() []Annotation { - annotationArr := make([]Annotation, 0, len(s.annotations.queue)) - for _, value := range s.annotations.queue { - annotationArr = append(annotationArr, value.(Annotation)) - } - return annotationArr -} - -func (s *span) lruAttributesToAttributeMap() map[string]interface{} { - attributes := make(map[string]interface{}, s.lruAttributes.len()) - for _, key := range s.lruAttributes.keys() { - value, ok := s.lruAttributes.get(key) - if ok { - keyStr := key.(string) - attributes[keyStr] = value - } - } - return attributes -} - -func (s *span) copyToCappedAttributes(attributes []Attribute) { - for _, a := range attributes { - s.lruAttributes.add(a.key, a.value) - } -} - -func (s *span) addChild() { - if !s.IsRecordingEvents() { - return - } - s.mu.Lock() - s.data.ChildSpanCount++ - s.mu.Unlock() -} - -// AddAttributes sets attributes in the span. -// -// Existing attributes whose keys appear in the attributes parameter are overwritten. -func (s *span) AddAttributes(attributes ...Attribute) { - if !s.IsRecordingEvents() { - return - } - s.mu.Lock() - s.copyToCappedAttributes(attributes) - s.mu.Unlock() -} - -func (s *span) printStringInternal(attributes []Attribute, str string) { - now := time.Now() - var am map[string]interface{} - if len(attributes) != 0 { - am = make(map[string]interface{}, len(attributes)) - for _, attr := range attributes { - am[attr.key] = attr.value - } - } - s.mu.Lock() - s.annotations.add(Annotation{ - Time: now, - Message: str, - Attributes: am, - }) - s.mu.Unlock() -} - -// Annotate adds an annotation with attributes. -// Attributes can be nil. -func (s *span) Annotate(attributes []Attribute, str string) { - if !s.IsRecordingEvents() { - return - } - s.printStringInternal(attributes, str) -} - -// Annotatef adds an annotation with attributes. -func (s *span) Annotatef(attributes []Attribute, format string, a ...interface{}) { - if !s.IsRecordingEvents() { - return - } - s.printStringInternal(attributes, fmt.Sprintf(format, a...)) -} - -// AddMessageSendEvent adds a message send event to the span. -// -// messageID is an identifier for the message, which is recommended to be -// unique in this span and the same between the send event and the receive -// event (this allows to identify a message between the sender and receiver). -// For example, this could be a sequence id. -func (s *span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) { - if !s.IsRecordingEvents() { - return - } - now := time.Now() - s.mu.Lock() - s.messageEvents.add(MessageEvent{ - Time: now, - EventType: MessageEventTypeSent, - MessageID: messageID, - UncompressedByteSize: uncompressedByteSize, - CompressedByteSize: compressedByteSize, - }) - s.mu.Unlock() -} - -// AddMessageReceiveEvent adds a message receive event to the span. -// -// messageID is an identifier for the message, which is recommended to be -// unique in this span and the same between the send event and the receive -// event (this allows to identify a message between the sender and receiver). -// For example, this could be a sequence id. -func (s *span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) { - if !s.IsRecordingEvents() { - return - } - now := time.Now() - s.mu.Lock() - s.messageEvents.add(MessageEvent{ - Time: now, - EventType: MessageEventTypeRecv, - MessageID: messageID, - UncompressedByteSize: uncompressedByteSize, - CompressedByteSize: compressedByteSize, - }) - s.mu.Unlock() -} - -// AddLink adds a link to the span. -func (s *span) AddLink(l Link) { - if !s.IsRecordingEvents() { - return - } - s.mu.Lock() - s.links.add(l) - s.mu.Unlock() -} - -func (s *span) String() string { - if s == nil { - return "" - } - if s.data == nil { - return fmt.Sprintf("span %s", s.spanContext.SpanID) - } - s.mu.Lock() - str := fmt.Sprintf("span %s %q", s.spanContext.SpanID, s.data.Name) - s.mu.Unlock() - return str -} - -var config atomic.Value // access atomically - -func init() { - config.Store(&Config{ - DefaultSampler: ProbabilitySampler(defaultSamplingProbability), - IDGenerator: &defaultIDGenerator{}, - MaxAttributesPerSpan: DefaultMaxAttributesPerSpan, - MaxAnnotationEventsPerSpan: DefaultMaxAnnotationEventsPerSpan, - MaxMessageEventsPerSpan: DefaultMaxMessageEventsPerSpan, - MaxLinksPerSpan: DefaultMaxLinksPerSpan, - }) -} - -type defaultIDGenerator struct { - sync.Mutex - - // Please keep these as the first fields - // so that these 8 byte fields will be aligned on addresses - // divisible by 8, on both 32-bit and 64-bit machines when - // performing atomic increments and accesses. - // See: - // * https://github.com/census-instrumentation/opencensus-go/issues/587 - // * https://github.com/census-instrumentation/opencensus-go/issues/865 - // * https://golang.org/pkg/sync/atomic/#pkg-note-BUG - nextSpanID uint64 - spanIDInc uint64 - - traceIDAdd [2]uint64 - traceIDRand *rand.Rand - - initOnce sync.Once -} - -// init initializes the generator on the first call to avoid consuming entropy -// unnecessarily. -func (gen *defaultIDGenerator) init() { - gen.initOnce.Do(func() { - // initialize traceID and spanID generators. - var rngSeed int64 - for _, p := range []interface{}{ - &rngSeed, &gen.traceIDAdd, &gen.nextSpanID, &gen.spanIDInc, - } { - binary.Read(crand.Reader, binary.LittleEndian, p) - } - gen.traceIDRand = rand.New(rand.NewSource(rngSeed)) - gen.spanIDInc |= 1 - }) -} - -// NewSpanID returns a non-zero span ID from a randomly-chosen sequence. -func (gen *defaultIDGenerator) NewSpanID() [8]byte { - var id uint64 - for id == 0 { - id = atomic.AddUint64(&gen.nextSpanID, gen.spanIDInc) - } - var sid [8]byte - binary.LittleEndian.PutUint64(sid[:], id) - return sid -} - -// NewTraceID returns a non-zero trace ID from a randomly-chosen sequence. -// mu should be held while this function is called. -func (gen *defaultIDGenerator) NewTraceID() [16]byte { - var tid [16]byte - // Construct the trace ID from two outputs of traceIDRand, with a constant - // added to each half for additional entropy. - gen.Lock() - binary.LittleEndian.PutUint64(tid[0:8], gen.traceIDRand.Uint64()+gen.traceIDAdd[0]) - binary.LittleEndian.PutUint64(tid[8:16], gen.traceIDRand.Uint64()+gen.traceIDAdd[1]) - gen.Unlock() - return tid -} diff --git a/vendor/go.opencensus.io/trace/trace_api.go b/vendor/go.opencensus.io/trace/trace_api.go deleted file mode 100644 index 9e2c3a999..000000000 --- a/vendor/go.opencensus.io/trace/trace_api.go +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2020, OpenCensus 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. - -package trace - -import ( - "context" -) - -// DefaultTracer is the tracer used when package-level exported functions are invoked. -var DefaultTracer Tracer = &tracer{} - -// Tracer can start spans and access context functions. -type Tracer interface { - - // StartSpan starts a new child span of the current span in the context. If - // there is no span in the context, creates a new trace and span. - // - // Returned context contains the newly created span. You can use it to - // propagate the returned span in process. - StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) - - // StartSpanWithRemoteParent starts a new child span of the span from the given parent. - // - // If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is - // preferred for cases where the parent is propagated via an incoming request. - // - // Returned context contains the newly created span. You can use it to - // propagate the returned span in process. - StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) - - // FromContext returns the Span stored in a context, or nil if there isn't one. - FromContext(ctx context.Context) *Span - - // NewContext returns a new context with the given Span attached. - NewContext(parent context.Context, s *Span) context.Context -} - -// StartSpan starts a new child span of the current span in the context. If -// there is no span in the context, creates a new trace and span. -// -// Returned context contains the newly created span. You can use it to -// propagate the returned span in process. -func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) { - return DefaultTracer.StartSpan(ctx, name, o...) -} - -// StartSpanWithRemoteParent starts a new child span of the span from the given parent. -// -// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is -// preferred for cases where the parent is propagated via an incoming request. -// -// Returned context contains the newly created span. You can use it to -// propagate the returned span in process. -func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) { - return DefaultTracer.StartSpanWithRemoteParent(ctx, name, parent, o...) -} - -// FromContext returns the Span stored in a context, or a Span that is not -// recording events if there isn't one. -func FromContext(ctx context.Context) *Span { - return DefaultTracer.FromContext(ctx) -} - -// NewContext returns a new context with the given Span attached. -func NewContext(parent context.Context, s *Span) context.Context { - return DefaultTracer.NewContext(parent, s) -} - -// SpanInterface represents a span of a trace. It has an associated SpanContext, and -// stores data accumulated while the span is active. -// -// Ideally users should interact with Spans by calling the functions in this -// package that take a Context parameter. -type SpanInterface interface { - - // IsRecordingEvents returns true if events are being recorded for this span. - // Use this check to avoid computing expensive annotations when they will never - // be used. - IsRecordingEvents() bool - - // End ends the span. - End() - - // SpanContext returns the SpanContext of the span. - SpanContext() SpanContext - - // SetName sets the name of the span, if it is recording events. - SetName(name string) - - // SetStatus sets the status of the span, if it is recording events. - SetStatus(status Status) - - // AddAttributes sets attributes in the span. - // - // Existing attributes whose keys appear in the attributes parameter are overwritten. - AddAttributes(attributes ...Attribute) - - // Annotate adds an annotation with attributes. - // Attributes can be nil. - Annotate(attributes []Attribute, str string) - - // Annotatef adds an annotation with attributes. - Annotatef(attributes []Attribute, format string, a ...interface{}) - - // AddMessageSendEvent adds a message send event to the span. - // - // messageID is an identifier for the message, which is recommended to be - // unique in this span and the same between the send event and the receive - // event (this allows to identify a message between the sender and receiver). - // For example, this could be a sequence id. - AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) - - // AddMessageReceiveEvent adds a message receive event to the span. - // - // messageID is an identifier for the message, which is recommended to be - // unique in this span and the same between the send event and the receive - // event (this allows to identify a message between the sender and receiver). - // For example, this could be a sequence id. - AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) - - // AddLink adds a link to the span. - AddLink(l Link) - - // String prints a string representation of a span. - String() string -} - -// NewSpan is a convenience function for creating a *Span out of a *span -func NewSpan(s SpanInterface) *Span { - return &Span{internal: s} -} - -// Span is a struct wrapper around the SpanInt interface, which allows correctly handling -// nil spans, while also allowing the SpanInterface implementation to be swapped out. -type Span struct { - internal SpanInterface -} - -// Internal returns the underlying implementation of the Span -func (s *Span) Internal() SpanInterface { - return s.internal -} - -// IsRecordingEvents returns true if events are being recorded for this span. -// Use this check to avoid computing expensive annotations when they will never -// be used. -func (s *Span) IsRecordingEvents() bool { - if s == nil { - return false - } - return s.internal.IsRecordingEvents() -} - -// End ends the span. -func (s *Span) End() { - if s == nil { - return - } - s.internal.End() -} - -// SpanContext returns the SpanContext of the span. -func (s *Span) SpanContext() SpanContext { - if s == nil { - return SpanContext{} - } - return s.internal.SpanContext() -} - -// SetName sets the name of the span, if it is recording events. -func (s *Span) SetName(name string) { - if !s.IsRecordingEvents() { - return - } - s.internal.SetName(name) -} - -// SetStatus sets the status of the span, if it is recording events. -func (s *Span) SetStatus(status Status) { - if !s.IsRecordingEvents() { - return - } - s.internal.SetStatus(status) -} - -// AddAttributes sets attributes in the span. -// -// Existing attributes whose keys appear in the attributes parameter are overwritten. -func (s *Span) AddAttributes(attributes ...Attribute) { - if !s.IsRecordingEvents() { - return - } - s.internal.AddAttributes(attributes...) -} - -// Annotate adds an annotation with attributes. -// Attributes can be nil. -func (s *Span) Annotate(attributes []Attribute, str string) { - if !s.IsRecordingEvents() { - return - } - s.internal.Annotate(attributes, str) -} - -// Annotatef adds an annotation with attributes. -func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) { - if !s.IsRecordingEvents() { - return - } - s.internal.Annotatef(attributes, format, a...) -} - -// AddMessageSendEvent adds a message send event to the span. -// -// messageID is an identifier for the message, which is recommended to be -// unique in this span and the same between the send event and the receive -// event (this allows to identify a message between the sender and receiver). -// For example, this could be a sequence id. -func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) { - if !s.IsRecordingEvents() { - return - } - s.internal.AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize) -} - -// AddMessageReceiveEvent adds a message receive event to the span. -// -// messageID is an identifier for the message, which is recommended to be -// unique in this span and the same between the send event and the receive -// event (this allows to identify a message between the sender and receiver). -// For example, this could be a sequence id. -func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) { - if !s.IsRecordingEvents() { - return - } - s.internal.AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize) -} - -// AddLink adds a link to the span. -func (s *Span) AddLink(l Link) { - if !s.IsRecordingEvents() { - return - } - s.internal.AddLink(l) -} - -// String prints a string representation of a span. -func (s *Span) String() string { - if s == nil { - return "" - } - return s.internal.String() -} diff --git a/vendor/go.opencensus.io/trace/trace_go11.go b/vendor/go.opencensus.io/trace/trace_go11.go deleted file mode 100644 index b8fc1e495..000000000 --- a/vendor/go.opencensus.io/trace/trace_go11.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2018, OpenCensus 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.11 -// +build go1.11 - -package trace - -import ( - "context" - t "runtime/trace" -) - -func startExecutionTracerTask(ctx context.Context, name string) (context.Context, func()) { - if !t.IsEnabled() { - // Avoid additional overhead if - // runtime/trace is not enabled. - return ctx, func() {} - } - nctx, task := t.NewTask(ctx, name) - return nctx, task.End -} diff --git a/vendor/go.opencensus.io/trace/trace_nongo11.go b/vendor/go.opencensus.io/trace/trace_nongo11.go deleted file mode 100644 index da488fc87..000000000 --- a/vendor/go.opencensus.io/trace/trace_nongo11.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018, OpenCensus 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.11 -// +build !go1.11 - -package trace - -import ( - "context" -) - -func startExecutionTracerTask(ctx context.Context, name string) (context.Context, func()) { - return ctx, func() {} -} diff --git a/vendor/go.opencensus.io/trace/tracestate/tracestate.go b/vendor/go.opencensus.io/trace/tracestate/tracestate.go deleted file mode 100644 index 2d6c713eb..000000000 --- a/vendor/go.opencensus.io/trace/tracestate/tracestate.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2018, OpenCensus 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. - -// Package tracestate implements support for the Tracestate header of the -// W3C TraceContext propagation format. -package tracestate - -import ( - "fmt" - "regexp" -) - -const ( - keyMaxSize = 256 - valueMaxSize = 256 - maxKeyValuePairs = 32 -) - -const ( - keyWithoutVendorFormat = `[a-z][_0-9a-z\-\*\/]{0,255}` - keyWithVendorFormat = `[a-z][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}` - keyFormat = `(` + keyWithoutVendorFormat + `)|(` + keyWithVendorFormat + `)` - valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]` -) - -var keyValidationRegExp = regexp.MustCompile(`^(` + keyFormat + `)$`) -var valueValidationRegExp = regexp.MustCompile(`^(` + valueFormat + `)$`) - -// Tracestate represents tracing-system specific context in a list of key-value pairs. Tracestate allows different -// vendors propagate additional information and inter-operate with their legacy Id formats. -type Tracestate struct { - entries []Entry -} - -// Entry represents one key-value pair in a list of key-value pair of Tracestate. -type Entry struct { - // Key is an opaque string up to 256 characters printable. It MUST begin with a lowercase letter, - // and can only contain lowercase letters a-z, digits 0-9, underscores _, dashes -, asterisks *, and - // forward slashes /. - Key string - - // Value is an opaque string up to 256 characters printable ASCII RFC0020 characters (i.e., the - // range 0x20 to 0x7E) except comma , and =. - Value string -} - -// Entries returns a slice of Entry. -func (ts *Tracestate) Entries() []Entry { - if ts == nil { - return nil - } - return ts.entries -} - -func (ts *Tracestate) remove(key string) *Entry { - for index, entry := range ts.entries { - if entry.Key == key { - ts.entries = append(ts.entries[:index], ts.entries[index+1:]...) - return &entry - } - } - return nil -} - -func (ts *Tracestate) add(entries []Entry) error { - for _, entry := range entries { - ts.remove(entry.Key) - } - if len(ts.entries)+len(entries) > maxKeyValuePairs { - return fmt.Errorf("adding %d key-value pairs to current %d pairs exceeds the limit of %d", - len(entries), len(ts.entries), maxKeyValuePairs) - } - ts.entries = append(entries, ts.entries...) - return nil -} - -func isValid(entry Entry) bool { - return keyValidationRegExp.MatchString(entry.Key) && - valueValidationRegExp.MatchString(entry.Value) -} - -func containsDuplicateKey(entries ...Entry) (string, bool) { - keyMap := make(map[string]int) - for _, entry := range entries { - if _, ok := keyMap[entry.Key]; ok { - return entry.Key, true - } - keyMap[entry.Key] = 1 - } - return "", false -} - -func areEntriesValid(entries ...Entry) (*Entry, bool) { - for _, entry := range entries { - if !isValid(entry) { - return &entry, false - } - } - return nil, true -} - -// New creates a Tracestate object from a parent and/or entries (key-value pair). -// Entries from the parent are copied if present. The entries passed to this function -// are inserted in front of those copied from the parent. If an entry copied from the -// parent contains the same key as one of the entry in entries then the entry copied -// from the parent is removed. See add func. -// -// An error is returned with nil Tracestate if -// 1. one or more entry in entries is invalid. -// 2. two or more entries in the input entries have the same key. -// 3. the number of entries combined from the parent and the input entries exceeds maxKeyValuePairs. -// (duplicate entry is counted only once). -func New(parent *Tracestate, entries ...Entry) (*Tracestate, error) { - if parent == nil && len(entries) == 0 { - return nil, nil - } - if entry, ok := areEntriesValid(entries...); !ok { - return nil, fmt.Errorf("key-value pair {%s, %s} is invalid", entry.Key, entry.Value) - } - - if key, duplicate := containsDuplicateKey(entries...); duplicate { - return nil, fmt.Errorf("contains duplicate keys (%s)", key) - } - - tracestate := Tracestate{} - - if parent != nil && len(parent.entries) > 0 { - tracestate.entries = append([]Entry{}, parent.entries...) - } - - err := tracestate.add(entries) - if err != nil { - return nil, err - } - return &tracestate, nil -} 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 e8ce5978a..7ba1b654f 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,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 ( "context" 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 b8b836b00..353e288bb 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 7bab8da8f..c8065028e 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,21 +1,62 @@ // 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://opentelemetry.io/docs/specs/semconv/rpc/ import ( "net" + "net/url" "strconv" + "strings" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" grpc_codes "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) +// 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.: +// +// 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), + } + } + } + // 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)} + } + 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, "/") + } + if ep == "" { + ep = u.Opaque + } + if ep != "" { + return serverAddrAttrs(ep) + } + return []attribute.KeyValue{semconv.ServerAddress(target)} +} + // serverAddrAttrs returns the server address attributes for the hostport. func serverAddrAttrs(hostport string) []attribute.KeyValue { h, pStr, err := net.SplitHostPort(hostport) 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 b62f7cd7c..7a3083f3c 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 97616c535..aa4bbfa4a 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,14 +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" 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.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) // ParseFullMethod returns a span name following the OpenTelemetry semantic 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 4c62341d6..6651e8bd8 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,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 ( "context" 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 f8d254df3..1d0fc0622 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,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 ( "context" @@ -13,8 +13,8 @@ import ( "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" 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.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/rpcconv" + 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" @@ -26,6 +26,11 @@ import ( 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 { metricAttrs []attribute.KeyValue record bool @@ -328,6 +333,20 @@ func (*config) handleRPC( switch rs := rs.(type) { case *stats.Begin: + // 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...) + } + } + } case *stats.InPayload: case *stats.InHeader: if !rs.Client && rs.LocalAddr != nil { @@ -339,13 +358,18 @@ func (*config) handleRPC( case *stats.OutPayload: case *stats.OutTrailer: case *stats.OutHeader: + // 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) { - attrs := serverAddrAttrs(rs.RemoteAddr.String()) - if span.IsRecording() { - span.SetAttributes(attrs...) - } - if gctx != nil { - gctx.metricAttrs = append(gctx.metricAttrs, attrs...) + 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: 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 1f5996cc0..23fda6f50 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,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 // Version is the current release version of the gRPC instrumentation. -const Version = "0.69.0" +const Version = "0.70.0" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/api.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/api.go index 71c528e5b..3016ee6a9 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/api.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/api.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttptrace // import "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace" +package otelhttptrace import ( "context" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go index 2ad6c7cc8..f7f152510 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/clienttrace.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttptrace // import "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace" +package otelhttptrace import ( "context" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/httptrace.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/httptrace.go index 549494192..dc306b1b2 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/httptrace.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/httptrace.go @@ -3,7 +3,7 @@ // Package otelhttptrace provides instrumentation for the [net/http/httptrace] // package. -package otelhttptrace // import "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace" +package otelhttptrace import ( "context" diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/client.go index d88cd079d..c275b5f05 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/client.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/client.go @@ -1,12 +1,12 @@ -// 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/httptrace/otelhttptrace/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.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/httpconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/httpconv" ) type HTTPClient struct { @@ -45,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) } @@ -120,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)) } @@ -138,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 { @@ -153,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)) @@ -162,10 +177,17 @@ 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.HTTPRequestMethodOther, attribute.KeyValue{} } @@ -180,7 +202,7 @@ func (n HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValu 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 { @@ -200,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++ } @@ -213,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), @@ -249,7 +279,7 @@ 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)) } @@ -269,12 +299,12 @@ func (n HTTPClient) MetricOptions(ma MetricAttributes) MetricOpts { // 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 (n HTTPClient) ErrorType(err error) attribute.KeyValue { +func (HTTPClient) ErrorType(err error) attribute.KeyValue { t := reflect.TypeOf(err) if t == nil { return semconv.ErrorTypeOther } - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } var value string @@ -307,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/httptrace/otelhttptrace/internal/semconv/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/gen.go index d6aed214e..15dd69337 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/gen.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/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/httptrace/otelhttptrace/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/httptrace/otelhttptrace\" }" --out=bench_test.go diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/server.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/server.go index a50124078..35e744e41 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/server.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/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/httptrace/otelhttptrace/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.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.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,7 +240,11 @@ 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 @@ -274,7 +279,7 @@ func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { // 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 (n HTTPServer) SpanName(r *http.Request) string { +func (HTTPServer) SpanName(r *http.Request) string { method := strings.ToUpper(r.Method) if _, ok := methodLookup[method]; !ok { method = "HTTP" @@ -287,7 +292,7 @@ func (n HTTPServer) SpanName(r *http.Request) string { return method } -func (n HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { +func (HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { if method == "" { return semconv.HTTPRequestMethodOther, attribute.KeyValue{} } @@ -314,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 { @@ -330,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), ) } @@ -349,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/httptrace/otelhttptrace/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/util.go index 88b67003c..0de0bd83c 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/internal/semconv/util.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/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/httptrace/otelhttptrace/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.41.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/httptrace/otelhttptrace/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/version.go index f38ce8da3..5a98937f1 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/version.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelhttptrace // import "go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace" +package otelhttptrace // Version is the current release version of the httptrace instrumentation. -const Version = "0.69.0" +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 3ae082434..733b75dca 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 a7d4b2a81..08ba0778f 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 1c9aa3ff4..09a2103fe 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 204588b84..844363a09 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" 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 d032aa841..aeff41604 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 9e00dd2fc..98f7bdbfc 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 f29f9b7c9..6b523cb74 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 0241b08e8..c275b5f05 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,12 +1,12 @@ -// 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" @@ -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.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.0/httpconv" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" + "go.opentelemetry.io/otel/semconv/v1.43.0/httpconv" ) type HTTPClient struct { @@ -45,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) } @@ -120,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)) } @@ -138,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 { @@ -153,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)) @@ -162,10 +177,17 @@ 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.HTTPRequestMethodOther, attribute.KeyValue{} } @@ -180,7 +202,7 @@ func (n HTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValu 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 { @@ -200,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++ } @@ -213,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), @@ -249,7 +279,7 @@ 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)) } @@ -269,12 +299,12 @@ func (n HTTPClient) MetricOptions(ma MetricAttributes) MetricOpts { // 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 (n HTTPClient) ErrorType(err error) attribute.KeyValue { +func (HTTPClient) ErrorType(err error) attribute.KeyValue { t := reflect.TypeOf(err) if t == nil { return semconv.ErrorTypeOther } - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } var value string @@ -307,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 a8a0d58df..fbcd4f6b2 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 8e0430863..35e744e41 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.41.0" - "go.opentelemetry.io/otel/semconv/v1.41.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,7 +240,11 @@ 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 @@ -274,7 +279,7 @@ func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) { // 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 (n HTTPServer) SpanName(r *http.Request) string { +func (HTTPServer) SpanName(r *http.Request) string { method := strings.ToUpper(r.Method) if _, ok := methodLookup[method]; !ok { method = "HTTP" @@ -287,7 +292,7 @@ func (n HTTPServer) SpanName(r *http.Request) string { return method } -func (n HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { +func (HTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) { if method == "" { return semconv.HTTPRequestMethodOther, attribute.KeyValue{} } @@ -314,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 { @@ -330,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), ) } @@ -349,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 d6842ed2a..0de0bd83c 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.41.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 d62ce44b0..8362b8246 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 9476ef01b..9b6c0a889 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 b15895cee..82501eab3 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.41.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,6 +164,7 @@ 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)...), @@ -183,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 2feb88500..b757d6e9d 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.69.0" +const Version = "0.70.0" diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index 645c7e6af..8a7f1ec5d 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -96,9 +96,9 @@ linters: - "!**/exporters/zipkin/**" deny: - pkg: go.opentelemetry.io/otel/semconv - desc: "Use go.opentelemetry.io/otel/semconv/v1.41.0 instead. If a newer semconv version has been released, update the depguard rule." + desc: "Use go.opentelemetry.io/otel/semconv/v1.43.0 instead. If a newer semconv version has been released, update the depguard rule." allow: - - go.opentelemetry.io/otel/semconv/v1.41.0 + - go.opentelemetry.io/otel/semconv/v1.43.0 gocritic: disabled-checks: - appendAssign diff --git a/vendor/go.opentelemetry.io/otel/.lycheeignore b/vendor/go.opentelemetry.io/otel/.lycheeignore index 994b677df..df0d328bf 100644 --- a/vendor/go.opentelemetry.io/otel/.lycheeignore +++ b/vendor/go.opentelemetry.io/otel/.lycheeignore @@ -11,3 +11,17 @@ http://4.3.2.1:78/user/123 file:///home/runner/work/opentelemetry-go/opentelemetry-go/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/dns:/:4317 # URL works, but it has blocked link checkers. https://dl.acm.org/doi/10.1145/198429.198435 +https://pkg.go.dev/google.golang.org/grpc.*internal/resolver +https://golang.org/src/crypto/tls/generate_cert.go +https://github.com/grpc/grpc/blob/.*/doc/naming.md +https://github.com/open-telemetry/opentelemetry-specification/blob/.* +# Fake domains used in otlp options_test.go tests +https?://env\.endpoint.* +https?://env\.metrics\.endpoint.* +https?://env_metrics_endpoint.* +https?://env\.traces\.endpoint.* +https?://env_traces_endpoint.* +https?://someendpoint.* +https?://overrode\.by\.signal\.specific.* +https?://overrode_by_signal_specific.* +https?://proxy\.com.* diff --git a/vendor/go.opentelemetry.io/otel/AGENTS.md b/vendor/go.opentelemetry.io/otel/AGENTS.md index 26c0fc4dd..02db71528 100644 --- a/vendor/go.opentelemetry.io/otel/AGENTS.md +++ b/vendor/go.opentelemetry.io/otel/AGENTS.md @@ -47,6 +47,9 @@ For docs-only, test-only, or review-only tasks, still start with the required re - Prefer examples over long code snippets in GoDoc when practical. - Keep docs aligned with actual behavior. Do not leave stale comments, stale examples, or stale package documentation behind. - For user-visible changes, update `CHANGELOG.md` under the appropriate `Added`, `Changed`, `Deprecated`, `Fixed`, or `Removed` section within `## [Unreleased]`. + - Always put the PR number at the end of the line (e.g., `(#1234)`), NOT the issue number. + - If the PR number is not yet known, omit it until the PR is created, then update the changelog entry before merging. + - Always use references to the go module that is updated (e.g., `go.opentelemetry.io/otel/sdk/metric`), instead of just the path (e.g., `sdk/metric`). ## Repository habits diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 6a90451f5..2db588ea2 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -11,6 +11,75 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +## [1.45.0/0.67.0/0.21.0/0.0.18] - 2026-08-03 + +### Added + +- Add experimental observability metrics to `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log`. (#7124) +- Add the experimental `WithUnsafeAttributes` no-copy attribute option to `go.opentelemetry.io/otel/metric/x` for future performance improvements. This API is a work in progress. (#8251) +- Add `Map` and `MapValue` functions for the new `MAP` attribute type in `go.opentelemetry.io/otel/attribute`. (#8445) +- Support `MAP` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8453) +- Support `MAP` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8453) +- Support `MAP` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8453) +- Support `MAP` attributes in `go.opentelemetry.io/otel/exporters/zipkin`. (#8453) +- Apply `AttributeValueLengthLimit` recursively to values contained in `attribute.MAP` attributes in `go.opentelemetry.io/otel/sdk/trace`. (#8454) +- Remove duplicate keys from `attribute.MAP` values in `go.opentelemetry.io/otel/sdk/resource` using last-value-wins semantics. (#8471) +- Remove duplicate keys by default from `attribute.MAP` values in instrumentation scope attributes in `go.opentelemetry.io/otel/sdk/log` using last-value-wins semantics. (#8471) +- Remove duplicate keys by default from `attribute.MAP` values in span, event, link, and instrumentation scope attributes in `go.opentelemetry.io/otel/sdk/trace` using last-value-wins semantics. (#8471) +- Remove duplicate keys by default from `attribute.MAP` values in measurement and instrumentation scope attributes in `go.opentelemetry.io/otel/sdk/metric` using last-value-wins semantics. (#8471) +- Extend `WithAllowKeyDuplication` in `go.opentelemetry.io/otel/sdk/log` to disable duplicate-key removal in `attribute.MAP` values for instrumentation scope attributes. (#8471) +- Add the `go.opentelemetry.io/otel/semconv/v1.42.0` package. + The package contains semantic conventions from the `v1.42.0` version of the OpenTelemetry Semantic Conventions. + See the [migration documentation](./semconv/v1.42.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.41.0`. (#8484) +- Add `WithoutPanicRecording` as a `TracerProviderOption` in `go.opentelemetry.io/otel/sdk/trace` to disable exception event recording for panics. (#8532) +- Add the `go.opentelemetry.io/otel/semconv/v1.43.0` package. + The package contains semantic conventions from the `v1.43.0` version of the OpenTelemetry Semantic Conventions. + See the [migration documentation](./semconv/v1.43.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.42.0`. (#8628) + +### Changed + +- `HistogramReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` now uses a time-unbiased sampling algorithm for exemplars. (#8306) +- ⚠️ **Breaking Change:** Use `go.opentelemetry.io/otel/attribute.Value` and `go.opentelemetry.io/otel/attribute.KeyValue` for log bodies and attributes in `go.opentelemetry.io/otel/log`, `go.opentelemetry.io/otel/log/logtest`, `go.opentelemetry.io/otel/sdk/log`, and `go.opentelemetry.io/otel/sdk/log/logtest`. (#8490) +- Encode log bodies and attributes as `go.opentelemetry.io/otel/attribute.Value` JSON in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. (#8490) +- Improve the performance of hashing `BOOLSLICE`, `INT64SLICE`, `FLOAT64SLICE`, and `STRINGSLICE` attribute values by avoiding reflection for short slices in `go.opentelemetry.io/otel/attribute`. (#8511) +- ⚠️ **Breaking Change:** `WithEndpointURL` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` no longer appends the default signal path when an endpoint URL has no path, making the behavior consistent with `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` and with setting the endpoint through `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`. If the URL has no path component, the root path (`/`) is used. Use `WithEndpointURL(url.JoinPath(endpoint, "/v1/metrics"))` to preserve the previous behavior. (#8538) +- ⚠️ **Breaking Change:** `WithEndpointURL` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` no longer appends the default signal path when an endpoint URL has no path, making the behavior consistent with `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` and with setting the endpoint through `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`. If the URL has no path component, the root path (`/`) is used. Use `WithEndpointURL(url.JoinPath(endpoint, "/v1/traces"))` to preserve the previous behavior. (#8538) + +### Deprecated + +- Deprecate `WithExportBufferSize` in `go.opentelemetry.io/otel/sdk/log`. The option remains available for source compatibility but no longer affects behavior; `BatchProcessor` no longer maintains a separate export-request buffer. (#8620) + +### Removed + +- ⚠️ **Breaking Change:** Remove `Kind`, `Value`, `KeyValue`, their constructors, and attribute conversion helpers from `go.opentelemetry.io/otel/log`. (#8490) +- ⚠️ **Breaking Change:** Remove the `AttributeValueLengthLimit` and `AttributeCountLimit` fields from `RecordFactory` in `go.opentelemetry.io/otel/sdk/log/logtest`; records produced by the factory now keep attribute limits disabled so test code can append exact attributes. (#8556) + +### Fixed + +- Apply TLS certificates configured through environment variables to gRPC connections in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. +- Prevent panics in `go.opentelemetry.io/otel/bridge/opentracing` when OpenTracing baggage is propagated concurrently with `Span.SetBaggageItem`. +- Fix an off-by-one error in `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` that prevented the first exemplar from being sampled after the reservoir was filled. (#8309) +- Interpret HTTP `Retry-After` header values as seconds instead of nanoseconds when retrying OTLP HTTP exports in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8383) +- Fix a memory leak in the `Reservoir` implementation in `go.opentelemetry.io/otel/sdk/metric/exemplar`, where storing the full `context.Context` pinned large objects such as gRPC transport buffers. (#8389) +- Prevent a non-empty attribute set whose computed hash is zero from collapsing to an empty set in `go.opentelemetry.io/otel/attribute`. (#8402) +- Fix histogram data point reuse in `go.opentelemetry.io/otel/sdk/metric` aggregation to avoid leaking stale sum, minimum, and maximum values when they are disabled in subsequent collections. (#8403) +- Avoid preallocating scope attributes when they are disabled in `go.opentelemetry.io/otel/exporters/prometheus`. (#8404) +- Support HTTP-date values in the HTTP `Retry-After` header when retrying OTLP HTTP exports in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8417) +- Reduce histogram heap allocations by reusing `BucketCounts` and `Exemplars` slices across `Collect` cycles in the cumulative histogram aggregation in `go.opentelemetry.io/otel/sdk/metric`. (#8428) +- Fix `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` self-observability to record `error.type` on the operation-duration histogram when the `exportedSpans` metric is disabled. (#8432) +- Stop including trace exporter endpoint configuration in internal logs from `go.opentelemetry.io/otel/sdk/trace`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, and `go.opentelemetry.io/otel/exporters/zipkin`. (#8438) +- Fix invalid error formatting for out-of-range JSON code values in `go.opentelemetry.io/otel/codes`. (#8497) +- Clarify in `go.opentelemetry.io/otel/log` that `Logger.Enabled` should be checked for every log emission because its result may change over time. (#8565) +- Preserve user-provided exception attributes while independently deriving missing exception message and type attributes in `go.opentelemetry.io/otel/sdk/log`. (#8566) +- Make `WithAttributeCountLimit(0)` and `OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT=0` discard all log record attributes in `go.opentelemetry.io/otel/sdk/log`. (#8570) +- Clarify that the `Record` methods of `Float64Histogram` and `Int64Histogram` in `go.opentelemetry.io/otel/metric` expect non-negative values. (#8574) +- Clarify in `go.opentelemetry.io/otel/log` that `LoggerProvider` implementations should retain an empty `Logger` name instead of replacing it with a default. (#8587) +- Ensure that the built-in processors in `go.opentelemetry.io/otel/sdk/log` call exporter `ForceFlush` during `Shutdown`. (#8599) +- Prevent processor operations in `go.opentelemetry.io/otel/sdk/log` from overlapping with processor shutdown or running after `LoggerProvider` shutdown. (#8608) +- Prevent `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` from busy-spinning under exporter backpressure and serialize dequeue, export, force-flush, and shutdown work in one worker. (#8620) +- Make `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` return errors encountered while draining records during `ForceFlush` and `Shutdown`, while continuing to attempt later batches as long as the request context remains valid. (#8620) +- Keep the default `BatchProcessor` maximum export batch size in `go.opentelemetry.io/otel/sdk/log` at or below the configured maximum queue size. (#8620) + ## [1.44.0/0.66.0/0.20.0/0.0.17] 2026-05-27 ### Added @@ -42,13 +111,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Set `OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE=` to enable for all periodic readers. See `go.opentelemetry.io/otel/sdk/metric/internal/x` for feature documentation. (#8071) - Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. - Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable. + Enable with `OTEL_GO_X_OBSERVABILITY=true` environment variable. See `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x` for feature documentation. (#8192) - Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. - Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable. + Enable with `OTEL_GO_X_OBSERVABILITY=true` environment variable. See `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x` for feature documentation. (#8194) - Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. - Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable. + Enable with `OTEL_GO_X_OBSERVABILITY=true` environment variable. See `go.opentelemetry.io/otel/stdout/stdoutlog/internal/x` for feature documentation. (#8263) - Add `WithDefaultAttributes` to `go.opentelemetry.io/otel/metric/x` to support setting default attributes on instruments. (#8135) - Add `go.opentelemetry.io/otel/semconv/v1.41.0` package. @@ -3713,7 +3782,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.44.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.45.0...HEAD +[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 [1.42.0/0.64.0/0.18.0/0.0.16]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.42.0 diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md index 3ec17d683..2aba71e19 100644 --- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md +++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md @@ -8,8 +8,10 @@ repo for information on this and other language SIGs. See the [public meeting notes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit) for a summary description of past meetings. To request edit access, -join the meeting or get in touch on -[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT). +join the meeting or get in touch on the +[#otel-go](https://cloud-native.slack.com/archives/C01NPAXACKT) +channel on CNCF Slack. If you are new to the CNCF Slack community, +you can [create an account](https://slack.cncf.io/). The meeting is open for all to join. We invite everyone to join our meeting, regardless of your experience level. Whether you're a @@ -752,8 +754,8 @@ Encapsulate setup in constructor functions, ensuring clear ownership and scope: import ( "errors" - 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" ) type SDKComponent struct { @@ -1054,7 +1056,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) All observability metrics should follow the [OpenTelemetry Semantic Conventions for SDK metrics](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/otel/sdk-metrics.md). -Use the metric semantic conventions convenience package [otelconv](./semconv/v1.41.0/otelconv/metric.go). +Use the metric semantic conventions convenience package [otelconv](./semconv/v1.43.0/otelconv/metric.go). ##### Component Identification diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index de63a5e9b..d4711257d 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -10,6 +10,7 @@ ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} GO = go TIMEOUT = 60 +GO_VERSION := $(shell awk '/^go [0-9]/ {print $$2; exit}' go.mod) # User to run as in docker images. DOCKER_USER=$(shell id -u):$(shell id -g) @@ -19,7 +20,7 @@ DEPENDENCIES_DOCKERFILE=./dependencies.Dockerfile .PHONY: precommit ci precommit: generate toolchain-check license-check misspell go-mod-tidy golangci-lint-fix verify-readmes verify-mods test-default -ci: generate toolchain-check license-check lint vanity-import-check verify-readmes verify-mods build test-default check-clean-work-tree test-coverage +ci: generate toolchain-check license-check lint verify-readmes verify-mods build test-default check-clean-work-tree test-coverage # Tools @@ -59,9 +60,6 @@ $(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge STRINGER = $(TOOLS)/stringer $(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer -PORTO = $(TOOLS)/porto -$(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto - GOTMPL = $(TOOLS)/gotmpl $(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl @@ -72,7 +70,7 @@ GOVULNCHECK = $(TOOLS)/govulncheck $(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck .PHONY: tools -tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) +tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) # Virtualized python tools via docker @@ -110,7 +108,7 @@ $(CODESPELL): PACKAGE=codespell # Generate .PHONY: generate -generate: go-generate vanity-import-fix +generate: go-generate .PHONY: go-generate go-generate: $(OTEL_GO_MOD_DIRS:%=go-generate/%) @@ -120,14 +118,10 @@ go-generate/%: $(STRINGER) $(GOTMPL) && cd $(DIR) \ && PATH="$(TOOLS):$${PATH}" $(GO) generate ./... -.PHONY: vanity-import-fix -vanity-import-fix: $(PORTO) - @$(PORTO) --include-internal -w . - # Generate go.work file for local development. .PHONY: go-work go-work: $(CROSSLINK) - $(CROSSLINK) work --root=$(shell pwd) --go=1.22.7 + $(CROSSLINK) work --root=$(shell pwd) --go=$(GO_VERSION) # Build @@ -228,10 +222,6 @@ go-mod-tidy/%: crosslink .PHONY: lint lint: misspell go-mod-tidy golangci-lint -.PHONY: vanity-import-check -vanity-import-check: $(PORTO) - @$(PORTO) --include-internal -l . || ( echo "(run: make vanity-import-fix)"; exit 1 ) - .PHONY: misspell misspell: $(MISSPELL) @$(MISSPELL) -w $(ALL_DOCS) diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index 16a72004c..ce97e9a25 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -113,3 +113,10 @@ All officially supported exporters for the OpenTelemetry project are contained i ## Contributing See the [contributing documentation](CONTRIBUTING.md). + +### Emeritus + +- [Alex Kats](https://github.com/akats7), Triager + +For more information about the emeritus role, see the +[community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager). diff --git a/vendor/go.opentelemetry.io/otel/attribute/doc.go b/vendor/go.opentelemetry.io/otel/attribute/doc.go index eef51ebc2..c543f2ca6 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/doc.go +++ b/vendor/go.opentelemetry.io/otel/attribute/doc.go @@ -2,4 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 // Package attribute provides key and value attributes. -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute diff --git a/vendor/go.opentelemetry.io/otel/attribute/encoder.go b/vendor/go.opentelemetry.io/otel/attribute/encoder.go index ca186d8ac..413e7a185 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/encoder.go +++ b/vendor/go.opentelemetry.io/otel/attribute/encoder.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute import ( "bytes" diff --git a/vendor/go.opentelemetry.io/otel/attribute/filter.go b/vendor/go.opentelemetry.io/otel/attribute/filter.go index 624ebbe38..6dab64f5d 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/filter.go +++ b/vendor/go.opentelemetry.io/otel/attribute/filter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute // Filter supports removing certain attributes from attribute sets. When // the filter returns true, the attribute will be kept in the filtered diff --git a/vendor/go.opentelemetry.io/otel/attribute/hash.go b/vendor/go.opentelemetry.io/otel/attribute/hash.go index 92f39ffe7..f651eb13d 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/hash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/hash.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute import ( "fmt" @@ -29,6 +29,7 @@ const ( stringSliceID uint64 = 7453010373645655387 // "[]string" (little endian) byteSliceID uint64 = 6874028470941080415 // "_[]byte_" (little endian) sliceID uint64 = 7883494272577650031 // "__slice_" (little endian) + mapID uint64 = 6872316492666199903 // "__map___" (little endian) emptyID uint64 = 7305809155345288421 // "__empty_" (little endian) ) @@ -38,7 +39,13 @@ func hashKVs(kvs []KeyValue) uint64 { for _, kv := range kvs { h = hashKV(h, kv) } - return h.Sum64() + 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 } // hashKV returns the xxHash64 hash of kv with h as the base. @@ -64,27 +71,79 @@ func hashValue(h xxhash.Hash, v Value) xxhash.Hash { h = h.String(v.stringly) case BOOLSLICE: h = h.Uint64(boolSliceID) - rv := reflect.ValueOf(v.slice) - for i := 0; i < rv.Len(); i++ { - h = h.Bool(rv.Index(i).Bool()) + switch vals := v.slice.(type) { + case [0]bool: + case [1]bool: + h = h.Bool(vals[0]) + case [2]bool: + h = h.Bool(vals[0]) + h = h.Bool(vals[1]) + case [3]bool: + h = h.Bool(vals[0]) + h = h.Bool(vals[1]) + h = h.Bool(vals[2]) + default: + rv := reflect.ValueOf(v.slice) + for i := 0; i < rv.Len(); i++ { + h = h.Bool(rv.Index(i).Bool()) + } } case INT64SLICE: h = h.Uint64(int64SliceID) - rv := reflect.ValueOf(v.slice) - for i := 0; i < rv.Len(); i++ { - h = h.Int64(rv.Index(i).Int()) + switch vals := v.slice.(type) { + case [0]int64: + case [1]int64: + h = h.Int64(vals[0]) + case [2]int64: + h = h.Int64(vals[0]) + h = h.Int64(vals[1]) + case [3]int64: + h = h.Int64(vals[0]) + h = h.Int64(vals[1]) + h = h.Int64(vals[2]) + default: + rv := reflect.ValueOf(v.slice) + for i := 0; i < rv.Len(); i++ { + h = h.Int64(rv.Index(i).Int()) + } } case FLOAT64SLICE: h = h.Uint64(float64SliceID) - rv := reflect.ValueOf(v.slice) - for i := 0; i < rv.Len(); i++ { - h = h.Float64(rv.Index(i).Float()) + switch vals := v.slice.(type) { + case [0]float64: + case [1]float64: + h = h.Float64(vals[0]) + case [2]float64: + h = h.Float64(vals[0]) + h = h.Float64(vals[1]) + case [3]float64: + h = h.Float64(vals[0]) + h = h.Float64(vals[1]) + h = h.Float64(vals[2]) + default: + rv := reflect.ValueOf(v.slice) + for i := 0; i < rv.Len(); i++ { + h = h.Float64(rv.Index(i).Float()) + } } case STRINGSLICE: h = h.Uint64(stringSliceID) - rv := reflect.ValueOf(v.slice) - for i := 0; i < rv.Len(); i++ { - h = h.String(rv.Index(i).String()) + switch vals := v.slice.(type) { + case [0]string: + case [1]string: + h = h.String(vals[0]) + case [2]string: + h = h.String(vals[0]) + h = h.String(vals[1]) + case [3]string: + h = h.String(vals[0]) + h = h.String(vals[1]) + h = h.String(vals[2]) + default: + rv := reflect.ValueOf(v.slice) + for i := 0; i < rv.Len(); i++ { + h = h.String(rv.Index(i).String()) + } } case BYTESLICE: h = h.Uint64(byteSliceID) @@ -95,21 +154,79 @@ func hashValue(h xxhash.Hash, v Value) xxhash.Hash { case [0]Value: // No values to hash, but the type identifier is still hashed above. case [1]Value: - h = hashValueSlice(h, vals[:]) + h = hashValue(h, vals[0]) case [2]Value: - h = hashValueSlice(h, vals[:]) + h = hashValue(h, vals[0]) + h = hashValue(h, vals[1]) case [3]Value: - h = hashValueSlice(h, vals[:]) + h = hashValue(h, vals[0]) + h = hashValue(h, vals[1]) + h = hashValue(h, vals[2]) case [4]Value: - h = hashValueSlice(h, vals[:]) + h = hashValue(h, vals[0]) + h = hashValue(h, vals[1]) + h = hashValue(h, vals[2]) + h = hashValue(h, vals[3]) case [5]Value: - h = hashValueSlice(h, vals[:]) + h = hashValue(h, vals[0]) + h = hashValue(h, vals[1]) + h = hashValue(h, vals[2]) + h = hashValue(h, vals[3]) + h = hashValue(h, vals[4]) default: rv := reflect.ValueOf(v.slice) for i := 0; i < rv.Len(); i++ { h = hashValue(h, rv.Index(i).Interface().(Value)) } } + case MAP: + h = h.Uint64(mapID) + switch vals := v.slice.(type) { + case [0]KeyValue: + // No values to hash, but the type identifier is still hashed above. + case [1]KeyValue: + h = h.String(string(vals[0].Key)) + h = hashValue(h, vals[0].Value) + case [2]KeyValue: + h = h.String(string(vals[0].Key)) + h = hashValue(h, vals[0].Value) + h = h.String(string(vals[1].Key)) + h = hashValue(h, vals[1].Value) + case [3]KeyValue: + h = h.String(string(vals[0].Key)) + h = hashValue(h, vals[0].Value) + h = h.String(string(vals[1].Key)) + h = hashValue(h, vals[1].Value) + h = h.String(string(vals[2].Key)) + h = hashValue(h, vals[2].Value) + case [4]KeyValue: + h = h.String(string(vals[0].Key)) + h = hashValue(h, vals[0].Value) + h = h.String(string(vals[1].Key)) + h = hashValue(h, vals[1].Value) + h = h.String(string(vals[2].Key)) + h = hashValue(h, vals[2].Value) + h = h.String(string(vals[3].Key)) + h = hashValue(h, vals[3].Value) + case [5]KeyValue: + h = h.String(string(vals[0].Key)) + h = hashValue(h, vals[0].Value) + h = h.String(string(vals[1].Key)) + h = hashValue(h, vals[1].Value) + h = h.String(string(vals[2].Key)) + h = hashValue(h, vals[2].Value) + h = h.String(string(vals[3].Key)) + h = hashValue(h, vals[3].Value) + h = h.String(string(vals[4].Key)) + h = hashValue(h, vals[4].Value) + default: + rv := reflect.ValueOf(v.slice) + for i := 0; i < rv.Len(); i++ { + kv := rv.Index(i).Interface().(KeyValue) + h = h.String(string(kv.Key)) + h = hashValue(h, kv.Value) + } + } case EMPTY: h = h.Uint64(emptyID) default: @@ -121,10 +238,3 @@ func hashValue(h xxhash.Hash, v Value) xxhash.Hash { } return h } - -func hashValueSlice(h xxhash.Hash, vals []Value) xxhash.Hash { - for _, v := range vals { - h = hashValue(h, v) - } - return h -} diff --git a/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go b/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go index d9f51fa2d..ec4a5f07f 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go +++ b/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go @@ -5,7 +5,7 @@ Package attribute provide several helper functions for some commonly used logic of processing attributes. */ -package attribute // import "go.opentelemetry.io/otel/attribute/internal" +package attribute import ( "reflect" 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 113a97838..c851179cc 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go +++ b/vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package xxhash provides a wrapper around the xxhash library for attribute hashing. -package xxhash // import "go.opentelemetry.io/otel/attribute/internal/xxhash" +package xxhash import ( "encoding/binary" diff --git a/vendor/go.opentelemetry.io/otel/attribute/iterator.go b/vendor/go.opentelemetry.io/otel/attribute/iterator.go index 8df6249f0..1afd00ff0 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/iterator.go +++ b/vendor/go.opentelemetry.io/otel/attribute/iterator.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute // Iterator allows iterating over the set of attributes in order, sorted by // key. diff --git a/vendor/go.opentelemetry.io/otel/attribute/key.go b/vendor/go.opentelemetry.io/otel/attribute/key.go index cdc7089e8..6403191c2 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/key.go +++ b/vendor/go.opentelemetry.io/otel/attribute/key.go @@ -1,16 +1,16 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute // Key represents the key part in key-value pairs. It's a string. The // allowed character set in the key depends on the use of the key. type Key string -// Bool creates a KeyValue instance with a BOOL Value. +// Bool returns a [KeyValue] for a bool value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Bool(name, value). +// If creating both a key and value at the same time, use the package-level +// [Bool] function. func (k Key) Bool(v bool) KeyValue { return KeyValue{ Key: k, @@ -18,10 +18,15 @@ func (k Key) Bool(v bool) KeyValue { } } -// BoolSlice creates a KeyValue instance with a BOOLSLICE Value. +// BoolSlice returns a [KeyValue] for a []bool value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- BoolSlice(name, value). +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [BoolSlice] function. func (k Key) BoolSlice(v []bool) KeyValue { return KeyValue{ Key: k, @@ -29,10 +34,12 @@ func (k Key) BoolSlice(v []bool) KeyValue { } } -// Int creates a KeyValue instance with an INT64 Value. +// Int returns a [KeyValue] for an int value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Int(name, value). +// It is provided as a convenience for [Key.Int64]. +// +// If creating both a key and value at the same time, use the package-level [Int] +// function. func (k Key) Int(v int) KeyValue { return KeyValue{ Key: k, @@ -40,10 +47,17 @@ func (k Key) Int(v int) KeyValue { } } -// IntSlice creates a KeyValue instance with an INT64SLICE Value. +// IntSlice returns a [KeyValue] for a []int value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- IntSlice(name, value). +// It is provided as a convenience for [Key.Int64Slice]. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [IntSlice] function. func (k Key) IntSlice(v []int) KeyValue { return KeyValue{ Key: k, @@ -51,10 +65,10 @@ func (k Key) IntSlice(v []int) KeyValue { } } -// Int64 creates a KeyValue instance with an INT64 Value. +// Int64 returns a [KeyValue] for an int64 value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Int64(name, value). +// If creating both a key and value at the same time, use the package-level +// [Int64] function. func (k Key) Int64(v int64) KeyValue { return KeyValue{ Key: k, @@ -62,10 +76,15 @@ func (k Key) Int64(v int64) KeyValue { } } -// Int64Slice creates a KeyValue instance with an INT64SLICE Value. +// Int64Slice returns a [KeyValue] for a []int64 value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Int64Slice(name, value). +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [Int64Slice] function. func (k Key) Int64Slice(v []int64) KeyValue { return KeyValue{ Key: k, @@ -73,10 +92,10 @@ func (k Key) Int64Slice(v []int64) KeyValue { } } -// Float64 creates a KeyValue instance with a FLOAT64 Value. +// Float64 returns a [KeyValue] for a float64 value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Float64(name, value). +// If creating both a key and value at the same time, use the package-level +// [Float64] function. func (k Key) Float64(v float64) KeyValue { return KeyValue{ Key: k, @@ -84,10 +103,15 @@ func (k Key) Float64(v float64) KeyValue { } } -// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value. +// Float64Slice returns a [KeyValue] for a []float64 value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Float64(name, value). +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [Float64Slice] function. func (k Key) Float64Slice(v []float64) KeyValue { return KeyValue{ Key: k, @@ -95,10 +119,10 @@ func (k Key) Float64Slice(v []float64) KeyValue { } } -// String creates a KeyValue instance with a STRING Value. +// String returns a [KeyValue] for a string value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- String(name, value). +// If creating both a key and value at the same time, use the package-level +// [String] function. func (k Key) String(v string) KeyValue { return KeyValue{ Key: k, @@ -106,10 +130,15 @@ func (k Key) String(v string) KeyValue { } } -// StringSlice creates a KeyValue instance with a STRINGSLICE Value. +// StringSlice returns a [KeyValue] for a []string value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- StringSlice(name, value). +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [StringSlice] function. func (k Key) StringSlice(v []string) KeyValue { return KeyValue{ Key: k, @@ -117,10 +146,15 @@ func (k Key) StringSlice(v []string) KeyValue { } } -// ByteSlice creates a KeyValue instance with a BYTESLICE Value. +// ByteSlice returns a [KeyValue] for a []byte value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- ByteSlice(name, value). +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [ByteSlice] function. func (k Key) ByteSlice(v []byte) KeyValue { return KeyValue{ Key: k, @@ -128,10 +162,15 @@ func (k Key) ByteSlice(v []byte) KeyValue { } } -// Slice creates a KeyValue instance with a SLICE Value. +// Slice returns a [KeyValue] for a []Value value. // -// If creating both a key and value at the same time, use the provided -// convenience function instead -- Slice(name, values...). +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// If creating both a key and value at the same time, use the package-level +// [Slice] function. func (k Key) Slice(v ...Value) KeyValue { return KeyValue{ Key: k, @@ -139,6 +178,27 @@ func (k Key) Slice(v ...Value) KeyValue { } } +// Map returns a [KeyValue] for a []KeyValue value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// Users should avoid providing duplicate keys; many receivers handle maps +// containing duplicate keys unpredictably. +// +// The order of v is not preserved. +// +// If creating both a key and value at the same time, use the package-level [Map] +// function. +func (k Key) Map(v ...KeyValue) KeyValue { + return KeyValue{ + Key: k, + Value: MapValue(v...), + } +} + // Defined reports whether the key is not empty. func (k Key) Defined() bool { return len(k) != 0 diff --git a/vendor/go.opentelemetry.io/otel/attribute/kv.go b/vendor/go.opentelemetry.io/otel/attribute/kv.go index eeb76a134..c4f0dd928 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/kv.go +++ b/vendor/go.opentelemetry.io/otel/attribute/kv.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute import ( "fmt" @@ -18,66 +18,120 @@ func (kv KeyValue) Valid() bool { return kv.Key.Defined() } -// Bool creates a KeyValue with a BOOL Value type. +// Bool returns a [KeyValue] for a bool value. func Bool(k string, v bool) KeyValue { return Key(k).Bool(v) } -// BoolSlice creates a KeyValue with a BOOLSLICE Value type. +// BoolSlice returns a [KeyValue] for a []bool value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func BoolSlice(k string, v []bool) KeyValue { return Key(k).BoolSlice(v) } -// Int creates a KeyValue with an INT64 Value type. +// Int returns a [KeyValue] for an int value. +// +// It is provided as a convenience for [Int64]. func Int(k string, v int) KeyValue { return Key(k).Int(v) } -// IntSlice creates a KeyValue with an INT64SLICE Value type. +// IntSlice returns a [KeyValue] for a []int value. +// +// It is provided as a convenience for [Int64Slice]. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func IntSlice(k string, v []int) KeyValue { return Key(k).IntSlice(v) } -// Int64 creates a KeyValue with an INT64 Value type. +// Int64 returns a [KeyValue] for an int64 value. func Int64(k string, v int64) KeyValue { return Key(k).Int64(v) } -// Int64Slice creates a KeyValue with an INT64SLICE Value type. +// Int64Slice returns a [KeyValue] for a []int64 value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func Int64Slice(k string, v []int64) KeyValue { return Key(k).Int64Slice(v) } -// Float64 creates a KeyValue with a FLOAT64 Value type. +// Float64 returns a [KeyValue] for a float64 value. func Float64(k string, v float64) KeyValue { return Key(k).Float64(v) } -// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type. +// Float64Slice returns a [KeyValue] for a []float64 value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func Float64Slice(k string, v []float64) KeyValue { return Key(k).Float64Slice(v) } -// String creates a KeyValue with a STRING Value type. +// String returns a [KeyValue] for a string value. func String(k, v string) KeyValue { return Key(k).String(v) } -// StringSlice creates a KeyValue with a STRINGSLICE Value type. +// StringSlice returns a [KeyValue] for a []string value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func StringSlice(k string, v []string) KeyValue { return Key(k).StringSlice(v) } -// ByteSlice creates a KeyValue with a BYTESLICE Value type. +// ByteSlice returns a [KeyValue] for a []byte value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func ByteSlice(k string, v []byte) KeyValue { return Key(k).ByteSlice(v) } -// Slice creates a KeyValue with a SLICE Value type. +// Slice returns a [KeyValue] for a []Value value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func Slice(k string, v ...Value) KeyValue { return Key(k).Slice(v...) } +// Map returns a [KeyValue] for a []KeyValue value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// Users should avoid providing duplicate keys; many receivers handle maps +// containing duplicate keys unpredictably. +// +// The order of v is not preserved. +func Map(k string, v ...KeyValue) KeyValue { + return Key(k).Map(v...) +} + // Stringer creates a new key-value pair with a passed name and a string // value generated by the passed Stringer interface. func Stringer(k string, v fmt.Stringer) KeyValue { diff --git a/vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go b/vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go index 5791c6e7a..939e46f90 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go +++ b/vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute import ( "math" diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go index a4b6ce81d..87d6f9620 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/set.go +++ b/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute import ( "cmp" diff --git a/vendor/go.opentelemetry.io/otel/attribute/type_string.go b/vendor/go.opentelemetry.io/otel/attribute/type_string.go index dbc01d324..ab5da2288 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/type_string.go +++ b/vendor/go.opentelemetry.io/otel/attribute/type_string.go @@ -19,11 +19,12 @@ func _() { _ = x[STRINGSLICE-8] _ = x[BYTESLICE-9] _ = x[SLICE-10] + _ = x[MAP-11] } -const _Type_name = "EMPTYBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICEBYTESLICESLICE" +const _Type_name = "EMPTYBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICEBYTESLICESLICEMAP" -var _Type_index = [...]uint8{0, 5, 9, 14, 21, 27, 36, 46, 58, 69, 78, 83} +var _Type_index = [...]uint8{0, 5, 9, 14, 21, 27, 36, 46, 58, 69, 78, 83, 86} func (i Type) String() string { idx := int(i) - 0 diff --git a/vendor/go.opentelemetry.io/otel/attribute/value.go b/vendor/go.opentelemetry.io/otel/attribute/value.go index 0529fefae..07a0353a1 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/value.go +++ b/vendor/go.opentelemetry.io/otel/attribute/value.go @@ -1,14 +1,16 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package attribute // import "go.opentelemetry.io/otel/attribute" +package attribute import ( + "cmp" "encoding/base64" "encoding/json" "fmt" "math" "reflect" + "slices" "strconv" "strings" "unicode/utf8" @@ -18,10 +20,10 @@ import ( //go:generate stringer -type=Type -// Type describes the type of the data Value holds. +// Type describes the kind of data a [Value] holds. type Type int // nolint: revive // redefines builtin Type. -// Value represents the value part in key-value pairs. +// Value represents the value in key-value pairs. // // Note that the zero value is a valid empty value. type Value struct { @@ -32,35 +34,40 @@ type Value struct { } const ( - // EMPTY is used for a Value with no value set. + // EMPTY identifies a Value with no data. EMPTY Type = iota - // BOOL is a boolean Type Value. + // BOOL identifies a Value containing a bool. BOOL - // INT64 is a 64-bit signed integral Type Value. + // INT64 identifies a Value containing an int64. INT64 - // FLOAT64 is a 64-bit floating point Type Value. + // FLOAT64 identifies a Value containing a float64. FLOAT64 - // STRING is a string Type Value. + // STRING identifies a Value containing a string. STRING - // BOOLSLICE is a slice of booleans Type Value. + // BOOLSLICE identifies a Value containing a []bool. BOOLSLICE - // INT64SLICE is a slice of 64-bit signed integral numbers Type Value. + // INT64SLICE identifies a Value containing a []int64. INT64SLICE - // FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value. + // FLOAT64SLICE identifies a Value containing a []float64. FLOAT64SLICE - // STRINGSLICE is a slice of strings Type Value. + // STRINGSLICE identifies a Value containing a []string. STRINGSLICE - // BYTESLICE is a slice of bytes Type Value. + // BYTESLICE identifies a Value containing a []byte. BYTESLICE - // SLICE is a slice of Value Type values. + // SLICE identifies a Value containing a []Value. SLICE + // MAP identifies a Value containing a []KeyValue representation of a map. + // + // Note that MAP values may contain duplicate keys if duplicate keys are + // provided when creating the value. + MAP // INVALID is used for a Value with no value set. // // Deprecated: Use EMPTY instead as an empty value is a valid value. INVALID = EMPTY ) -// BoolValue creates a BOOL Value. +// BoolValue returns a [Value] for a bool value. func BoolValue(v bool) Value { return Value{ vtype: BOOL, @@ -68,17 +75,31 @@ func BoolValue(v bool) Value { } } -// BoolSliceValue creates a BOOLSLICE Value. +// BoolSliceValue returns a [Value] for a []bool value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func BoolSliceValue(v []bool) Value { return Value{vtype: BOOLSLICE, slice: attribute.SliceValue(v)} } -// IntValue creates an INT64 Value. +// IntValue returns a [Value] for an int value. +// +// It is provided as a convenience for [Int64Value]. func IntValue(v int) Value { return Int64Value(int64(v)) } -// IntSliceValue creates an INT64SLICE Value. +// IntSliceValue returns a [Value] for a []int value. +// +// It is provided as a convenience for [Int64SliceValue]. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func IntSliceValue(v []int) Value { val := Value{vtype: INT64SLICE} @@ -104,7 +125,7 @@ func IntSliceValue(v []int) Value { return val } -// Int64Value creates an INT64 Value. +// Int64Value returns a [Value] for an int64 value. func Int64Value(v int64) Value { return Value{ vtype: INT64, @@ -112,12 +133,17 @@ func Int64Value(v int64) Value { } } -// Int64SliceValue creates an INT64SLICE Value. +// Int64SliceValue returns a [Value] for a []int64 value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func Int64SliceValue(v []int64) Value { return Value{vtype: INT64SLICE, slice: attribute.SliceValue(v)} } -// Float64Value creates a FLOAT64 Value. +// Float64Value returns a [Value] for a float64 value. func Float64Value(v float64) Value { return Value{ vtype: FLOAT64, @@ -125,12 +151,17 @@ func Float64Value(v float64) Value { } } -// Float64SliceValue creates a FLOAT64SLICE Value. +// Float64SliceValue returns a [Value] for a []float64 value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func Float64SliceValue(v []float64) Value { return Value{vtype: FLOAT64SLICE, slice: attribute.SliceValue(v)} } -// StringValue creates a STRING Value. +// StringValue returns a [Value] for a string value. func StringValue(v string) Value { return Value{ vtype: STRING, @@ -138,12 +169,22 @@ func StringValue(v string) Value { } } -// StringSliceValue creates a STRINGSLICE Value. +// StringSliceValue returns a [Value] for a []string value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func StringSliceValue(v []string) Value { return Value{vtype: STRINGSLICE, slice: attribute.SliceValue(v)} } -// ByteSliceValue creates a BYTESLICE Value. +// ByteSliceValue returns a [Value] for a []byte value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func ByteSliceValue(v []byte) Value { return Value{ vtype: BYTESLICE, @@ -151,12 +192,32 @@ func ByteSliceValue(v []byte) Value { } } -// SliceValue creates a SLICE Value. +// SliceValue returns a [Value] for a []Value value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. func SliceValue(v ...Value) Value { return Value{vtype: SLICE, slice: sliceValue(v)} } -// Type returns a type of the Value. +// MapValue returns a [Value] for a []KeyValue value. +// +// Note that many observability backends are not optimized to query, index, or +// aggregate complex attribute values. Complex values may also carry +// additional performance overhead. Prefer primitive values when +// possible. +// +// Users should avoid providing duplicate keys; many receivers handle maps +// containing duplicate keys unpredictably. +// +// The order of v is not preserved. +func MapValue(v ...KeyValue) Value { + return Value{vtype: MAP, slice: mapValue(v)} +} + +// Type returns v's type. func (v Value) Type() Type { return v.vtype } @@ -277,6 +338,53 @@ func asValueSliceReflect(v any) []Value { return cpy } +// AsMap returns the []KeyValue value. Make sure that the Value's type is +// MAP. +// +// The returned slice is sorted by key and may differ from the order +// provided when creating the map value. +// +// The returned slice may contain duplicate keys if duplicate keys were +// provided when creating the map value. Callers should not assume the returned +// keys are unique. +func (v Value) AsMap() []KeyValue { + if v.vtype != MAP { + return nil + } + return v.asMap() +} + +func (v Value) asMap() []KeyValue { + switch vals := v.slice.(type) { + case [0]KeyValue: + return []KeyValue{} + case [1]KeyValue: + return []KeyValue{vals[0]} + case [2]KeyValue: + return []KeyValue{vals[0], vals[1]} + case [3]KeyValue: + return []KeyValue{vals[0], vals[1], vals[2]} + case [4]KeyValue: + return []KeyValue{vals[0], vals[1], vals[2], vals[3]} + case [5]KeyValue: + return []KeyValue{vals[0], vals[1], vals[2], vals[3], vals[4]} + default: + return asKeyValueSliceReflect(v.slice) + } +} + +func asKeyValueSliceReflect(v any) []KeyValue { + rv := reflect.ValueOf(v) + if !rv.IsValid() || rv.Kind() != reflect.Array || rv.Type().Elem() != reflect.TypeFor[KeyValue]() { + return nil + } + cpy := make([]KeyValue, rv.Len()) + if len(cpy) > 0 { + _ = reflect.Copy(reflect.ValueOf(cpy), rv) + } + return cpy +} + // AsByteSlice returns the bytes value. Make sure that the Value's type // is BYTESLICE. func (v Value) AsByteSlice() []byte { @@ -315,6 +423,8 @@ func (v Value) AsInterface() any { return v.asByteSlice() case SLICE: return v.asSlice() + case MAP: + return v.asMap() case EMPTY: return nil } @@ -327,10 +437,10 @@ func (v Value) AsInterface() any { // Strings are returned as-is without JSON quoting, booleans and integers use // JSON literals, floating-point values use JSON numbers except that NaN and // ±Inf are rendered as NaN, Infinity, and -Infinity, byte slices are -// base64-encoded, empty values are the empty string, and slices are encoded as -// JSON arrays. String, byte, and special floating-point values inside arrays -// are encoded as JSON strings, and empty values inside arrays are encoded as -// null. +// base64-encoded, empty values are the empty string, slices are encoded as JSON +// arrays, and maps are encoded as JSON objects. String, byte, and special +// floating-point values inside arrays and maps are encoded as JSON strings, and +// empty values inside arrays and maps are encoded as null. // // [OpenTelemetry AnyValue representation for non-OTLP protocols]: https://opentelemetry.io/docs/specs/otel/common/#anyvalue-representation-for-non-otlp-protocols func (v Value) String() string { @@ -355,6 +465,8 @@ func (v Value) String() string { return formatByteSlice(v.stringly) case SLICE: return formatValueSliceValue(v.slice) + case MAP: + return formatMapValue(v.slice) case EMPTY: return "" default: @@ -399,6 +511,8 @@ func (v Value) Emit() string { return formatByteSlice(v.stringly) case SLICE: return formatValueSliceValue(v.slice) + case MAP: + return formatMapValue(v.slice) case EMPTY: return "" default: @@ -439,6 +553,47 @@ func sliceValueReflect(v []Value) any { return cp.Interface() } +func mapValue(v []KeyValue) any { + switch len(v) { + case 0: + return [0]KeyValue{} + case 1: + return [1]KeyValue{v[0]} + case 2: + vals := [2]KeyValue{v[0], v[1]} + sortKeyValues(vals[:]) + return vals + case 3: + vals := [3]KeyValue{v[0], v[1], v[2]} + sortKeyValues(vals[:]) + return vals + case 4: + vals := [4]KeyValue{v[0], v[1], v[2], v[3]} + sortKeyValues(vals[:]) + return vals + case 5: + vals := [5]KeyValue{v[0], v[1], v[2], v[3], v[4]} + sortKeyValues(vals[:]) + return vals + default: + return mapValueReflect(v) + } +} + +func mapValueReflect(v []KeyValue) any { + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[KeyValue]())).Elem() + reflect.Copy(cp, reflect.ValueOf(v)) + vals := cp.Slice(0, len(v)).Interface().([]KeyValue) + sortKeyValues(vals) + return cp.Interface() +} + +func sortKeyValues(vals []KeyValue) { + slices.SortStableFunc(vals, func(a, b KeyValue) int { + return cmp.Compare(a.Key, b.Key) + }) +} + func formatBoolSliceValue(v any) string { switch vals := v.(type) { case [0]bool: @@ -807,6 +962,37 @@ func formatValueSliceReflect(v any) string { return b.String() } +func formatMapValue(v any) string { + switch vals := v.(type) { + case [0]KeyValue: + return "{}" + case [1]KeyValue: + return formatMap(vals[:]) + case [2]KeyValue: + return formatMap(vals[:]) + case [3]KeyValue: + return formatMap(vals[:]) + case [4]KeyValue: + return formatMap(vals[:]) + case [5]KeyValue: + return formatMap(vals[:]) + default: + return formatMapReflect(v) + } +} + +func formatMap(vals []KeyValue) string { + var b strings.Builder + appendMap(&b, vals) + return b.String() +} + +func formatMapReflect(v any) string { + var b strings.Builder + appendMapReflect(&b, reflect.ValueOf(v)) + return b.String() +} + func appendValueSliceValue(dst *strings.Builder, v any) { switch vals := v.(type) { case [0]Value: @@ -852,6 +1038,68 @@ func appendValueSliceReflect(dst *strings.Builder, rv reflect.Value) { _ = dst.WriteByte(']') } +func appendMapValue(dst *strings.Builder, v any) { + switch vals := v.(type) { + case [0]KeyValue: + _, _ = dst.WriteString("{}") + case [1]KeyValue: + appendMap(dst, vals[:]) + case [2]KeyValue: + appendMap(dst, vals[:]) + case [3]KeyValue: + appendMap(dst, vals[:]) + case [4]KeyValue: + appendMap(dst, vals[:]) + case [5]KeyValue: + appendMap(dst, vals[:]) + default: + appendMapReflect(dst, reflect.ValueOf(v)) + } +} + +func appendMap(dst *strings.Builder, vals []KeyValue) { + // Estimate 32 bytes per value for small values, plus key quotes, colon, + // and commas. Escaped keys and larger values grow the builder as needed. + size := len("{}") + len(vals)*commaLen + len(vals)*32 + for _, val := range vals { + size += len(val.Key) + len(`"":`) + } + + dst.Grow(size) + _ = dst.WriteByte('{') + for i, val := range vals { + if i > 0 { + _ = dst.WriteByte(',') + } + appendJSONString(dst, string(val.Key)) + _ = dst.WriteByte(':') + appendJSONValue(dst, val.Value) + } + _ = dst.WriteByte('}') +} + +func appendMapReflect(dst *strings.Builder, rv reflect.Value) { + // Estimate 32 bytes per value for small values, plus key quotes, colon, + // and commas. Escaped keys and larger values grow the builder as needed. + size := len("{}") + rv.Len()*commaLen + rv.Len()*32 + for i := 0; i < rv.Len(); i++ { + size += len(rv.Index(i).Field(0).String()) + len(`"":`) + } + + dst.Grow(size) + _ = dst.WriteByte('{') + for i := 0; i < rv.Len(); i++ { + if i > 0 { + _ = dst.WriteByte(',') + } + val := rv.Index(i).Interface().(KeyValue) + appendJSONString(dst, string(val.Key)) + _ = dst.WriteByte(':') + appendJSONValue(dst, val.Value) + } + _ = dst.WriteByte('}') +} + func appendJSONValue(dst *strings.Builder, v Value) { switch v.Type() { case BOOL: @@ -894,6 +1142,8 @@ func appendJSONValue(dst *strings.Builder, v Value) { _ = dst.WriteByte('"') case SLICE: appendValueSliceValue(dst, v.slice) + case MAP: + appendMapValue(dst, v.slice) case EMPTY: _, _ = dst.WriteString("null") default: diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go index b290c6d6c..25c739d08 100644 --- a/vendor/go.opentelemetry.io/otel/baggage/baggage.go +++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package baggage // import "go.opentelemetry.io/otel/baggage" +package baggage import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/baggage/context.go b/vendor/go.opentelemetry.io/otel/baggage/context.go index a572461a0..4d09b59aa 100644 --- a/vendor/go.opentelemetry.io/otel/baggage/context.go +++ b/vendor/go.opentelemetry.io/otel/baggage/context.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package baggage // import "go.opentelemetry.io/otel/baggage" +package baggage import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/baggage/doc.go b/vendor/go.opentelemetry.io/otel/baggage/doc.go index b51d87cab..74d3a8709 100644 --- a/vendor/go.opentelemetry.io/otel/baggage/doc.go +++ b/vendor/go.opentelemetry.io/otel/baggage/doc.go @@ -6,4 +6,4 @@ Package baggage provides functionality for storing and retrieving baggage items in Go context. For propagating the baggage, see the go.opentelemetry.io/otel/propagation package. */ -package baggage // import "go.opentelemetry.io/otel/baggage" +package baggage diff --git a/vendor/go.opentelemetry.io/otel/codes/codes.go b/vendor/go.opentelemetry.io/otel/codes/codes.go index d48847ed8..9355545a8 100644 --- a/vendor/go.opentelemetry.io/otel/codes/codes.go +++ b/vendor/go.opentelemetry.io/otel/codes/codes.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package codes // import "go.opentelemetry.io/otel/codes" +package codes import ( "encoding/json" @@ -81,7 +81,7 @@ func (c *Code) UnmarshalJSON(b []byte) error { case float64: if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil { if ci >= maxCode { - return fmt.Errorf("invalid code: %q", ci) + return fmt.Errorf("invalid code: %d", ci) } *c = Code(ci) // nolint: gosec // Bit size of 32 check above. diff --git a/vendor/go.opentelemetry.io/otel/codes/doc.go b/vendor/go.opentelemetry.io/otel/codes/doc.go index ee8db448b..1073f6543 100644 --- a/vendor/go.opentelemetry.io/otel/codes/doc.go +++ b/vendor/go.opentelemetry.io/otel/codes/doc.go @@ -7,4 +7,4 @@ Package codes defines the canonical error codes used by OpenTelemetry. It conforms to [the OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/api.md#set-status). */ -package codes // import "go.opentelemetry.io/otel/codes" +package codes diff --git a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile index 74fa510bc..20eecba40 100644 --- a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile +++ b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile @@ -1,4 +1,4 @@ # This is a renovate-friendly source of Docker images. FROM python:3.13.6-slim-bullseye@sha256:e98b521460ee75bca92175c16247bdf7275637a8faaeb2bcfa19d879ae5c4b9a AS python -FROM otel/weaver:v0.23.0@sha256:7984ecb55b859eb3034ae9d836c4eeda137e2bdd0873b7ba2bb6c3d24d6ff457 AS weaver +FROM otel/weaver:v0.25.1@sha256:9ad46ca9cd4fa5974b121f886aa3e9946a8ef8ea905001a96c018d21f9db87ca AS weaver FROM avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee AS markdown diff --git a/vendor/go.opentelemetry.io/otel/doc.go b/vendor/go.opentelemetry.io/otel/doc.go index 921f85961..92b7a0566 100644 --- a/vendor/go.opentelemetry.io/otel/doc.go +++ b/vendor/go.opentelemetry.io/otel/doc.go @@ -22,4 +22,4 @@ To read more about logs, see go.opentelemetry.io/otel/log. To read more about propagation, see go.opentelemetry.io/otel/propagation and go.opentelemetry.io/otel/baggage. */ -package otel // import "go.opentelemetry.io/otel" +package otel diff --git a/vendor/go.opentelemetry.io/otel/error_handler.go b/vendor/go.opentelemetry.io/otel/error_handler.go index 67414c71e..06fd49da2 100644 --- a/vendor/go.opentelemetry.io/otel/error_handler.go +++ b/vendor/go.opentelemetry.io/otel/error_handler.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel // ErrorHandler handles irremediable events. type ErrorHandler interface { diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go index 22b845053..ee6b018dd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" +package otlpmetricgrpc import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go index 47eb85e9f..8f6fec81f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" +package otlpmetricgrpc import ( "fmt" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go index 62b05626f..938cb6a48 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go @@ -84,4 +84,4 @@ the experimental features. [Explicit Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation [Base2 Exponential Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation */ -package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" +package otlpmetricgrpc diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/exporter.go index b567800e3..302c992ee 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/exporter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" +package otlpmetricgrpc import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/counter/counter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/counter/counter.go index df6b830d3..57c6acb78 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/counter/counter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/internal/counter" +package counter import "sync/atomic" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/envconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/envconfig/envconfig.go index 2cd98b929..87764a695 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/envconfig/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/internal/gen.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/gen.go index c94f85ef4..df08789be 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/gen.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/gen.go @@ -2,12 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal functionally for the otlpmetricgrpc package. -package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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 -//go:generate gotmpl --body=../../../../../internal/shared/otlp/observ/target.go.tmpl "--data={ \"pkg\": \"observ\", \"pkg_path\": \"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlp/retry/retry.go.tmpl "--data={}" --out=retry/retry.go @@ -34,7 +34,7 @@ package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/o //go:generate gotmpl --body=../../../../../internal/shared/otlp/otlpmetric/transform/metricdata.go.tmpl "--data={}" --out=transform/metricdata.go //go:generate gotmpl --body=../../../../../internal/shared/otlp/otlpmetric/transform/metricdata_test.go.tmpl "--data={}" --out=transform/metricdata_test.go -//go:generate gotmpl --body=../../../../../internal/shared/counter/counter.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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 //go:generate gotmpl --body=../../../../../internal/shared/x/x.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc\" }" --out=x/x.go diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/instrumentation.go index 2b4dbb5d8..a8ffd871b 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/instrumentation.go @@ -3,7 +3,7 @@ // Package observ provides self-observability metrics for OTLP metric exporters. // This is an experimental feature controlled by the x.Observability feature flag. -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ" +package observ import ( "context" @@ -17,8 +17,8 @@ import ( "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/sdk" - 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" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/target.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/target.go index 0be4501ec..4d0665894 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/observ/target.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/internal/observ" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/observ/target.go.tmpl + +package observ import ( "errors" @@ -41,11 +41,10 @@ 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 { diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go index 7f947273b..700dc0d1c 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl + +package oconf import ( "crypto/tls" @@ -51,31 +51,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.Metrics.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.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) - return cfg - }, withEndpointForGRPC(u))) + opts = append( + opts, + withEndpointScheme(u), + newSplitOption(func(cfg Config) Config { + cfg.Metrics.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.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) + return cfg + }, withEndpointForGRPC(u)), + ) }), envconfig.WithURL("METRICS_ENDPOINT", func(u *url.URL) { - opts = append(opts, withEndpointScheme(u)) - opts = append(opts, newSplitOption(func(cfg Config) Config { - cfg.Metrics.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.Metrics.URLPath = path - return cfg - }, withEndpointForGRPC(u))) + opts = append( + opts, + withEndpointScheme(u), + newSplitOption(func(cfg Config) Config { + cfg.Metrics.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.Metrics.URLPath = path + return cfg + }, withEndpointForGRPC(u)), + ) }), envconfig.WithCertPool("CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), envconfig.WithCertPool("METRICS_CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), @@ -152,7 +158,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/otlpmetric/otlpmetricgrpc/internal/oconf/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go index b89d7eeb7..4b4f164e1 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go @@ -1,11 +1,11 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/options.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/options.go.tmpl + // Package oconf provides configuration for the otlpmetric exporters. -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf" +package oconf import ( "crypto/tls" @@ -112,7 +112,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 @@ -148,7 +148,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.Metrics.GRPCCredentials != nil { + if cfg.Metrics.GRPCCredentials != nil { //nolint:gocritic // if-else is clearer than switch cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(cfg.Metrics.GRPCCredentials)) } else if cfg.Metrics.Insecure { cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(insecure.NewCredentials())) @@ -242,7 +242,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} } @@ -295,6 +295,11 @@ func WithEndpointURL(v string) GenericOption { cfg.Metrics.Endpoint = u.Host cfg.Metrics.URLPath = u.Path + if cfg.Metrics.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.Metrics.URLPath = "/" + } cfg.Metrics.Insecure = u.Scheme != "https" return cfg diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/optiontypes.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/optiontypes.go index c18a6b1f2..79f77841a 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/optiontypes.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/optiontypes.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/optiontypes.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/optiontypes.go.tmpl + +package oconf import "time" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/tls.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/tls.go index e4547b3a6..4ed82885a 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/tls.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/tls.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/tls.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/tls.go.tmpl + +package oconf import ( "crypto/tls" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/partialsuccess.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/partialsuccess.go index 243abcb17..1138f2e71 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/partialsuccess.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/internal/retry/retry.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go index c14e5ae78..1883d0600 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry/retry.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/internal/retry" +package retry import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go index 96420d421..9fea51b46 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/attribute.go @@ -1,14 +1,15 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package transform // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl + +package transform import ( - "go.opentelemetry.io/otel/attribute" cpb "go.opentelemetry.io/proto/otlp/common/v1" + + "go.opentelemetry.io/otel/attribute" ) // AttrIter transforms an attribute iterator into OTLP key-values. @@ -91,6 +92,12 @@ func Value(v attribute.Value) *cpb.AnyValue { Values: attrValues(v.AsSlice()), }, } + case attribute.MAP: + av.Value = &cpb.AnyValue_KvlistValue{ + KvlistValue: &cpb.KeyValueList{ + Values: KeyValues(v.AsMap()), + }, + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/error.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/error.go index f03bfec41..728502222 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/error.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/error.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/transform/error.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package transform // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/transform/error.go.tmpl + +package transform import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/metricdata.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/metricdata.go index 9c156e91b..6c07896a8 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/metricdata.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform/metricdata.go @@ -1,21 +1,22 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/transform/metricdata.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/transform/metricdata.go.tmpl + // Package transform provides transformation functionality from the // sdk/metric/metricdata data-types into OTLP data-types. -package transform // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform" +package transform import ( "fmt" "time" - "go.opentelemetry.io/otel/sdk/metric/metricdata" cpb "go.opentelemetry.io/proto/otlp/common/v1" mpb "go.opentelemetry.io/proto/otlp/metrics/v1" rpb "go.opentelemetry.io/proto/otlp/resource/v1" + + "go.opentelemetry.io/otel/sdk/metric/metricdata" ) // ResourceMetrics returns an OTLP ResourceMetrics generated from rm. If rm diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/observ.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/observ.go index cc055ea47..f292e095c 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/observ.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc/internal/x" +package x import "strings" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/x.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/x.go index d42827877..02d7fbefe 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/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/otlpmetric/otlpmetricgrpc]. -package x // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x" +package x import ( "os" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/version.go index 8ee005c63..4ab57afe2 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/version.go @@ -1,9 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" +package otlpmetricgrpc // Version is the current release version of the OpenTelemetry OTLP over gRPC metrics exporter in use. func Version() string { - return "1.44.0" + return "1.45.0" } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go index b7ca17fe3..41aa7ff34 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" +package otlpmetrichttp import ( "bytes" @@ -341,7 +341,7 @@ func (r *request) reset(ctx context.Context) { // retryableError represents a request failure that can be retried. type retryableError struct { - throttle int64 + throttle time.Duration err error } @@ -351,15 +351,29 @@ type retryableError struct { func newResponseError(header http.Header, wrapped error) error { var rErr retryableError if v := header.Get("Retry-After"); v != "" { - if t, err := strconv.ParseInt(v, 10, 64); err == nil { - rErr.throttle = t - } + rErr.throttle = retryAfterDuration(v) } rErr.err = wrapped return rErr } +func retryAfterDuration(v string) time.Duration { + if t, err := strconv.ParseInt(v, 10, 64); err == nil && t >= 0 { + const maxRetryAfterSeconds = int64(1<<63-1) / int64(time.Second) + if t > maxRetryAfterSeconds { + return time.Duration(1<<63 - 1) + } + return time.Duration(t) * time.Second + } + + if date, err := http.ParseTime(v); err == nil { + return max(time.Until(date), 0) + } + + return 0 +} + func (e retryableError) Error() string { if e.err != nil { return "retry-able request failure: " + e.err.Error() @@ -401,5 +415,5 @@ func evaluate(err error) (bool, time.Duration) { return false, 0 } - return true, time.Duration(rErr.throttle) + return true, rErr.throttle } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/config.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/config.go index c6175507a..35e6bb12d 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/config.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" +package otlpmetrichttp import ( "crypto/tls" @@ -86,6 +86,11 @@ func WithEndpoint(endpoint string) Option { // // If an invalid URL is provided, the default value will be kept. // +// The path of the provided URL is used as-is; with one exception: if the URL has +// no path, it is normalized to the root path ("/"). The default metrics path +// ("/v1/metrics") is not appended automatically. Use WithEndpoint if you want +// that behavior, or pass a URL that includes that path. +// // By default, if an environment variable is not set, and this option is not // passed, "localhost:4318" will be used. // diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go index a2ea04922..a5e15efd6 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go @@ -84,4 +84,4 @@ The configuration can be overridden by [WithAggregationSelector] option. [Explicit Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation [Base2 Exponential Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation */ -package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" +package otlpmetrichttp diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/exporter.go index 292645a38..ea4e20c23 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/exporter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" +package otlpmetrichttp import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/counter/counter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/counter/counter.go index 267cb03d9..57c6acb78 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/counter/counter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/counter" +package counter import "sync/atomic" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/envconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/envconfig/envconfig.go index 8be035fca..87764a695 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/envconfig/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/gen.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/gen.go index f3d165a57..9b1727caa 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/gen.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/gen.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal functionally for the otlpmetrichttp package. -package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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 @@ -31,7 +31,7 @@ package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/o //go:generate gotmpl --body=../../../../../internal/shared/otlp/otlpmetric/transform/metricdata.go.tmpl "--data={}" --out=transform/metricdata.go //go:generate gotmpl --body=../../../../../internal/shared/otlp/otlpmetric/transform/metricdata_test.go.tmpl "--data={}" --out=transform/metricdata_test.go -//go:generate gotmpl --body=../../../../../internal/shared/counter/counter.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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 //go:generate gotmpl --body=../../../../../internal/shared/x/x.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x\" }" --out=x/x.go diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/count.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/count.go index 8b5bb1faa..b046b195e 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/count.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/count.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ" +package observ import metricpb "go.opentelemetry.io/proto/otlp/metrics/v1" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/instrumentation.go index 5db984a23..b28b2f886 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ/instrumentation.go @@ -3,7 +3,7 @@ // Package observ provides experimental observability instrumentation for the // otlpmetrichttp exporter. -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/observ" +package observ import ( "context" @@ -25,8 +25,8 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go index 69224c97d..c0a6392dd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl + +package oconf import ( "crypto/tls" @@ -51,31 +51,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.Metrics.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.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) - return cfg - }, withEndpointForGRPC(u))) + opts = append( + opts, + withEndpointScheme(u), + newSplitOption(func(cfg Config) Config { + cfg.Metrics.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.Metrics.URLPath = path.Join(u.Path, DefaultMetricsPath) + return cfg + }, withEndpointForGRPC(u)), + ) }), envconfig.WithURL("METRICS_ENDPOINT", func(u *url.URL) { - opts = append(opts, withEndpointScheme(u)) - opts = append(opts, newSplitOption(func(cfg Config) Config { - cfg.Metrics.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.Metrics.URLPath = path - return cfg - }, withEndpointForGRPC(u))) + opts = append( + opts, + withEndpointScheme(u), + newSplitOption(func(cfg Config) Config { + cfg.Metrics.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.Metrics.URLPath = path + return cfg + }, withEndpointForGRPC(u)), + ) }), envconfig.WithCertPool("CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), envconfig.WithCertPool("METRICS_CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }), @@ -152,7 +158,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/otlpmetric/otlpmetrichttp/internal/oconf/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go index 3fa7cbe5f..a3e4641c2 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go @@ -1,11 +1,11 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/options.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/options.go.tmpl + // Package oconf provides configuration for the otlpmetric exporters. -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf" +package oconf import ( "crypto/tls" @@ -112,7 +112,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 @@ -148,7 +148,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.Metrics.GRPCCredentials != nil { + if cfg.Metrics.GRPCCredentials != nil { //nolint:gocritic // if-else is clearer than switch cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(cfg.Metrics.GRPCCredentials)) } else if cfg.Metrics.Insecure { cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(insecure.NewCredentials())) @@ -242,7 +242,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} } @@ -295,6 +295,11 @@ func WithEndpointURL(v string) GenericOption { cfg.Metrics.Endpoint = u.Host cfg.Metrics.URLPath = u.Path + if cfg.Metrics.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.Metrics.URLPath = "/" + } cfg.Metrics.Insecure = u.Scheme != "https" return cfg diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/optiontypes.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/optiontypes.go index d7b005c97..79f77841a 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/optiontypes.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/optiontypes.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/optiontypes.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/optiontypes.go.tmpl + +package oconf import "time" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/tls.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/tls.go index e335cbd09..4ed82885a 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/tls.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/tls.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/oconf/tls.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package oconf // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/oconf/tls.go.tmpl + +package oconf import ( "crypto/tls" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/partialsuccess.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/partialsuccess.go index 04190f530..1138f2e71 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/partialsuccess.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/retry/retry.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go index b4b5c013d..1883d0600 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry/retry.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/retry" +package retry import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go index 6a91ff2af..9fea51b46 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/attribute.go @@ -1,14 +1,15 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package transform // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/transform/attribute.go.tmpl + +package transform import ( - "go.opentelemetry.io/otel/attribute" cpb "go.opentelemetry.io/proto/otlp/common/v1" + + "go.opentelemetry.io/otel/attribute" ) // AttrIter transforms an attribute iterator into OTLP key-values. @@ -91,6 +92,12 @@ func Value(v attribute.Value) *cpb.AnyValue { Values: attrValues(v.AsSlice()), }, } + case attribute.MAP: + av.Value = &cpb.AnyValue_KvlistValue{ + KvlistValue: &cpb.KeyValueList{ + Values: KeyValues(v.AsMap()), + }, + } case attribute.STRINGSLICE: av.Value = &cpb.AnyValue_ArrayValue{ ArrayValue: &cpb.ArrayValue{ diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/error.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/error.go index f65c87cbf..728502222 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/error.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/error.go @@ -1,10 +1,10 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/transform/error.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package transform // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform" +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/transform/error.go.tmpl + +package transform import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/metricdata.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/metricdata.go index 5e5f26aa4..6c07896a8 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/metricdata.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform/metricdata.go @@ -1,21 +1,22 @@ -// Code generated by gotmpl. DO NOT MODIFY. -// source: internal/shared/otlp/otlpmetric/transform/metricdata.go.tmpl - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// DO NOT MODIFY. Generated by gotmpl. +// source: internal/shared/otlp/otlpmetric/transform/metricdata.go.tmpl + // Package transform provides transformation functionality from the // sdk/metric/metricdata data-types into OTLP data-types. -package transform // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform" +package transform import ( "fmt" "time" - "go.opentelemetry.io/otel/sdk/metric/metricdata" cpb "go.opentelemetry.io/proto/otlp/common/v1" mpb "go.opentelemetry.io/proto/otlp/metrics/v1" rpb "go.opentelemetry.io/proto/otlp/resource/v1" + + "go.opentelemetry.io/otel/sdk/metric/metricdata" ) // ResourceMetrics returns an OTLP ResourceMetrics generated from rm. If rm diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/version.go index 103ac79d0..fdd5f6bdd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal" +package internal // Version is the current release version of the OpenTelemetry OTLP HTTP metric // exporter in use. -const Version = "1.44.0" +const Version = "1.45.0" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/README.md b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/README.md index ef239cbae..745170a80 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/README.md +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/README.md @@ -24,7 +24,7 @@ When enabled, the exporter will create the following metrics using the global `M Please see the [Semantic conventions for OpenTelemetry SDK metrics] documentation for more details on these metrics. -[Semantic conventions for OpenTelemetry SDK metrics]: https://github.com/open-telemetry/semantic-conventions/blob/v1.41.0/docs/otel/sdk-metrics.md +[Semantic conventions for OpenTelemetry SDK metrics]: https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/docs/otel/sdk-metrics.md ## Compatibility and Stability diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/observ.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/observ.go index 296946a3b..76b6fdebd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/observ.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/x" +package x import "strings" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/x.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/x.go index 663375f63..87c19a268 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/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/otlpmetric/otlpmetrichttp/internal/x]. -package x // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x" +package x import ( "os" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/version.go index da551839d..273e5e791 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/version.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" +package otlpmetrichttp // Version is the current release version of the OpenTelemetry OTLP over HTTP/protobuf metrics exporter in use. func Version() string { 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 3c1a625c0..d97fada29 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 09ad5eadb..5fd4bf5bb 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 30446bd28..037d485d5 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 0d43a5dc5..86a34d3b9 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 43359c894..078a9db0a 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 526bb5e07..14e5bdc56 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 d431fc451..3ab14b54f 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 e8b33d3fa..494bece44 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 b7bd429ff..b01358fc8 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 b826b8424..d75b18443 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 323b2a2c9..57c6acb78 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 6eacdf311..87764a695 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 7fe9c9f3a..ec16d0145 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 0dd54e4b9..32188bf72 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 676a93514..d6730bc1e 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 34eee27db..4d0665894 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" @@ -41,11 +41,10 @@ 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 { 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 1d840be20..8b3f729fd 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 }), @@ -142,7 +148,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 d940b6762..36cf1e267 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" @@ -99,7 +99,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 @@ -134,7 +134,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 +228,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 +286,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 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 918490387..213c3605f 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. 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 ba6e41183..a14d5e6ec 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 a811a07b3..1138f2e71 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 a7b8e81a7..1883d0600 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" 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 28e51e443..942d37af7 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.45.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 4e89c6524..76b6fdebd 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 741ba62c9..69ce31eef 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" 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 b32006052..ea20363c0 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/otlptracehttp/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go index f81098b38..5b122f3c4 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptracehttp // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" +package otlptracehttp import ( "bytes" @@ -334,15 +334,11 @@ func (c *client) newRequest(body []byte) (request, error) { } // 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 - Insecure bool + Type string }{ - Type: "otlptracehttp", - Endpoint: c.cfg.Endpoint, - Insecure: c.cfg.Insecure, + Type: "otlptracehttp", } } @@ -376,7 +372,7 @@ func (r *request) reset(ctx context.Context) { // retryableError represents a request failure that can be retried. type retryableError struct { - throttle int64 + throttle time.Duration err error } @@ -385,16 +381,30 @@ type retryableError struct { // if it is not nil. func newResponseError(header http.Header, wrapped error) error { var rErr retryableError - if s, ok := header["Retry-After"]; ok { - if t, err := strconv.ParseInt(s[0], 10, 64); err == nil { - rErr.throttle = t - } + if v := header.Get("Retry-After"); v != "" { + rErr.throttle = retryAfterDuration(v) } rErr.err = wrapped return rErr } +func retryAfterDuration(v string) time.Duration { + if t, err := strconv.ParseInt(v, 10, 64); err == nil && t >= 0 { + const maxRetryAfterSeconds = int64(1<<63-1) / int64(time.Second) + if t > maxRetryAfterSeconds { + return time.Duration(1<<63 - 1) + } + return time.Duration(t) * time.Second + } + + if date, err := http.ParseTime(v); err == nil { + return max(time.Until(date), 0) + } + + return 0 +} + func (e retryableError) Error() string { if e.err != nil { return "retry-able request failure: " + e.err.Error() @@ -436,7 +446,7 @@ func evaluate(err error) (bool, time.Duration) { return false, 0 } - return true, time.Duration(rErr.throttle) + return true, rErr.throttle } func (c *client) getScheme() string { diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/doc.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/doc.go index 85645e118..2064db571 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/doc.go @@ -65,4 +65,4 @@ The configuration can be overridden by [WithTLSClientConfig] option. [W3C Baggage HTTP Header Content Format]: https://www.w3.org/TR/baggage/#header-content */ -package otlptracehttp // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" +package otlptracehttp diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/exporter.go index fae89ea4f..b6e1214c8 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/exporter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptracehttp // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" +package otlptracehttp import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/counter/counter.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/counter/counter.go index 75e5c0c7e..57c6acb78 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/counter/counter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/internal/counter" +package counter import "sync/atomic" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/envconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/envconfig/envconfig.go index f4385fb4e..87764a695 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/envconfig/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/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/otlptracehttp/internal/gen.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/gen.go index ca387432f..9064f6564 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/gen.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/gen.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal functionally for the otlptracehttp package. -package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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 @@ -26,6 +26,6 @@ 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/otlptracehttp\" }" --out=x/x.go -//go:generate gotmpl --body=../../../../../internal/shared/counter/counter.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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 //go:generate gotmpl --body=../../../../../internal/shared/x/x_test.go.tmpl "--data={}" --out=x/x_test.go diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ/instrumentation.go index 1f4fc55c6..14ef0bbd8 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ/instrumentation.go @@ -3,7 +3,7 @@ // Package observ provides experimental observability instrumentation for the // otlptracehttp exporter. -package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/observ" +package observ import ( "context" @@ -23,8 +23,8 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/internal/otlpconfig/envconfig.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/envconfig.go index 121b02f5c..f630d66b8 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/envconfig.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/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 }), @@ -142,7 +148,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/otlptracehttp/internal/otlpconfig/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options.go index 2abde6615..eccabc0c2 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/internal/otlpconfig" +package otlpconfig import ( "crypto/tls" @@ -99,7 +99,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 @@ -134,7 +134,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 +228,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 +286,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 diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/optiontypes.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/optiontypes.go index 6a52b58cc..213c3605f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/optiontypes.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/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. diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/tls.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/tls.go index 5b389cb03..a14d5e6ec 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/tls.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/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/otlptracehttp/internal/partialsuccess.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/partialsuccess.go index 33ff6c024..1138f2e71 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/partialsuccess.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/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/otlptracehttp/internal/retry/retry.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go index bf3980825..1883d0600 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry/retry.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/internal/retry" +package retry import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/version.go index 882b67138..6e753209a 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/internal" +package internal // Version is the current release version of the OpenTelemetry OTLP HTTP trace // exporter in use. -const Version = "1.44.0" +const Version = "1.45.0" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/observ.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/observ.go index ecae4a79c..76b6fdebd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/observ.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp/internal/x" +package x import "strings" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/x.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/x.go index 099dab007..9e7537b9b 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/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/otlptracehttp]. -package x // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/x" +package x import ( "os" diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go index 291b5f9b6..ad6a2d748 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otlptracehttp // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" +package otlptracehttp import ( "crypto/tls" @@ -93,6 +93,11 @@ func WithEndpoint(endpoint string) Option { // // If an invalid URL is provided, the default value will be kept. // +// The path of the provided URL is used as-is; with one exception: if the URL has +// no path, it is normalized to the root path ("/"). The default traces path +// ("/v1/traces") is not appended automatically. Use WithEndpoint if you want +// that behavior, or pass a URL that includes that path. +// // By default, if an environment variable is not set, and this option is not // passed, "localhost:4318" will be used. // 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 d847210db..da70f3f54 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.45.0" } diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go index 5fe28b93d..f23fd9286 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" +package prometheus import ( "github.com/prometheus/client_golang/prometheus" diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go index 2f49f375b..3f885153e 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go @@ -8,4 +8,4 @@ // The Prometheus exporter ignores metrics from the Prometheus bridge. To // export these metrics, simply register them directly with the Prometheus // Handler. -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" +package prometheus diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/errors.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/errors.go index 7206acabf..445c9cb1f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/errors.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/errors.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" +package prometheus import "errors" diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go index bc0103893..38af8cd74 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" +package prometheus import ( "context" @@ -251,8 +251,11 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) { }) continue } - // resource attributes + scope attributes + scope name + scope version + scope schema url - n := len(c.resourceKeyVals.keys) + 3 + scopeMetrics.Scope.Attributes.Len() + // resource attributes + (if enabled) scope fields + n := len(c.resourceKeyVals.keys) + if !c.disableScopeInfo { + n += 3 + scopeMetrics.Scope.Attributes.Len() + } kv := keyVals{ keys: make([]string, 0, n), vals: make([]string, 0, n), diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/counter/counter.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/counter/counter.go index 87808d548..57c6acb78 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/counter/counter.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/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/prometheus/internal/counter" +package counter import "sync/atomic" diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/gen.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/gen.go index add058a2e..66d8b442b 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/gen.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/gen.go @@ -3,9 +3,9 @@ // Package internal provides internal functionality for the prometheus // package. -package internal // import "go.opentelemetry.io/otel/exporters/prometheus/internal" +package internal -//go:generate gotmpl --body=../../../internal/shared/counter/counter.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/prometheus/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 //go:generate gotmpl --body=../../../internal/shared/x/x.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/otel/exporters/prometheus\" }" --out=x/x.go diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/instrumentation.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/instrumentation.go index c995b982c..101c8db26 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/instrumentation.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/instrumentation.go @@ -3,7 +3,7 @@ // Package observ provides experimental observability instrumentation // for the prometheus exporter. -package observ // import "go.opentelemetry.io/otel/exporters/prometheus/internal/observ" +package observ import ( "context" @@ -17,8 +17,8 @@ import ( "go.opentelemetry.io/otel/exporters/prometheus/internal" "go.opentelemetry.io/otel/exporters/prometheus/internal/x" "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/prometheus/internal/version.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/version.go index 5616fe25a..cf8a159ff 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/version.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/version.go @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // Package internal provides internal utilities for the OpenTelemetry prometheus exporter. -package internal // import "go.opentelemetry.io/otel/exporters/prometheus/internal" +package internal // Version is the current release version of the OpenTelemetry prometheus // exporter in use. -const Version = "0.66.0" +const Version = "0.67.0" diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/features.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/features.go index fc9aeb08d..76b6fdebd 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/features.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/features.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package x // import "go.opentelemetry.io/otel/exporters/prometheus/internal/x" +package x import "strings" diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/x.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/x.go index 60d0baa72..476327e75 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/x.go +++ b/vendor/go.opentelemetry.io/otel/exporters/prometheus/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/prometheus]. -package x // import "go.opentelemetry.io/otel/exporters/prometheus/internal/x" +package x import ( "os" diff --git a/vendor/go.opentelemetry.io/otel/handler.go b/vendor/go.opentelemetry.io/otel/handler.go index 07623b679..1f45ea388 100644 --- a/vendor/go.opentelemetry.io/otel/handler.go +++ b/vendor/go.opentelemetry.io/otel/handler.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel import ( "go.opentelemetry.io/otel/internal/global" diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go index b4f85f44a..cbeb14fcd 100644 --- a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go +++ b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go @@ -10,7 +10,7 @@ this need this package would not need to exist and the `go.opentelemetry.io/otel/baggage` package would be the singular place where W3C baggage is handled. */ -package baggage // import "go.opentelemetry.io/otel/internal/baggage" +package baggage // List is the collection of baggage members. The W3C allows for duplicates, // but OpenTelemetry does not, therefore, this is represented as a map. diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/context.go b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go index 3aea9c491..f3bece165 100644 --- a/vendor/go.opentelemetry.io/otel/internal/baggage/context.go +++ b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package baggage // import "go.opentelemetry.io/otel/internal/baggage" +package baggage import "context" diff --git a/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go b/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go index 3f0ab3131..de294461c 100644 --- a/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go +++ b/vendor/go.opentelemetry.io/otel/internal/errorhandler/errorhandler.go @@ -5,7 +5,7 @@ // // This package has no OTel dependencies, allowing it to be imported by any // package in the module without creating import cycles. -package errorhandler // import "go.opentelemetry.io/otel/internal/errorhandler" +package errorhandler import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/handler.go b/vendor/go.opentelemetry.io/otel/internal/global/handler.go index 77d0425f5..6fb8034f8 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/handler.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/handler.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // Package global provides the OpenTelemetry global API. -package global // import "go.opentelemetry.io/otel/internal/global" +package global import ( "go.opentelemetry.io/otel/internal/errorhandler" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go index 55255cddf..4db3fdcde 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package global // import "go.opentelemetry.io/otel/internal/global" +package global import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go index 86d7f4ba0..8e1327354 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package global // import "go.opentelemetry.io/otel/internal/global" +package global import ( "log" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/meter.go b/vendor/go.opentelemetry.io/otel/internal/global/meter.go index 50043d669..48be49037 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/meter.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/meter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package global // import "go.opentelemetry.io/otel/internal/global" +package global import ( "container/list" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go index 38560ff99..90c462ef0 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package global // import "go.opentelemetry.io/otel/internal/global" +package global import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/state.go b/vendor/go.opentelemetry.io/otel/internal/global/state.go index 225c9e501..f8fcb82bc 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/state.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/state.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package global // import "go.opentelemetry.io/otel/internal/global" +package global import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/internal/global/trace.go b/vendor/go.opentelemetry.io/otel/internal/global/trace.go index bf5cf3119..45899f8c0 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/trace.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/trace.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package global // import "go.opentelemetry.io/otel/internal/global" +package global /* This file contains the forwarding implementation of the TracerProvider used as diff --git a/vendor/go.opentelemetry.io/otel/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal_logging.go index 6de7f2e4d..3f6b7b10d 100644 --- a/vendor/go.opentelemetry.io/otel/internal_logging.go +++ b/vendor/go.opentelemetry.io/otel/internal_logging.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel import ( "github.com/go-logr/logr" diff --git a/vendor/go.opentelemetry.io/otel/metric.go b/vendor/go.opentelemetry.io/otel/metric.go index 527d9aec8..30dbb4118 100644 --- a/vendor/go.opentelemetry.io/otel/metric.go +++ b/vendor/go.opentelemetry.io/otel/metric.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel import ( "go.opentelemetry.io/otel/internal/global" diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go index 1d21e2eb7..11e5b282f 100644 --- a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go index 9d45a4d41..f5577b0c5 100644 --- a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/metric/config.go b/vendor/go.opentelemetry.io/otel/metric/config.go index 889545e23..31a5da817 100644 --- a/vendor/go.opentelemetry.io/otel/metric/config.go +++ b/vendor/go.opentelemetry.io/otel/metric/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "slices" diff --git a/vendor/go.opentelemetry.io/otel/metric/doc.go b/vendor/go.opentelemetry.io/otel/metric/doc.go index 794e1a8ba..235e81f3a 100644 --- a/vendor/go.opentelemetry.io/otel/metric/doc.go +++ b/vendor/go.opentelemetry.io/otel/metric/doc.go @@ -201,4 +201,4 @@ fully implement all the API interfaces when a user updates their API. [OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/ [GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider */ -package metric // import "go.opentelemetry.io/otel/metric" +package metric diff --git a/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go index 1a9dc6809..10f361b5b 100644 --- a/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go +++ b/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go @@ -11,7 +11,7 @@ // the API package). // // [OpenTelemetry metric API]: https://pkg.go.dev/go.opentelemetry.io/otel/metric -package embedded // import "go.opentelemetry.io/otel/metric/embedded" +package embedded // MeterProvider is embedded in // [go.opentelemetry.io/otel/metric.MeterProvider]. diff --git a/vendor/go.opentelemetry.io/otel/metric/instrument.go b/vendor/go.opentelemetry.io/otel/metric/instrument.go index 2e79ab568..e8c1c96cb 100644 --- a/vendor/go.opentelemetry.io/otel/metric/instrument.go +++ b/vendor/go.opentelemetry.io/otel/metric/instrument.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/metric/meter.go b/vendor/go.opentelemetry.io/otel/metric/meter.go index 5606ec4bd..70ff4c731 100644 --- a/vendor/go.opentelemetry.io/otel/metric/meter.go +++ b/vendor/go.opentelemetry.io/otel/metric/meter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/metric/noop/noop.go b/vendor/go.opentelemetry.io/otel/metric/noop/noop.go index 634e73aee..80c0f2f22 100644 --- a/vendor/go.opentelemetry.io/otel/metric/noop/noop.go +++ b/vendor/go.opentelemetry.io/otel/metric/noop/noop.go @@ -10,7 +10,7 @@ // This implementation can be embedded in other implementations of the // OpenTelemetry metric API. Doing so will mean the implementation defaults to // no operation for methods it does not implement. -package noop // import "go.opentelemetry.io/otel/metric/noop" +package noop import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go index 2101f686a..2770ac2dc 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "context" @@ -158,6 +158,8 @@ type Float64Histogram interface { // Record adds an additional value to the distribution. // + // The incr value is expected to be non-negative. + // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. // diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go index 425c1a0d5..c8a739c90 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package metric // import "go.opentelemetry.io/otel/metric" +package metric import ( "context" @@ -158,6 +158,8 @@ type Int64Histogram interface { // Record adds an additional value to the distribution. // + // The incr value is expected to be non-negative. + // // Use the WithAttributeSet (or, if performance is not a concern, // the WithAttributes) option to include measurement attributes. // diff --git a/vendor/go.opentelemetry.io/otel/propagation.go b/vendor/go.opentelemetry.io/otel/propagation.go index 2fd949733..05e9b11ce 100644 --- a/vendor/go.opentelemetry.io/otel/propagation.go +++ b/vendor/go.opentelemetry.io/otel/propagation.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel import ( "go.opentelemetry.io/otel/internal/global" diff --git a/vendor/go.opentelemetry.io/otel/propagation/baggage.go b/vendor/go.opentelemetry.io/otel/propagation/baggage.go index d81b709a2..9d7ef7c89 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/baggage.go +++ b/vendor/go.opentelemetry.io/otel/propagation/baggage.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package propagation // import "go.opentelemetry.io/otel/propagation" +package propagation import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/propagation/doc.go b/vendor/go.opentelemetry.io/otel/propagation/doc.go index 33a3baf15..6e2bbbb18 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/doc.go +++ b/vendor/go.opentelemetry.io/otel/propagation/doc.go @@ -10,4 +10,4 @@ package is the W3C Trace Context encoding (https://www.w3.org/TR/trace-context/), and W3C Baggage (https://www.w3.org/TR/baggage/). */ -package propagation // import "go.opentelemetry.io/otel/propagation" +package propagation diff --git a/vendor/go.opentelemetry.io/otel/propagation/propagation.go b/vendor/go.opentelemetry.io/otel/propagation/propagation.go index 0a32c59aa..a3891fbe7 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/propagation.go +++ b/vendor/go.opentelemetry.io/otel/propagation/propagation.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package propagation // import "go.opentelemetry.io/otel/propagation" +package propagation import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go index 11f404deb..ffaa90303 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go +++ b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package propagation // import "go.opentelemetry.io/otel/propagation" +package propagation import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/requirements.txt b/vendor/go.opentelemetry.io/otel/requirements.txt index 7c541dee7..b2666ab48 100644 --- a/vendor/go.opentelemetry.io/otel/requirements.txt +++ b/vendor/go.opentelemetry.io/otel/requirements.txt @@ -1 +1 @@ -codespell==2.4.2 +codespell==2.4.3 diff --git a/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go b/vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go index a4faa6a03..39b34eabe 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 f2cdf3c65..8baf8dbb3 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 34852a47b..1fd06db75 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 000000000..fe9ddc96d --- /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 000000000..9955e9072 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/attrnorm/truncate.go @@ -0,0 +1,232 @@ +// 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 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 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 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() +} 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 694b64a31..13ff34b27 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 13347e560..e829d1794 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" diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go b/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go index e6f5cfb2a..f52e7ea54 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 63b88f086..1d6f6a089 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 dda4e086d..444a8cfda 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 51e168c75..61410b330 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 a6c403797..132664a7e 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 993f001ae..fb124052c 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 9f2389376..f7e547617 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 1ab694678..32913a6e5 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 b50f5c153..a9efd20d1 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 ce97ab1bf..48f2b464c 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 dacac3eba..e1001e4dc 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 000000000..da5eb241c --- /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 ba5cd1a6b..a6cfdf44f 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 790496027..9a0be05a2 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 590b089a8..c7d1645b6 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 1969cb42c..7bec41529 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 dfb4964d9..31f7afef9 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 a35f3bcc1..696fc21ca 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" 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 eb69e9650..675c23fc3 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,23 @@ 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 { +func (m *limitedSyncMap[V]) LoadOrStoreAttr(fltrAttr attribute.Set, newValue func(attribute.Set) V) V { actual, loaded := m.Load(fltrAttr.Equivalent()) 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() @@ -248,7 +248,7 @@ func (m *limitedSyncMap) LoadOrStoreAttr(fltrAttr attribute.Set, newValue func(a // concurrently. actual, loaded = m.Load(fltrAttr.Equivalent()) if loaded { - return actual + return actual.(V) } if m.aggLimit > 0 && m.len >= m.aggLimit-1 { @@ -258,17 +258,17 @@ func (m *limitedSyncMap) LoadOrStoreAttr(fltrAttr attribute.Set, newValue func(a 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 7b7225e6e..c0399c408 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 7adfcaf85..47ec26dba 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" 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 25d709948..45b620419 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 767b1d6dc..77c20a315 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" @@ -412,12 +412,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 +491,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 e4f9409bc..9aac90f03 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,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" 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 50c82ff32..17807e11e 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 @@ -114,7 +112,7 @@ func (s *deltaHistogram[N]) measure( ) { 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(fltrAttr, func(attr attribute.Set) *histogramPoint[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) hPt := &histogramPoint[N]{ @@ -131,7 +129,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 @@ -171,7 +169,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 +210,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 +250,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,7 +279,7 @@ func newCumulativeHistogram[N int64 | float64]( noSum: noSum, bounds: b, newRes: r, - values: limitedSyncMap{aggLimit: limit}, + values: limitedSyncMap[*hotColdHistogramPoint[N]]{aggLimit: limit}, } } @@ -288,7 +289,7 @@ func (s *cumulativeHistogram[N]) measure( fltrAttr attribute.Set, droppedAttr []attribute.KeyValue, ) { - h := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + h := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) *hotColdHistogramPoint[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) hPt := &hotColdHistogramPoint[N]{ @@ -313,7 +314,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 @@ -350,9 +351,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 +374,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, - } - if !s.noSum { - newPt.Sum = val.hotColdPoint[readIdx].total.load() + // Concurrent writers can grow s.values between Len() and Range. + // Cold-path grow. + if i >= len(hDPts) { + hDPts = append(hDPts, metricdata.HistogramDataPoint[N]{}) } - 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()) - } + 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 { + 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 && 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 2af252ec5..0fddc9dcc 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,7 +24,7 @@ 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( @@ -33,7 +33,7 @@ func (s *lastValueMap[N]) measure( fltrAttr attribute.Set, droppedAttr []attribute.KeyValue, ) { - lv := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + lv := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) *lastValuePoint[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) p := &lastValuePoint[N]{ @@ -44,7 +44,7 @@ func (s *lastValueMap[N]) measure( } p.value.Store(value) return p - }).(*lastValuePoint[N]) + }) lv.value.Store(value) if !lv.dropExemplars { @@ -61,12 +61,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}, }, }, } @@ -148,8 +148,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/limit.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go index c19a1aff6..426a8b275 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 0cd3c9457..bee5ca370 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,8 +21,8 @@ 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( @@ -31,7 +31,7 @@ func (s *sumValueMap[N]) measure( fltrAttr attribute.Set, droppedAttr []attribute.KeyValue, ) { - sv := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) any { + sv := s.values.LoadOrStoreAttr(fltrAttr, func(attr attribute.Set) *sumValue[N] { r := s.newRes(attr) _, isDrop := r.(*dropRes[N]) return &sumValue[N]{ @@ -40,7 +40,7 @@ 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. @@ -63,12 +63,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}, }, }, } @@ -140,8 +140,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 000000000..fe9ddc96d --- /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 000000000..5f077dfe9 --- /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 c580dcc30..b09748a79 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 3be234a41..8542fd94b 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 6cd213b5f..6dbf906c8 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 ea452be6c..6ddf01473 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 000000000..a8268702a --- /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 8e3c62a13..f501984ae 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,36 +1,38 @@ // 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 // user has enabled the feature. Otherwise, if the feature is not enabled, a @@ -40,11 +42,13 @@ func (f Feature[T]) Lookup() (v T, ok bool) { // // > 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 7e0cccdff..b98e255d8 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 e9a2d5957..8c54974e0 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 af835e9d9..1caed336e 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 2ac840ff3..8d7c89d85 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 c1c2e3e2f..9f7712bd5 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 09d10eeb5..f04c2ddce 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 fd4cdccd0..9f9f01f43 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 556afcea6..505c9ad93 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 a7931412b..b183cf486 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 3e1bea4b4..4c1cd75e2 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.45.0" } diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/view.go b/vendor/go.opentelemetry.io/otel/sdk/metric/view.go index 13fb7143c..3f98928f9 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 c02aeefdd..8754313af 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 28823edd5..d5f6dc0a6 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 a3d647d92..c5ffa45d0 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 ce03e24c4..c81163bf8 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 64939a271..f5a79d3fe 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 ac5691c08..0eeb1e2ae 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 cb38fa1a8..47219be22 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 4c1c30f25..bcd174342 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 b09fde3b7..81ece5b34 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 e239ead02..c058f0d26 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 4a26096c8..26cf6a5d1 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 c95d87685..d955c2c90 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 63ad2fa4e..9f6ca8211 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 2b8ca20b3..e9e4a0384 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 4c0def414..6af491567 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 3d703c5d9..f12876d17 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 a1763267c..ad9285854 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 1cd87c398..ba5e48db2 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 25f629532..e2c19c2b3 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 ebd50826d..9b7648957 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 b015f8233..a578fc325 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 f715be53e..68ab274d2 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 { 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 f9f2a6c2c..2b9560ee7 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 b502c7d47..b292fa311 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 60a7ed134..49eac0459 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 8c308dd60..1f62b528c 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 3649322a6..be22ac632 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 58f68df44..1385ae6fc 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 c725ebf37..896ed517f 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 b542121e6..64fd5238d 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 cf4b5d481..89922e4b8 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,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" ) var measureAttrsPool = sync.Pool{ 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 5aae89e88..3428aa894 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 c03bdc90f..d4a07a714 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 9d90c2eda..6b2368413 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 9b672a1d7..b0fa94ed2 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 5a4c74318..c79177ae8 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 771e427a4..e9bec4394 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" @@ -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 63aa33780..8893dc39f 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 d1d9af29d..0aae5f5bb 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" ) @@ -269,7 +268,8 @@ 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) } } @@ -329,7 +329,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 +340,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 +384,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 +516,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 @@ -863,7 +690,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 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 6bdda3d94..fad839a24 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 348ee0e80..5ee15a884 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 af7f9177f..ffd093a2f 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 e1d08fd4d..be576ffe0 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 e12fa67e6..4aa2d562f 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 ca63038f3..11e3d5b3f 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 12b384b08..6ee1b3f98 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 218dce1f5..1619fb3fa 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.45.0" } diff --git a/vendor/go.opentelemetry.io/otel/semconv/internal/metricpool/pool.go b/vendor/go.opentelemetry.io/otel/semconv/internal/metricpool/pool.go new file mode 100644 index 000000000..c5f5ad46e --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/internal/metricpool/pool.go @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package metricpool provides shared pools for semantic convention metric +// measurement options. +package metricpool + +import ( + "sync" + + "go.opentelemetry.io/otel/metric" +) + +var ( + addOptionsPool = sync.Pool{New: func() any { + o := make([]metric.AddOption, 0, 1) + return &o + }} + recOptionsPool = sync.Pool{New: func() any { + o := make([]metric.RecordOption, 0, 1) + return &o + }} +) + +// AddOptions returns a pooled AddOption slice. +func AddOptions() *[]metric.AddOption { + return addOptionsPool.Get().(*[]metric.AddOption) +} + +// PutAddOptions clears, resets, and returns o to the shared AddOption pool. +func PutAddOptions(o *[]metric.AddOption) { + clear(*o) + *o = (*o)[:0] + addOptionsPool.Put(o) +} + +// RecordOptions returns a pooled RecordOption slice. +func RecordOptions() *[]metric.RecordOption { + return recOptionsPool.Get().(*[]metric.RecordOption) +} + +// PutRecordOptions clears, resets, and returns o to the shared RecordOption +// pool. +func PutRecordOptions(o *[]metric.RecordOption) { + clear(*o) + *o = (*o)[:0] + recOptionsPool.Put(o) +} diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go index a9a15a1da..ec8f3609d 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/attribute_group.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" +package semconv import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go index 461331a55..4fd1a94f4 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/doc.go @@ -6,4 +6,4 @@ // OpenTelemetry semantic conventions are agreed standardized naming // patterns for OpenTelemetry things. This package represents the v1.21.0 // version of the OpenTelemetry semantic conventions. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" +package semconv diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go index c09d9317e..20b495e5a 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/event.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" +package semconv import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go index 5184ee339..3fe84aae0 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/exception.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" +package semconv const ( // ExceptionEventName is the name of the Span event representing an exception. diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go index f7aaa50b9..28f31ba26 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/resource.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" +package semconv import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go index be07217d8..cef48a6b8 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/schema.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.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 diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go index 55698cc44..fbc399f25 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.21.0/trace.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.21.0" +package semconv import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go index 2fcab2435..d20ad49ef 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.37.0" +package semconv import "go.opentelemetry.io/otel/attribute" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/doc.go index 111010321..b67c64b96 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/doc.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/doc.go @@ -6,4 +6,4 @@ // OpenTelemetry semantic conventions are agreed standardized naming // patterns for OpenTelemetry things. This package represents the v1.37.0 // version of the OpenTelemetry semantic conventions. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.37.0" +package semconv diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/error_type.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/error_type.go index 267979c05..719241429 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/error_type.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/error_type.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.37.0" +package semconv import ( "reflect" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/exception.go index e67469a4f..3fe84aae0 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/exception.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/exception.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.37.0" +package semconv const ( // ExceptionEventName is the name of the Span event representing an exception. diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/schema.go index f8a0b7044..0009b185b 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/schema.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/schema.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.37.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 diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md deleted file mode 100644 index ba52cadf7..000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md +++ /dev/null @@ -1,17 +0,0 @@ - -# Migration from v1.40.0 to v1.41.0 - -The `go.opentelemetry.io/otel/semconv/v1.41.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.40.0` with the following exceptions. - -## Removed - -The following declarations have been removed. -Refer to the [OpenTelemetry Semantic Conventions documentation] for deprecation instructions. - -If the type is not listed in the documentation as deprecated, it has been removed in this version due to lack of applicability or use. -If you use any of these non-deprecated declarations in your Go application, please [open an issue] describing your use-case. - -- `DeploymentEnvironmentName` - -[OpenTelemetry Semantic Conventions documentation]: https://github.com/open-telemetry/semantic-conventions -[open an issue]: https://github.com/open-telemetry/opentelemetry-go/issues/new?template=Blank+issue diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md deleted file mode 100644 index 8353bb715..000000000 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Semconv v1.41.0 - -[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.41.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.41.0) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/MIGRATION.md b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/MIGRATION.md new file mode 100644 index 000000000..54d8e7d70 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/MIGRATION.md @@ -0,0 +1,4 @@ + +# Migration from v1.42.0 to v1.43.0 + +The `go.opentelemetry.io/otel/semconv/v1.43.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.42.0`. diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/README.md new file mode 100644 index 000000000..20e64d795 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/README.md @@ -0,0 +1,3 @@ +# Semconv v1.43.0 + +[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.43.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.43.0) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/attribute_group.go similarity index 90% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/attribute_group.go index 7cee08680..770388dfc 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/attribute_group.go @@ -3,7 +3,7 @@ // Code generated from semantic convention specification. DO NOT EDIT. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" +package semconv import "go.opentelemetry.io/otel/attribute" @@ -22,7 +22,7 @@ const ( // [Activity lifecycle callbacks], and from which the `OS identifiers` are // derived. // - // [Activity lifecycle callbacks]: https://developer.android.com/guide/components/activities/activity-lifecycle#lc + // [Activity lifecycle callbacks]: https://developer.android.com/guide/components/activities/activity-lifecycle#lifecycle-callbacks AndroidAppStateKey = attribute.Key("android.app.state") // AndroidOSAPILevelKey is the attribute Key conforming to the @@ -87,6 +87,24 @@ const ( // "9f2b833506aa6973a92fde9733e6271f", "my-app-1.0.0-code-123" AppBuildIDKey = attribute.Key("app.build_id") + // AppCrashIDKey is the attribute Key conforming to the "app.crash.id" semantic + // conventions. It represents a unique identifier representing an instance of an + // end-user facing app crash. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "083d3d2d-9a0e-47f8-be3d-bc3c5538ba38" + // Note: Its value MAY be meaningful and be used as a reference for telemetry + // and metadata recorded by + // the same instrumentation (e.g. it is an ID generated by an external source + // that captured the crash). + // It MAY come from a source external to the instrumentation such that it can be + // used to look up additional + // data from other sources as well as facilitate deduplication. + AppCrashIDKey = attribute.Key("app.crash.id") + // AppInstallationIDKey is the attribute Key conforming to the // "app.installation.id" semantic conventions. It represents a unique identifier // representing the installation of an application on a specific device. @@ -252,6 +270,13 @@ func AppBuildID(val string) attribute.KeyValue { return AppBuildIDKey.String(val) } +// AppCrashID returns an attribute KeyValue conforming to the "app.crash.id" +// semantic conventions. It represents a unique identifier representing an +// instance of an end-user facing app crash. +func AppCrashID(val string) attribute.KeyValue { + return AppCrashIDKey.String(val) +} + // AppInstallationID returns an attribute KeyValue conforming to the // "app.installation.id" semantic conventions. It represents a unique identifier // representing the installation of an application on a specific device. @@ -1744,6 +1769,19 @@ const ( // Examples: 1000, 1002 AzureCosmosDBResponseSubStatusCodeKey = attribute.Key("azure.cosmosdb.response.sub_status_code") + // AzureResourceGroupNameKey is the attribute Key conforming to the + // "azure.resource_group.name" semantic conventions. It represents the name of + // the Azure [resource group] the resource belongs to. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "my-resource-group", "rg-myapp-prod" + // + // [resource group]: https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal + AzureResourceGroupNameKey = attribute.Key("azure.resource_group.name") + // AzureResourceProviderNamespaceKey is the attribute Key conforming to the // "azure.resource_provider.namespace" semantic conventions. It represents the // [Azure Resource Provider Namespace] as recognized by the client. @@ -1808,6 +1846,15 @@ func AzureCosmosDBResponseSubStatusCode(val int) attribute.KeyValue { return AzureCosmosDBResponseSubStatusCodeKey.Int(val) } +// AzureResourceGroupName returns an attribute KeyValue conforming to the +// "azure.resource_group.name" semantic conventions. It represents the name of +// the Azure [resource group] the resource belongs to. +// +// [resource group]: https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal +func AzureResourceGroupName(val string) attribute.KeyValue { + return AzureResourceGroupNameKey.String(val) +} + // AzureResourceProviderNamespace returns an attribute KeyValue conforming to the // "azure.resource_provider.namespace" semantic conventions. It represents the // [Azure Resource Provider Namespace] as recognized by the client. @@ -1871,6 +1918,19 @@ const ( // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface BrowserBrandsKey = attribute.Key("browser.brands") + // BrowserDocumentURLFullKey is the attribute Key conforming to the + // "browser.document.url.full" semantic conventions. It represents the absolute + // URL of the current browser document according to [RFC3986]. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "https://www.example.com/search?q=OpenTelemetry#SemConv" + // + // [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986 + BrowserDocumentURLFullKey = attribute.Key("browser.document.url.full") + // BrowserLanguageKey is the attribute Key conforming to the "browser.language" // semantic conventions. It represents the preferred language of the user using // the browser. @@ -1933,6 +1993,15 @@ func BrowserBrands(val ...string) attribute.KeyValue { return BrowserBrandsKey.StringSlice(val) } +// BrowserDocumentURLFull returns an attribute KeyValue conforming to the +// "browser.document.url.full" semantic conventions. It represents the absolute +// URL of the current browser document according to [RFC3986]. +// +// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986 +func BrowserDocumentURLFull(val string) attribute.KeyValue { + return BrowserDocumentURLFullKey.String(val) +} + // BrowserLanguage returns an attribute KeyValue conforming to the // "browser.language" semantic conventions. It represents the preferred language // of the user using the browser. @@ -2107,7 +2176,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "BUILD", "RUN", "SYNC" CICDPipelineActionNameKey = attribute.Key("cicd.pipeline.action.name") @@ -2118,7 +2187,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "Build and Test", "Lint", "Deploy Go Project", // "deploy_to_environment" @@ -2130,9 +2199,9 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // - // Examples: "success", "failure", "timeout", "skipped" + // Examples: "success", "failure", "timeout", "skip" CICDPipelineResultKey = attribute.Key("cicd.pipeline.result") // CICDPipelineRunIDKey is the attribute Key conforming to the @@ -2141,7 +2210,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "120912" CICDPipelineRunIDKey = attribute.Key("cicd.pipeline.run.id") @@ -2152,7 +2221,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "pending", "executing", "finalizing" CICDPipelineRunStateKey = attribute.Key("cicd.pipeline.run.state") @@ -2164,7 +2233,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763?pr=1075" @@ -2180,7 +2249,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "Run GoLang Linter", "Go Build", "go-test", "deploy_binary" // @@ -2193,7 +2262,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "12097" // Note: For a given pipeline run and task, the `cicd.pipeline.task.run.id` MUST @@ -2209,9 +2278,9 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // - // Examples: "success", "failure", "timeout", "skipped" + // Examples: "success", "failure", "timeout", "skip" CICDPipelineTaskRunResultKey = attribute.Key("cicd.pipeline.task.run.result") // CICDPipelineTaskRunURLFullKey is the attribute Key conforming to the @@ -2221,7 +2290,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763/job/26920038674?pr=1075" @@ -2235,52 +2304,52 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // 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. + // component of the CI/CD system. // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "controller", "scheduler", "agent" CICDSystemComponentKey = attribute.Key("cicd.system.component") // CICDWorkerIDKey is the attribute Key conforming to the "cicd.worker.id" // semantic conventions. It represents the unique identifier of a worker within - // a CICD system. + // a CI/CD system. // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "abc123", "10.0.1.2", "controller" CICDWorkerIDKey = attribute.Key("cicd.worker.id") // CICDWorkerNameKey is the attribute Key conforming to the "cicd.worker.name" - // semantic conventions. It represents the name of a worker within a CICD + // semantic conventions. It represents the name of a worker within a CI/CD // system. // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "agent-abc", "controller", "Ubuntu LTS" CICDWorkerNameKey = attribute.Key("cicd.worker.name") // CICDWorkerStateKey is the attribute Key conforming to the "cicd.worker.state" - // semantic conventions. It represents the state of a CICD worker / agent. + // semantic conventions. It represents the state of a CI/CD worker / agent. // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // - // Examples: "idle", "busy", "down" + // Examples: "available", "busy", "offline" CICDWorkerStateKey = attribute.Key("cicd.worker.state") // CICDWorkerURLFullKey is the attribute Key conforming to the @@ -2290,7 +2359,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "https://cicd.example.org/worker/abc123" // @@ -2352,21 +2421,21 @@ func CICDPipelineTaskRunURLFull(val string) attribute.KeyValue { // CICDSystemComponent returns an attribute KeyValue conforming to the // "cicd.system.component" semantic conventions. It represents the name of a -// component of the CICD system. +// component of the CI/CD system. func CICDSystemComponent(val string) attribute.KeyValue { return CICDSystemComponentKey.String(val) } // CICDWorkerID returns an attribute KeyValue conforming to the "cicd.worker.id" // semantic conventions. It represents the unique identifier of a worker within a -// CICD system. +// CI/CD system. func CICDWorkerID(val string) attribute.KeyValue { return CICDWorkerIDKey.String(val) } // CICDWorkerName returns an attribute KeyValue conforming to the // "cicd.worker.name" semantic conventions. It represents the name of a worker -// within a CICD system. +// within a CI/CD system. func CICDWorkerName(val string) attribute.KeyValue { return CICDWorkerNameKey.String(val) } @@ -2384,39 +2453,39 @@ func CICDWorkerURLFull(val string) attribute.KeyValue { // Enum values for cicd.pipeline.action.name var ( // The pipeline run is executing a build. - // Stability: development + // Stability: release_candidate CICDPipelineActionNameBuild = CICDPipelineActionNameKey.String("BUILD") // The pipeline run is executing. - // Stability: development + // Stability: release_candidate CICDPipelineActionNameRun = CICDPipelineActionNameKey.String("RUN") // The pipeline run is executing a sync. - // Stability: development + // Stability: release_candidate CICDPipelineActionNameSync = CICDPipelineActionNameKey.String("SYNC") ) // Enum values for cicd.pipeline.result var ( // The pipeline run finished successfully. - // Stability: development + // Stability: release_candidate 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 + // Stability: release_candidate CICDPipelineResultFailure = CICDPipelineResultKey.String("failure") - // The pipeline run failed due to an error in the CICD system, eg. due to the + // The pipeline run failed due to an error in the CI/CD system, eg. due to the // worker being killed. - // Stability: development + // Stability: release_candidate CICDPipelineResultError = CICDPipelineResultKey.String("error") // A timeout caused the pipeline run to be interrupted. - // Stability: development + // Stability: release_candidate CICDPipelineResultTimeout = CICDPipelineResultKey.String("timeout") // The pipeline run was cancelled, eg. by a user manually cancelling the // pipeline run. - // Stability: development + // Stability: release_candidate CICDPipelineResultCancellation = CICDPipelineResultKey.String("cancellation") // The pipeline run was skipped, eg. due to a precondition not being met. - // Stability: development + // Stability: release_candidate CICDPipelineResultSkip = CICDPipelineResultKey.String("skip") ) @@ -2426,66 +2495,66 @@ var ( // the execution of the run starts (eg. time spent in a queue, provisioning // agents, creating run resources). // - // Stability: development + // Stability: release_candidate CICDPipelineRunStatePending = CICDPipelineRunStateKey.String("pending") // The executing state spans the execution of any run tasks (eg. build, test). - // Stability: development + // Stability: release_candidate CICDPipelineRunStateExecuting = CICDPipelineRunStateKey.String("executing") // The finalizing state spans from when the run has finished executing (eg. // cleanup of run resources). - // Stability: development + // Stability: release_candidate CICDPipelineRunStateFinalizing = CICDPipelineRunStateKey.String("finalizing") ) // Enum values for cicd.pipeline.task.run.result var ( // The task run finished successfully. - // Stability: development + // Stability: release_candidate CICDPipelineTaskRunResultSuccess = CICDPipelineTaskRunResultKey.String("success") // The task 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 task run. - // Stability: development + // Stability: release_candidate CICDPipelineTaskRunResultFailure = CICDPipelineTaskRunResultKey.String("failure") - // The task run failed due to an error in the CICD system, eg. due to the worker - // being killed. - // Stability: development + // The task run failed due to an error in the CI/CD system, eg. due to the + // worker being killed. + // Stability: release_candidate CICDPipelineTaskRunResultError = CICDPipelineTaskRunResultKey.String("error") // A timeout caused the task run to be interrupted. - // Stability: development + // Stability: release_candidate CICDPipelineTaskRunResultTimeout = CICDPipelineTaskRunResultKey.String("timeout") // The task run was cancelled, eg. by a user manually cancelling the task run. - // Stability: development + // Stability: release_candidate CICDPipelineTaskRunResultCancellation = CICDPipelineTaskRunResultKey.String("cancellation") // The task run was skipped, eg. due to a precondition not being met. - // Stability: development + // Stability: release_candidate CICDPipelineTaskRunResultSkip = CICDPipelineTaskRunResultKey.String("skip") ) // Enum values for cicd.pipeline.task.type var ( // build - // Stability: development + // Stability: release_candidate CICDPipelineTaskTypeBuild = CICDPipelineTaskTypeKey.String("build") // test - // Stability: development + // Stability: release_candidate CICDPipelineTaskTypeTest = CICDPipelineTaskTypeKey.String("test") // deploy - // Stability: development + // Stability: release_candidate 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 + // The worker is not performing work for the CI/CD system. It is available to + // the CI/CD system to perform work on (online / idle). + // Stability: release_candidate CICDWorkerStateAvailable = CICDWorkerStateKey.String("available") - // The worker is performing work for the CICD system. - // Stability: development + // The worker is performing work for the CI/CD system. + // Stability: release_candidate CICDWorkerStateBusy = CICDWorkerStateKey.String("busy") - // The worker is not available to the CICD system (disconnected / down). - // Stability: development + // The worker is not available to the CI/CD system (disconnected / down). + // Stability: release_candidate CICDWorkerStateOffline = CICDWorkerStateKey.String("offline") ) @@ -2544,7 +2613,9 @@ const ( // RequirementLevel: Recommended // Stability: Development // - // Examples: "111111111111", "opentelemetry" + // Examples: "111111111111", "opentelemetry", + // "22222222-2222-2222-2222-222222222222" + // Note: For Azure, this is the subscription ID. CloudAccountIDKey = attribute.Key("cloud.account.id") // CloudAvailabilityZoneKey is the attribute Key conforming to the @@ -3436,7 +3507,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "a3bf90e006b2" // @@ -3472,7 +3543,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "gcr.io/opentelemetry/operator" ContainerImageNameKey = attribute.Key("container.image.name") @@ -3483,7 +3554,7 @@ const ( // // Type: string[] // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: // "example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb", @@ -3502,7 +3573,7 @@ const ( // // Type: string[] // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "v1.27.1", "3.5.7-0" // @@ -3691,7 +3762,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "user", "system" CPUModeKey = attribute.Key("cpu.mode") @@ -3707,29 +3778,26 @@ func CPULogicalNumber(val int) attribute.KeyValue { // Enum values for cpu.mode var ( // User - // Stability: development + // Stability: release_candidate CPUModeUser = CPUModeKey.String("user") // System - // Stability: development + // Stability: release_candidate CPUModeSystem = CPUModeKey.String("system") // Nice - // Stability: development + // Stability: release_candidate CPUModeNice = CPUModeKey.String("nice") // Idle - // Stability: development + // Stability: release_candidate CPUModeIdle = CPUModeKey.String("idle") // IO Wait - // Stability: development + // Stability: release_candidate CPUModeIOWait = CPUModeKey.String("iowait") // Interrupt - // Stability: development + // Stability: release_candidate CPUModeInterrupt = CPUModeKey.String("interrupt") // Steal - // Stability: development + // Stability: release_candidate CPUModeSteal = CPUModeKey.String("steal") - // Kernel - // Stability: development - CPUModeKernel = CPUModeKey.String("kernel") ) // Namespace: db @@ -3803,15 +3871,46 @@ const ( // 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. + // database operations included in a batch operation. // // Type: int // RequirementLevel: Recommended // Stability: Stable // // 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`. + // Note: Except for empty batch requests described below, a batch operation + // contains two + // or more database operations explicitly submitted as separate operations in a + // single + // client call, protocol message, or database command. + // + // Requests to batch APIs that contain only one operation SHOULD be modeled as + // single + // operations, not as batch operations. + // + // A database call is not a batch operation solely because one operation accepts + // multiple operands, such as keys, rows, documents, points, or other data + // elements, + // including Redis [`MGET`] with + // multiple keys. + // + // In batch APIs that execute the same parameterized operation with parameter + // sets, + // each parameter set represents one database operation for determining whether + // the + // request is a batch operation. Requests with only one parameter set SHOULD be + // modeled + // as single operations, not as batch operations. + // + // `db.operation.batch.size` SHOULD be set to the number of operations in the + // batch. + // It SHOULD NOT be set for non-batch operations. + // + // A request to execute a batch operation with no operations SHOULD also be + // treated + // as a batch operation, and `db.operation.batch.size` SHOULD be set to `0`. + // + // [`MGET`]: https://redis.io/docs/latest/commands/mget/ DBOperationBatchSizeKey = attribute.Key("db.operation.batch.size") // DBOperationNameKey is the attribute Key conforming to the "db.operation.name" @@ -3980,7 +4079,7 @@ func DBNamespace(val string) attribute.KeyValue { // 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. +// database operations included in a batch operation. func DBOperationBatchSize(val int) attribute.KeyValue { return DBOperationBatchSizeKey.Int(val) } @@ -4511,7 +4610,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "read" DiskIODirectionKey = attribute.Key("disk.io.direction") @@ -4520,10 +4619,10 @@ const ( // Enum values for disk.io.direction var ( // read - // Stability: development + // Stability: release_candidate DiskIODirectionRead = DiskIODirectionKey.String("read") // write - // Stability: development + // Stability: release_candidate DiskIODirectionWrite = DiskIODirectionKey.String("write") ) @@ -5496,6 +5595,45 @@ const ( // Examples: "256383" FileInodeKey = attribute.Key("file.inode") + // FileLockMechanismKey is the attribute Key conforming to the + // "file.lock.mechanism" semantic conventions. It represents the lock mechanism + // such as noted by [POSIX]. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "POSIX", "FLOCK", "DELEG", "LEASE" + // + // [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html + FileLockMechanismKey = attribute.Key("file.lock.mechanism") + + // FileLockModeKey is the attribute Key conforming to the "file.lock.mode" + // semantic conventions. It represents the mode of lock or operation such as + // documented by [POSIX]. + // + // Type: string + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "ADVISORY", "MANDATORY", "BREAKING", "ACTIVE", "BREAKER" + // + // [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html + FileLockModeKey = attribute.Key("file.lock.mode") + + // FileLockTypeKey is the attribute Key conforming to the "file.lock.type" + // semantic conventions. It represents the lock type as represented by i.e. + // [POSIX]'s l_type. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "read" + // + // [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html + FileLockTypeKey = attribute.Key("file.lock.type") + // FileModeKey is the attribute Key conforming to the "file.mode" semantic // conventions. It represents the mode of the file in octal representation. // @@ -5652,6 +5790,24 @@ func FileInode(val string) attribute.KeyValue { return FileInodeKey.String(val) } +// FileLockMechanism returns an attribute KeyValue conforming to the +// "file.lock.mechanism" semantic conventions. It represents the lock mechanism +// such as noted by [POSIX]. +// +// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html +func FileLockMechanism(val string) attribute.KeyValue { + return FileLockMechanismKey.String(val) +} + +// FileLockMode returns an attribute KeyValue conforming to the "file.lock.mode" +// semantic conventions. It represents the mode of lock or operation such as +// documented by [POSIX]. +// +// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html +func FileLockMode(val string) attribute.KeyValue { + return FileLockModeKey.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 { @@ -5706,6 +5862,16 @@ func FileSymbolicLinkTargetPath(val string) attribute.KeyValue { return FileSymbolicLinkTargetPathKey.String(val) } +// Enum values for file.lock.type +var ( + // read + // Stability: development + FileLockTypeRead = FileLockTypeKey.String("read") + // write + // Stability: development + FileLockTypeWrite = FileLockTypeKey.String("write") +) + // Namespace: gcp const ( // GCPAppHubApplicationContainerKey is the attribute Key conforming to the @@ -6152,6 +6318,13 @@ func GCPGCEInstanceHostname(val string) attribute.KeyValue { return GCPGCEInstanceHostnameKey.String(val) } +// GCPGCEInstanceLabels returns an attribute KeyValue conforming to the +// "gcp.gce.instance.labels" semantic conventions. It represents the GCE instance +// labels, `` being the label name and the value being the label value. +func GCPGCEInstanceLabels(key string, val string) attribute.KeyValue { + return attribute.String("gcp.gce.instance.labels."+key, 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 @@ -6314,1182 +6487,6 @@ var ( GCPAppHubDestinationWorkloadEnvironmentTypeDevelopment = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("DEVELOPMENT") ) -// Namespace: gen_ai -const ( - // GenAIAgentDescriptionKey is the attribute Key conforming to the - // "gen_ai.agent.description" semantic conventions. It represents the free-form - // description of the GenAI agent provided by the application. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Helps with math problems", "Generates fiction stories" - GenAIAgentDescriptionKey = attribute.Key("gen_ai.agent.description") - - // GenAIAgentIDKey is the attribute Key conforming to the "gen_ai.agent.id" - // semantic conventions. It represents the unique identifier of the GenAI agent. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "asst_5j66UpCpwteGg4YSxUnt7lPY" - GenAIAgentIDKey = attribute.Key("gen_ai.agent.id") - - // GenAIAgentNameKey is the attribute Key conforming to the "gen_ai.agent.name" - // semantic conventions. It represents the human-readable name of the GenAI - // agent provided by the application. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Math Tutor", "Fiction Writer" - GenAIAgentNameKey = attribute.Key("gen_ai.agent.name") - - // GenAIAgentVersionKey is the attribute Key conforming to the - // "gen_ai.agent.version" semantic conventions. It represents the version of the - // GenAI agent. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "1.0.0", "2025-05-01" - GenAIAgentVersionKey = attribute.Key("gen_ai.agent.version") - - // GenAIConversationIDKey is the attribute Key conforming to the - // "gen_ai.conversation.id" semantic conventions. It represents the unique - // identifier for a conversation (session, thread), used to store and correlate - // messages within this conversation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "conv_5j66UpCpwteGg4YSxUnt7lPY" - GenAIConversationIDKey = attribute.Key("gen_ai.conversation.id") - - // GenAIDataSourceIDKey is the attribute Key conforming to the - // "gen_ai.data_source.id" semantic conventions. It represents the data source - // identifier. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "H7STPQYOND" - // Note: Data sources are used by AI agents and RAG applications to store - // grounding data. A data source may be an external database, object store, - // document collection, website, or any other storage system used by the GenAI - // agent or application. The `gen_ai.data_source.id` SHOULD match the identifier - // used by the GenAI system rather than a name specific to the external storage, - // such as a database or object store. Semantic conventions referencing - // `gen_ai.data_source.id` MAY also leverage additional attributes, such as - // `db.*`, to further identify and describe the data source. - GenAIDataSourceIDKey = attribute.Key("gen_ai.data_source.id") - - // GenAIEmbeddingsDimensionCountKey is the attribute Key conforming to the - // "gen_ai.embeddings.dimension.count" semantic conventions. It represents the - // number of dimensions the resulting output embeddings should have. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 512, 1024 - GenAIEmbeddingsDimensionCountKey = attribute.Key("gen_ai.embeddings.dimension.count") - - // GenAIEvaluationExplanationKey is the attribute Key conforming to the - // "gen_ai.evaluation.explanation" semantic conventions. It represents a - // free-form explanation for the assigned score provided by the evaluator. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "The response is factually accurate but lacks sufficient detail to - // fully address the question." - GenAIEvaluationExplanationKey = attribute.Key("gen_ai.evaluation.explanation") - - // GenAIEvaluationNameKey is the attribute Key conforming to the - // "gen_ai.evaluation.name" semantic conventions. It represents the name of the - // evaluation metric used for the GenAI response. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Relevance", "IntentResolution" - GenAIEvaluationNameKey = attribute.Key("gen_ai.evaluation.name") - - // GenAIEvaluationScoreLabelKey is the attribute Key conforming to the - // "gen_ai.evaluation.score.label" semantic conventions. It represents the human - // readable label for evaluation. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "relevant", "not_relevant", "correct", "incorrect", "pass", "fail" - // Note: This attribute provides a human-readable interpretation of the - // evaluation score produced by an evaluator. For example, a score value of 1 - // could mean "relevant" in one evaluation system and "not relevant" in another, - // depending on the scoring range and evaluator. The label SHOULD have low - // cardinality. Possible values depend on the evaluation metric and evaluator - // used; implementations SHOULD document the possible values. - GenAIEvaluationScoreLabelKey = attribute.Key("gen_ai.evaluation.score.label") - - // GenAIEvaluationScoreValueKey is the attribute Key conforming to the - // "gen_ai.evaluation.score.value" semantic conventions. It represents the - // evaluation score returned by the evaluator. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 4.0 - GenAIEvaluationScoreValueKey = attribute.Key("gen_ai.evaluation.score.value") - - // GenAIInputMessagesKey is the attribute Key conforming to the - // "gen_ai.input.messages" semantic conventions. It represents the chat history - // provided to the model as an input. - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "[\n {\n "role": "user",\n "parts": [\n {\n "type": "text",\n - // "content": "Weather in Paris?"\n }\n ]\n },\n {\n "role": "assistant",\n - // "parts": [\n {\n "type": "tool_call",\n "id": - // "call_VSPygqKTWdrhaFErNvMV18Yl",\n "name": "get_weather",\n "arguments": {\n - // "location": "Paris"\n }\n }\n ]\n },\n {\n "role": "tool",\n "parts": [\n {\n - // "type": "tool_call_response",\n "id": " call_VSPygqKTWdrhaFErNvMV18Yl",\n - // "result": "rainy, 57°F"\n }\n ]\n }\n]\n" - // Note: Instrumentations MUST follow [Input messages JSON schema]. - // When the attribute is recorded on events, it MUST be recorded in structured - // form. When recorded on spans, it MAY be recorded as a JSON string if - // structured - // format is not supported and SHOULD be recorded in structured form otherwise. - // - // Messages MUST be provided in the order they were sent to the model. - // Instrumentations MAY provide a way for users to filter or truncate - // input messages. - // - // > [!Warning] - // > This attribute is likely to contain sensitive information including - // > user/PII data. - // - // See [Recording content on attributes] - // section for more details. - // - // [Input messages JSON schema]: /docs/gen-ai/gen-ai-input-messages.json - // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes - GenAIInputMessagesKey = attribute.Key("gen_ai.input.messages") - - // 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") - - // GenAIOutputMessagesKey is the attribute Key conforming to the - // "gen_ai.output.messages" semantic conventions. It represents the messages - // returned by the model where each message represents a specific model response - // (choice, candidate). - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "[\n {\n "role": "assistant",\n "parts": [\n {\n "type": "text",\n - // "content": "The weather in Paris is currently rainy with a temperature of - // 57°F."\n }\n ],\n "finish_reason": "stop"\n }\n]\n" - // Note: Instrumentations MUST follow [Output messages JSON schema] - // - // Each message represents a single output choice/candidate generated by - // the model. Each message corresponds to exactly one generation - // (choice/candidate) and vice versa - one choice cannot be split across - // multiple messages or one message cannot contain parts from multiple choices. - // - // When the attribute is recorded on events, it MUST be recorded in structured - // form. When recorded on spans, it MAY be recorded as a JSON string if - // structured - // format is not supported and SHOULD be recorded in structured form otherwise. - // - // Instrumentations MAY provide a way for users to filter or truncate - // output messages. - // - // > [!Warning] - // > This attribute is likely to contain sensitive information including - // > user/PII data. - // - // See [Recording content on attributes] - // section for more details. - // - // [Output messages JSON schema]: /docs/gen-ai/gen-ai-output-messages.json - // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes - GenAIOutputMessagesKey = attribute.Key("gen_ai.output.messages") - - // GenAIOutputTypeKey is the attribute Key conforming to the - // "gen_ai.output.type" semantic conventions. It represents the represents the - // content type requested by the client. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: This attribute SHOULD be used when the client requests output of a - // specific type. The model may return zero or more outputs of this type. - // This attribute specifies the output modality and not the actual output - // format. For example, if an image is requested, the actual output could be a - // URL pointing to an image file. - // Additional output format details may be recorded in the future in the - // `gen_ai.output.{type}.*` attributes. - GenAIOutputTypeKey = attribute.Key("gen_ai.output.type") - - // GenAIPromptNameKey is the attribute Key conforming to the - // "gen_ai.prompt.name" semantic conventions. It represents the name of the - // prompt that uniquely identifies it. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "analyze-code" - GenAIPromptNameKey = attribute.Key("gen_ai.prompt.name") - - // GenAIProviderNameKey is the attribute Key conforming to the - // "gen_ai.provider.name" semantic conventions. It represents the Generative AI - // provider as identified by the client or server instrumentation. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - // Note: The attribute SHOULD be set based on the instrumentation's best - // knowledge and may differ from the actual model provider. - // - // Multiple providers, including Azure OpenAI, Gemini, and AI hosting platforms - // are accessible using the OpenAI REST API and corresponding client libraries, - // but may proxy or host models from different providers. - // - // The `gen_ai.request.model`, `gen_ai.response.model`, and `server.address` - // attributes may help identify the actual system in use. - // - // The `gen_ai.provider.name` attribute acts as a discriminator that - // identifies the GenAI telemetry format flavor specific to that provider - // within GenAI semantic conventions. - // It SHOULD be set consistently with provider-specific attributes and signals. - // For example, GenAI spans, metrics, and events related to AWS Bedrock - // should have the `gen_ai.provider.name` set to `aws.bedrock` and include - // applicable `aws.bedrock.*` attributes and are not expected to include - // `openai.*` attributes. - GenAIProviderNameKey = attribute.Key("gen_ai.provider.name") - - // GenAIRequestChoiceCountKey is the attribute Key conforming to the - // "gen_ai.request.choice.count" semantic conventions. It represents the target - // number of candidate completions to return. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 3 - GenAIRequestChoiceCountKey = attribute.Key("gen_ai.request.choice.count") - - // 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") - - // GenAIRequestStreamKey is the attribute Key conforming to the - // "gen_ai.request.stream" semantic conventions. It represents the indicates - // whether the GenAI request was made in streaming mode. - // - // Type: boolean - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - GenAIRequestStreamKey = attribute.Key("gen_ai.request.stream") - - // 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") - - // GenAIResponseTimeToFirstChunkKey is the attribute Key conforming to the - // "gen_ai.response.time_to_first_chunk" semantic conventions. It represents the - // time to first chunk in a streaming response, measured from request issuance, - // in seconds. The value is measured from when the client issues the generation - // request to when the first chunk is received in the response stream. - // - // Type: double - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 0.5, 1.2 - GenAIResponseTimeToFirstChunkKey = attribute.Key("gen_ai.response.time_to_first_chunk") - - // GenAIRetrievalDocumentsKey is the attribute Key conforming to the - // "gen_ai.retrieval.documents" semantic conventions. It represents the - // documents retrieved. - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "[\n {\n "id": "doc_123",\n "score": 0.95\n },\n {\n "id": - // "doc_456",\n "score": 0.87\n },\n {\n "id": "doc_789",\n "score": 0.82\n - // }\n]\n" - // Note: Instrumentations MUST follow [Retrieval documents JSON schema]. - // When the attribute is recorded on events, it MUST be recorded in structured - // form. When recorded on spans, it MAY be recorded as a JSON string if - // structured - // format is not supported and SHOULD be recorded in structured form otherwise. - // - // Each document object SHOULD contain at least the following properties: - // `id` (string): A unique identifier for the document, `score` (double): The - // relevance score of the document - // - // [Retrieval documents JSON schema]: /docs/gen-ai/gen-ai-retrieval-documents.json - GenAIRetrievalDocumentsKey = attribute.Key("gen_ai.retrieval.documents") - - // GenAIRetrievalQueryTextKey is the attribute Key conforming to the - // "gen_ai.retrieval.query.text" semantic conventions. It represents the query - // text used for retrieval. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "What is the capital of France?", "weather in Paris" - // Note: > [!Warning] - // - // > This attribute may contain sensitive information. - GenAIRetrievalQueryTextKey = attribute.Key("gen_ai.retrieval.query.text") - - // GenAISystemInstructionsKey is the attribute Key conforming to the - // "gen_ai.system_instructions" semantic conventions. It represents the system - // message or instructions provided to the GenAI model separately from the chat - // history. - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "[\n {\n "type": "text",\n "content": "You are an Agent that greet - // users, always use greetings tool to respond"\n }\n]\n", "[\n {\n "type": - // "text",\n "content": "You are a language translator."\n },\n {\n "type": - // "text",\n "content": "Your mission is to translate text in English to - // French."\n }\n]\n" - // Note: This attribute SHOULD be used when the corresponding provider or API - // allows to provide system instructions or messages separately from the - // chat history. - // - // Instructions that are part of the chat history SHOULD be recorded in - // `gen_ai.input.messages` attribute instead. - // - // Instrumentations MUST follow [System instructions JSON schema]. - // - // When recorded on spans, it MAY be recorded as a JSON string if structured - // format is not supported and SHOULD be recorded in structured form otherwise. - // - // Instrumentations MAY provide a way for users to filter or truncate - // system instructions. - // - // > [!Warning] - // > This attribute may contain sensitive information. - // - // See [Recording content on attributes] - // section for more details. - // - // [System instructions JSON schema]: /docs/gen-ai/gen-ai-system-instructions.json - // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes - GenAISystemInstructionsKey = attribute.Key("gen_ai.system_instructions") - - // 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") - - // GenAIToolCallArgumentsKey is the attribute Key conforming to the - // "gen_ai.tool.call.arguments" semantic conventions. It represents the - // parameters passed to the tool call. - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{\n "location": "San Francisco?",\n "date": "2025-10-01"\n}\n" - // Note: > [!WARNING] - // - // > This attribute may contain sensitive information. - // - // It's expected to be an object - in case a serialized string is available - // to the instrumentation, the instrumentation SHOULD do the best effort to - // deserialize it to an object. When recorded on spans, it MAY be recorded as a - // JSON string if structured format is not supported and SHOULD be recorded in - // structured form otherwise. - GenAIToolCallArgumentsKey = attribute.Key("gen_ai.tool.call.arguments") - - // GenAIToolCallIDKey is the attribute Key conforming to the - // "gen_ai.tool.call.id" semantic conventions. It represents the tool call - // identifier. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "call_mszuSIzqtI65i1wAUOE8w5H4" - GenAIToolCallIDKey = attribute.Key("gen_ai.tool.call.id") - - // GenAIToolCallResultKey is the attribute Key conforming to the - // "gen_ai.tool.call.result" semantic conventions. It represents the result - // returned by the tool call (if any and if execution was successful). - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "{\n "temperature_range": {\n "high": 75,\n "low": 60\n },\n - // "conditions": "sunny"\n}\n" - // Note: > [!WARNING] - // - // > This attribute may contain sensitive information. - // - // It's expected to be an object - in case a serialized string is available - // to the instrumentation, the instrumentation SHOULD do the best effort to - // deserialize it to an object. When recorded on spans, it MAY be recorded as a - // JSON string if structured format is not supported and SHOULD be recorded in - // structured form otherwise. - GenAIToolCallResultKey = attribute.Key("gen_ai.tool.call.result") - - // GenAIToolDefinitionsKey is the attribute Key conforming to the - // "gen_ai.tool.definitions" semantic conventions. It represents the list of - // tool definitions available to the GenAI agent or model. - // - // Type: any - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "[\n {\n "type": "function",\n "name": "get_current_weather",\n - // "description": "Get the current weather in a given location",\n "parameters": - // {\n "type": "object",\n "properties": {\n "location": {\n "type": "string",\n - // "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": - // {\n "type": "string",\n "enum": [\n "celsius",\n "fahrenheit"\n ]\n }\n },\n - // "required": [\n "location",\n "unit"\n ]\n }\n }\n]\n" - // Note: Instrumentations MUST follow [Tool Definitions JSON Schema]. - // - // When the attribute is recorded on events, it MUST be recorded in structured - // form. When recorded on spans, it MAY be recorded as a JSON string if - // structured - // format is not supported and SHOULD be recorded in structured form otherwise. - // - // Since this attribute could be large, it's NOT RECOMMENDED to populate - // non-required properties by default. Instrumentations MAY provide a way - // to enable populating optional properties. - // - // [Tool Definitions JSON Schema]: /docs/gen-ai/gen-ai-tool-definitions.json - GenAIToolDefinitionsKey = attribute.Key("gen_ai.tool.definitions") - - // GenAIToolDescriptionKey is the attribute Key conforming to the - // "gen_ai.tool.description" semantic conventions. It represents the tool - // description. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Multiply two numbers" - GenAIToolDescriptionKey = attribute.Key("gen_ai.tool.description") - - // GenAIToolNameKey is the attribute Key conforming to the "gen_ai.tool.name" - // semantic conventions. It represents the name of the tool utilized by the - // agent. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "Flights" - GenAIToolNameKey = attribute.Key("gen_ai.tool.name") - - // GenAIToolTypeKey is the attribute Key conforming to the "gen_ai.tool.type" - // semantic conventions. It represents the type of the tool utilized by the - // agent. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "function", "extension", "datastore" - // Note: Extension: A tool executed on the agent-side to directly call external - // APIs, bridging the gap between the agent and real-world systems. - // Agent-side operations involve actions that are performed by the agent on the - // server or within the agent's controlled environment. - // Function: A tool executed on the client-side, where the agent generates - // parameters for a predefined function, and the client executes the logic. - // Client-side operations are actions taken on the user's end or within the - // client application. - // Datastore: A tool used by the agent to access and query structured or - // unstructured external data for retrieval-augmented tasks or knowledge - // updates. - GenAIToolTypeKey = attribute.Key("gen_ai.tool.type") - - // GenAIUsageCacheCreationInputTokensKey is the attribute Key conforming to the - // "gen_ai.usage.cache_creation.input_tokens" semantic conventions. It - // represents the number of input tokens written to a provider-managed cache. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 25 - // Note: The value SHOULD be included in `gen_ai.usage.input_tokens`. - GenAIUsageCacheCreationInputTokensKey = attribute.Key("gen_ai.usage.cache_creation.input_tokens") - - // GenAIUsageCacheReadInputTokensKey is the attribute Key conforming to the - // "gen_ai.usage.cache_read.input_tokens" semantic conventions. It represents - // the number of input tokens served from a provider-managed cache. - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 50 - // Note: The value SHOULD be included in `gen_ai.usage.input_tokens`. - GenAIUsageCacheReadInputTokensKey = attribute.Key("gen_ai.usage.cache_read.input_tokens") - - // 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 - // Note: This value SHOULD include all types of input tokens, including cached - // tokens. - // Instrumentations SHOULD make a best effort to populate this value, using a - // total - // provided by the provider when available or, depending on the provider API, - // by summing different token types parsed from the provider output. - 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") - - // GenAIUsageReasoningOutputTokensKey is the attribute Key conforming to the - // "gen_ai.usage.reasoning.output_tokens" semantic conventions. It represents - // the number of output tokens used for reasoning (e.g. chain-of-thought, - // extended thinking). - // - // Type: int - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: 50 - // Note: The value SHOULD be included in `gen_ai.usage.output_tokens`. - GenAIUsageReasoningOutputTokensKey = attribute.Key("gen_ai.usage.reasoning.output_tokens") - - // GenAIWorkflowNameKey is the attribute Key conforming to the - // "gen_ai.workflow.name" semantic conventions. It represents the human-readable - // name of the GenAI workflow provided by the application. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "multi_agent_rag", "customer_support_pipeline" - // Note: This attribute can be populated in different frameworks eg: name of the - // first chain in LangChain OR name of the crew in CrewAI. - GenAIWorkflowNameKey = attribute.Key("gen_ai.workflow.name") -) - -// GenAIAgentDescription returns an attribute KeyValue conforming to the -// "gen_ai.agent.description" semantic conventions. It represents the free-form -// description of the GenAI agent provided by the application. -func GenAIAgentDescription(val string) attribute.KeyValue { - return GenAIAgentDescriptionKey.String(val) -} - -// GenAIAgentID returns an attribute KeyValue conforming to the "gen_ai.agent.id" -// semantic conventions. It represents the unique identifier of the GenAI agent. -func GenAIAgentID(val string) attribute.KeyValue { - return GenAIAgentIDKey.String(val) -} - -// GenAIAgentName returns an attribute KeyValue conforming to the -// "gen_ai.agent.name" semantic conventions. It represents the human-readable -// name of the GenAI agent provided by the application. -func GenAIAgentName(val string) attribute.KeyValue { - return GenAIAgentNameKey.String(val) -} - -// GenAIAgentVersion returns an attribute KeyValue conforming to the -// "gen_ai.agent.version" semantic conventions. It represents the version of the -// GenAI agent. -func GenAIAgentVersion(val string) attribute.KeyValue { - return GenAIAgentVersionKey.String(val) -} - -// GenAIConversationID returns an attribute KeyValue conforming to the -// "gen_ai.conversation.id" semantic conventions. It represents the unique -// identifier for a conversation (session, thread), used to store and correlate -// messages within this conversation. -func GenAIConversationID(val string) attribute.KeyValue { - return GenAIConversationIDKey.String(val) -} - -// GenAIDataSourceID returns an attribute KeyValue conforming to the -// "gen_ai.data_source.id" semantic conventions. It represents the data source -// identifier. -func GenAIDataSourceID(val string) attribute.KeyValue { - return GenAIDataSourceIDKey.String(val) -} - -// GenAIEmbeddingsDimensionCount returns an attribute KeyValue conforming to the -// "gen_ai.embeddings.dimension.count" semantic conventions. It represents the -// number of dimensions the resulting output embeddings should have. -func GenAIEmbeddingsDimensionCount(val int) attribute.KeyValue { - return GenAIEmbeddingsDimensionCountKey.Int(val) -} - -// GenAIEvaluationExplanation returns an attribute KeyValue conforming to the -// "gen_ai.evaluation.explanation" semantic conventions. It represents a -// free-form explanation for the assigned score provided by the evaluator. -func GenAIEvaluationExplanation(val string) attribute.KeyValue { - return GenAIEvaluationExplanationKey.String(val) -} - -// GenAIEvaluationName returns an attribute KeyValue conforming to the -// "gen_ai.evaluation.name" semantic conventions. It represents the name of the -// evaluation metric used for the GenAI response. -func GenAIEvaluationName(val string) attribute.KeyValue { - return GenAIEvaluationNameKey.String(val) -} - -// GenAIEvaluationScoreLabel returns an attribute KeyValue conforming to the -// "gen_ai.evaluation.score.label" semantic conventions. It represents the human -// readable label for evaluation. -func GenAIEvaluationScoreLabel(val string) attribute.KeyValue { - return GenAIEvaluationScoreLabelKey.String(val) -} - -// GenAIEvaluationScoreValue returns an attribute KeyValue conforming to the -// "gen_ai.evaluation.score.value" semantic conventions. It represents the -// evaluation score returned by the evaluator. -func GenAIEvaluationScoreValue(val float64) attribute.KeyValue { - return GenAIEvaluationScoreValueKey.Float64(val) -} - -// GenAIPromptName returns an attribute KeyValue conforming to the -// "gen_ai.prompt.name" semantic conventions. It represents the name of the -// prompt that uniquely identifies it. -func GenAIPromptName(val string) attribute.KeyValue { - return GenAIPromptNameKey.String(val) -} - -// GenAIRequestChoiceCount returns an attribute KeyValue conforming to the -// "gen_ai.request.choice.count" semantic conventions. It represents the target -// number of candidate completions to return. -func GenAIRequestChoiceCount(val int) attribute.KeyValue { - return GenAIRequestChoiceCountKey.Int(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) -} - -// GenAIRequestStream returns an attribute KeyValue conforming to the -// "gen_ai.request.stream" semantic conventions. It represents the indicates -// whether the GenAI request was made in streaming mode. -func GenAIRequestStream(val bool) attribute.KeyValue { - return GenAIRequestStreamKey.Bool(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) -} - -// GenAIResponseTimeToFirstChunk returns an attribute KeyValue conforming to the -// "gen_ai.response.time_to_first_chunk" semantic conventions. It represents the -// time to first chunk in a streaming response, measured from request issuance, -// in seconds. The value is measured from when the client issues the generation -// request to when the first chunk is received in the response stream. -func GenAIResponseTimeToFirstChunk(val float64) attribute.KeyValue { - return GenAIResponseTimeToFirstChunkKey.Float64(val) -} - -// GenAIRetrievalQueryText returns an attribute KeyValue conforming to the -// "gen_ai.retrieval.query.text" semantic conventions. It represents the query -// text used for retrieval. -func GenAIRetrievalQueryText(val string) attribute.KeyValue { - return GenAIRetrievalQueryTextKey.String(val) -} - -// GenAIToolCallID returns an attribute KeyValue conforming to the -// "gen_ai.tool.call.id" semantic conventions. It represents the tool call -// identifier. -func GenAIToolCallID(val string) attribute.KeyValue { - return GenAIToolCallIDKey.String(val) -} - -// GenAIToolDescription returns an attribute KeyValue conforming to the -// "gen_ai.tool.description" semantic conventions. It represents the tool -// description. -func GenAIToolDescription(val string) attribute.KeyValue { - return GenAIToolDescriptionKey.String(val) -} - -// GenAIToolName returns an attribute KeyValue conforming to the -// "gen_ai.tool.name" semantic conventions. It represents the name of the tool -// utilized by the agent. -func GenAIToolName(val string) attribute.KeyValue { - return GenAIToolNameKey.String(val) -} - -// GenAIToolType returns an attribute KeyValue conforming to the -// "gen_ai.tool.type" semantic conventions. It represents the type of the tool -// utilized by the agent. -func GenAIToolType(val string) attribute.KeyValue { - return GenAIToolTypeKey.String(val) -} - -// GenAIUsageCacheCreationInputTokens returns an attribute KeyValue conforming to -// the "gen_ai.usage.cache_creation.input_tokens" semantic conventions. It -// represents the number of input tokens written to a provider-managed cache. -func GenAIUsageCacheCreationInputTokens(val int) attribute.KeyValue { - return GenAIUsageCacheCreationInputTokensKey.Int(val) -} - -// GenAIUsageCacheReadInputTokens returns an attribute KeyValue conforming to the -// "gen_ai.usage.cache_read.input_tokens" semantic conventions. It represents the -// number of input tokens served from a provider-managed cache. -func GenAIUsageCacheReadInputTokens(val int) attribute.KeyValue { - return GenAIUsageCacheReadInputTokensKey.Int(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) -} - -// GenAIUsageReasoningOutputTokens returns an attribute KeyValue conforming to -// the "gen_ai.usage.reasoning.output_tokens" semantic conventions. It represents -// the number of output tokens used for reasoning (e.g. chain-of-thought, -// extended thinking). -func GenAIUsageReasoningOutputTokens(val int) attribute.KeyValue { - return GenAIUsageReasoningOutputTokensKey.Int(val) -} - -// GenAIWorkflowName returns an attribute KeyValue conforming to the -// "gen_ai.workflow.name" semantic conventions. It represents the human-readable -// name of the GenAI workflow provided by the application. -func GenAIWorkflowName(val string) attribute.KeyValue { - return GenAIWorkflowNameKey.String(val) -} - -// 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") - // Multimodal content generation operation such as [Gemini Generate Content] - // Stability: development - // - // [Gemini Generate Content]: https://ai.google.dev/api/generate-content - GenAIOperationNameGenerateContent = GenAIOperationNameKey.String("generate_content") - // 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") - // Retrieval operation such as [OpenAI Search Vector Store API] - // Stability: development - // - // [OpenAI Search Vector Store API]: https://platform.openai.com/docs/api-reference/vector-stores/search - GenAIOperationNameRetrieval = GenAIOperationNameKey.String("retrieval") - // Create GenAI agent - // Stability: development - GenAIOperationNameCreateAgent = GenAIOperationNameKey.String("create_agent") - // Invoke GenAI agent - // Stability: development - GenAIOperationNameInvokeAgent = GenAIOperationNameKey.String("invoke_agent") - // Execute a tool - // Stability: development - GenAIOperationNameExecuteTool = GenAIOperationNameKey.String("execute_tool") - // Invoke GenAI workflow - // Stability: development - GenAIOperationNameInvokeWorkflow = GenAIOperationNameKey.String("invoke_workflow") -) - -// Enum values for gen_ai.output.type -var ( - // Plain text - // Stability: development - GenAIOutputTypeText = GenAIOutputTypeKey.String("text") - // JSON object with known or unknown schema - // Stability: development - GenAIOutputTypeJSON = GenAIOutputTypeKey.String("json") - // Image - // Stability: development - GenAIOutputTypeImage = GenAIOutputTypeKey.String("image") - // Speech - // Stability: development - GenAIOutputTypeSpeech = GenAIOutputTypeKey.String("speech") -) - -// Enum values for gen_ai.provider.name -var ( - // [OpenAI] - // Stability: development - // - // [OpenAI]: https://openai.com/ - GenAIProviderNameOpenAI = GenAIProviderNameKey.String("openai") - // Any Google generative AI endpoint - // Stability: development - GenAIProviderNameGCPGenAI = GenAIProviderNameKey.String("gcp.gen_ai") - // [Vertex AI] - // Stability: development - // - // [Vertex AI]: https://cloud.google.com/vertex-ai - GenAIProviderNameGCPVertexAI = GenAIProviderNameKey.String("gcp.vertex_ai") - // [Gemini] - // Stability: development - // - // [Gemini]: https://cloud.google.com/products/gemini - GenAIProviderNameGCPGemini = GenAIProviderNameKey.String("gcp.gemini") - // [Anthropic] - // Stability: development - // - // [Anthropic]: https://www.anthropic.com/ - GenAIProviderNameAnthropic = GenAIProviderNameKey.String("anthropic") - // [Cohere] - // Stability: development - // - // [Cohere]: https://cohere.com/ - GenAIProviderNameCohere = GenAIProviderNameKey.String("cohere") - // Azure AI Inference - // Stability: development - GenAIProviderNameAzureAIInference = GenAIProviderNameKey.String("azure.ai.inference") - // [Azure OpenAI] - // Stability: development - // - // [Azure OpenAI]: https://learn.microsoft.com/en-us/azure/ai-services/openai/overview - GenAIProviderNameAzureAIOpenAI = GenAIProviderNameKey.String("azure.ai.openai") - // [IBM Watsonx AI] - // Stability: development - // - // [IBM Watsonx AI]: https://www.ibm.com/products/watsonx-ai - GenAIProviderNameIBMWatsonxAI = GenAIProviderNameKey.String("ibm.watsonx.ai") - // [AWS Bedrock] - // Stability: development - // - // [AWS Bedrock]: https://aws.amazon.com/bedrock - GenAIProviderNameAWSBedrock = GenAIProviderNameKey.String("aws.bedrock") - // [Perplexity] - // Stability: development - // - // [Perplexity]: https://www.perplexity.ai/ - GenAIProviderNamePerplexity = GenAIProviderNameKey.String("perplexity") - // [xAI] - // Stability: development - // - // [xAI]: https://x.ai/ - GenAIProviderNameXAI = GenAIProviderNameKey.String("x_ai") - // [DeepSeek] - // Stability: development - // - // [DeepSeek]: https://www.deepseek.com/ - GenAIProviderNameDeepseek = GenAIProviderNameKey.String("deepseek") - // [Groq] - // Stability: development - // - // [Groq]: https://groq.com/ - GenAIProviderNameGroq = GenAIProviderNameKey.String("groq") - // [Mistral AI] - // Stability: development - // - // [Mistral AI]: https://mistral.ai/ - GenAIProviderNameMistralAI = GenAIProviderNameKey.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 - GenAITokenTypeOutput = GenAITokenTypeKey.String("output") -) - // Namespace: geo const ( // GeoContinentCodeKey is the attribute Key conforming to the @@ -9201,7 +8198,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry-cluster" K8SClusterNameKey = attribute.Key("k8s.cluster.name") @@ -9212,7 +8209,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d" // Note: K8s doesn't have support for obtaining a cluster ID. If this is ever @@ -9241,6 +8238,19 @@ const ( // [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") + // K8SContainerEphemeralStorageFsTypeKey is the attribute Key conforming to the + // "k8s.container.ephemeral_storage.fs_type" semantic conventions. It represents + // the type of file system component for ephemeral storage. + // + // Type: Enum + // RequirementLevel: Recommended + // Stability: Development + // + // Examples: "rootfs", "logs" + // Note: Eviction decisions based on ephemeral-storage resource limits are made + // based on the total container usage. + K8SContainerEphemeralStorageFsTypeKey = attribute.Key("k8s.container.ephemeral_storage.fs_type") + // 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 @@ -9248,7 +8258,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "redis" K8SContainerNameKey = attribute.Key("k8s.container.name") @@ -9260,7 +8270,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count") @@ -9289,8 +8299,8 @@ const ( // "CreateContainerConfigError", "ErrImagePull", "ImagePullBackOff", // "OOMKilled", "Completed", "Error", "ContainerCannotRun" // - // [K8s ContainerStateWaiting]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstatewaiting-v1-core - // [K8s ContainerStateTerminated]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstateterminated-v1-core + // [K8s ContainerStateWaiting]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatewaiting-v1-core + // [K8s ContainerStateTerminated]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstateterminated-v1-core K8SContainerStatusReasonKey = attribute.Key("k8s.container.status.reason") // K8SContainerStatusStateKey is the attribute Key conforming to the @@ -9303,7 +8313,7 @@ const ( // // Examples: "terminated", "running", "waiting" // - // [K8s ContainerState]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstate-v1-core + // [K8s ContainerState]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstate-v1-core K8SContainerStatusStateKey = attribute.Key("k8s.container.status.state") // K8SCronJobNameKey is the attribute Key conforming to the "k8s.cronjob.name" @@ -9311,7 +8321,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry" K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") @@ -9321,7 +8331,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") @@ -9332,7 +8342,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry" K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") @@ -9342,7 +8352,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") @@ -9353,7 +8363,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry" K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") @@ -9364,7 +8374,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") @@ -9454,7 +8464,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry" K8SJobNameKey = attribute.Key("k8s.job.name") @@ -9464,7 +8474,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SJobUIDKey = attribute.Key("k8s.job.uid") @@ -9475,7 +8485,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "default" K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") @@ -9492,7 +8502,7 @@ const ( // 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 + // [K8s NamespaceStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#namespacestatus-v1-core K8SNamespacePhaseKey = attribute.Key("k8s.namespace.phase") // K8SNodeConditionStatusKey is the attribute Key conforming to the @@ -9507,7 +8517,7 @@ const ( // Note: This attribute aligns with the `status` field of the // [NodeCondition] // - // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core + // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#nodecondition-v1-core K8SNodeConditionStatusKey = attribute.Key("k8s.node.condition.status") // K8SNodeConditionTypeKey is the attribute Key conforming to the @@ -9531,8 +8541,8 @@ const ( // When this occurs, the exact value as reported by the Kubernetes API SHOULD be // used. // - // [K8s documentation]: https://v1-32.docs.kubernetes.io/docs/reference/node/node-status/#condition - // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core + // [K8s documentation]: https://kubernetes.io/docs/reference/node/node-status/#condition + // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#nodecondition-v1-core K8SNodeConditionTypeKey = attribute.Key("k8s.node.condition.type") // K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name" @@ -9540,7 +8550,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "node-1" K8SNodeNameKey = attribute.Key("k8s.node.name") @@ -9561,7 +8571,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2" K8SNodeUIDKey = attribute.Key("k8s.node.uid") @@ -9661,7 +8671,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "collector-gateway" // Note: The K8s Pod spec has an optional hostname field, which can be used to @@ -9681,7 +8691,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "172.18.0.2" // Note: This attribute aligns with the `podIP` field of the @@ -9695,7 +8705,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry-pod-autoconf" K8SPodNameKey = attribute.Key("k8s.pod.name") @@ -9706,7 +8716,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "2025-12-04T08:41:03Z" // Note: Date and time at which the object was acknowledged by the Kubelet. @@ -9750,7 +8760,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SPodUIDKey = attribute.Key("k8s.pod.uid") @@ -9761,7 +8771,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry" K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") @@ -9772,7 +8782,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") @@ -9985,7 +8995,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "opentelemetry" K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") @@ -9996,7 +9006,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Release_Candidate + // Stability: Stable // // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff" K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") @@ -10011,7 +9021,7 @@ const ( // // Examples: "gold.storageclass.storage.k8s.io" // - // [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io + // [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#storageclass-v1-storage-k8s-io K8SStorageclassNameKey = attribute.Key("k8s.storageclass.name") // K8SVolumeNameKey is the attribute Key conforming to the "k8s.volume.name" @@ -10559,7 +9569,7 @@ func K8SStatefulSetUID(val string) attribute.KeyValue { // "k8s.storageclass.name" semantic conventions. It represents the name of K8s // [StorageClass] object. // -// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io +// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#storageclass-v1-storage-k8s-io func K8SStorageclassName(val string) attribute.KeyValue { return K8SStorageclassNameKey.String(val) } @@ -10571,6 +9581,16 @@ func K8SVolumeName(val string) attribute.KeyValue { return K8SVolumeNameKey.String(val) } +// Enum values for k8s.container.ephemeral_storage.fs_type +var ( + // For the container's writable layer usage. + // Stability: development + K8SContainerEphemeralStorageFsTypeRootfs = K8SContainerEphemeralStorageFsTypeKey.String("rootfs") + // For the container's log files usage (stdout/stderr). + // Stability: development + K8SContainerEphemeralStorageFsTypeLogs = K8SContainerEphemeralStorageFsTypeKey.String("logs") +) + // Enum values for k8s.container.status.reason var ( // The container is being created. @@ -10809,32 +9829,32 @@ var ( // A [persistentVolumeClaim] volume // Stability: development // - // [persistentVolumeClaim]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim + // [persistentVolumeClaim]: https://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 + // [configMap]: https://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 + // [downwardAPI]: https://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 + // [emptyDir]: https://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 + // [secret]: https://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 + // [local]: https://kubernetes.io/docs/concepts/storage/volumes/#local K8SVolumeTypeLocal = K8SVolumeTypeKey.String("local") ) @@ -10998,188 +10018,6 @@ func MainframeLparName(val string) attribute.KeyValue { return MainframeLparNameKey.String(val) } -// Namespace: mcp -const ( - // McpMethodNameKey is the attribute Key conforming to the "mcp.method.name" - // semantic conventions. It represents the name of the request or notification - // method. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - McpMethodNameKey = attribute.Key("mcp.method.name") - - // McpProtocolVersionKey is the attribute Key conforming to the - // "mcp.protocol.version" semantic conventions. It represents the [version] of - // the Model Context Protocol used. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "2025-06-18" - // - // [version]: https://modelcontextprotocol.io/specification/versioning - McpProtocolVersionKey = attribute.Key("mcp.protocol.version") - - // McpResourceURIKey is the attribute Key conforming to the "mcp.resource.uri" - // semantic conventions. It represents the value of the resource uri. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "postgres://database/customers/schema", - // "file:///home/user/documents/report.pdf" - // Note: This is a URI of the resource provided in the following requests or - // notifications: `resources/read`, `resources/subscribe`, - // `resources/unsubscribe`, or `notifications/resources/updated`. - McpResourceURIKey = attribute.Key("mcp.resource.uri") - - // McpSessionIDKey is the attribute Key conforming to the "mcp.session.id" - // semantic conventions. It represents the identifies [MCP session]. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "191c4850af6c49e08843a3f6c80e5046" - // - // [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management - McpSessionIDKey = attribute.Key("mcp.session.id") -) - -// McpProtocolVersion returns an attribute KeyValue conforming to the -// "mcp.protocol.version" semantic conventions. It represents the [version] of -// the Model Context Protocol used. -// -// [version]: https://modelcontextprotocol.io/specification/versioning -func McpProtocolVersion(val string) attribute.KeyValue { - return McpProtocolVersionKey.String(val) -} - -// McpResourceURI returns an attribute KeyValue conforming to the -// "mcp.resource.uri" semantic conventions. It represents the value of the -// resource uri. -func McpResourceURI(val string) attribute.KeyValue { - return McpResourceURIKey.String(val) -} - -// McpSessionID returns an attribute KeyValue conforming to the "mcp.session.id" -// semantic conventions. It represents the identifies [MCP session]. -// -// [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management -func McpSessionID(val string) attribute.KeyValue { - return McpSessionIDKey.String(val) -} - -// Enum values for mcp.method.name -var ( - // Notification cancelling a previously-issued request. - // - // Stability: development - McpMethodNameNotificationsCancelled = McpMethodNameKey.String("notifications/cancelled") - // Request to initialize the MCP client. - // - // Stability: development - McpMethodNameInitialize = McpMethodNameKey.String("initialize") - // Notification indicating that the MCP client has been initialized. - // - // Stability: development - McpMethodNameNotificationsInitialized = McpMethodNameKey.String("notifications/initialized") - // Notification indicating the progress for a long-running operation. - // - // Stability: development - McpMethodNameNotificationsProgress = McpMethodNameKey.String("notifications/progress") - // Request to check that the other party is still alive. - // - // Stability: development - McpMethodNamePing = McpMethodNameKey.String("ping") - // Request to list resources available on server. - // - // Stability: development - McpMethodNameResourcesList = McpMethodNameKey.String("resources/list") - // Request to list resource templates available on server. - // - // Stability: development - McpMethodNameResourcesTemplatesList = McpMethodNameKey.String("resources/templates/list") - // Request to read a resource. - // - // Stability: development - McpMethodNameResourcesRead = McpMethodNameKey.String("resources/read") - // Notification indicating that the list of resources has changed. - // - // Stability: development - McpMethodNameNotificationsResourcesListChanged = McpMethodNameKey.String("notifications/resources/list_changed") - // Request to subscribe to a resource. - // - // Stability: development - McpMethodNameResourcesSubscribe = McpMethodNameKey.String("resources/subscribe") - // Request to unsubscribe from resource updates. - // - // Stability: development - McpMethodNameResourcesUnsubscribe = McpMethodNameKey.String("resources/unsubscribe") - // Notification indicating that a resource has been updated. - // - // Stability: development - McpMethodNameNotificationsResourcesUpdated = McpMethodNameKey.String("notifications/resources/updated") - // Request to list prompts available on server. - // - // Stability: development - McpMethodNamePromptsList = McpMethodNameKey.String("prompts/list") - // Request to get a prompt. - // - // Stability: development - McpMethodNamePromptsGet = McpMethodNameKey.String("prompts/get") - // Notification indicating that the list of prompts has changed. - // - // Stability: development - McpMethodNameNotificationsPromptsListChanged = McpMethodNameKey.String("notifications/prompts/list_changed") - // Request to list tools available on server. - // - // Stability: development - McpMethodNameToolsList = McpMethodNameKey.String("tools/list") - // Request to call a tool. - // - // Stability: development - McpMethodNameToolsCall = McpMethodNameKey.String("tools/call") - // Notification indicating that the list of tools has changed. - // - // Stability: development - McpMethodNameNotificationsToolsListChanged = McpMethodNameKey.String("notifications/tools/list_changed") - // Request to set the logging level. - // - // Stability: development - McpMethodNameLoggingSetLevel = McpMethodNameKey.String("logging/setLevel") - // Notification indicating that a message has been received. - // - // Stability: development - McpMethodNameNotificationsMessage = McpMethodNameKey.String("notifications/message") - // Request to create a sampling message. - // - // Stability: development - McpMethodNameSamplingCreateMessage = McpMethodNameKey.String("sampling/createMessage") - // Request to complete a prompt. - // - // Stability: development - McpMethodNameCompletionComplete = McpMethodNameKey.String("completion/complete") - // Request to list roots available on server. - // - // Stability: development - McpMethodNameRootsList = McpMethodNameKey.String("roots/list") - // Notification indicating that the list of roots has changed. - // - // Stability: development - McpMethodNameNotificationsRootsListChanged = McpMethodNameKey.String("notifications/roots/list_changed") - // Request from the server to elicit additional information from the user via - // the client - // - // Stability: development - McpMethodNameElicitationCreate = McpMethodNameKey.String("elicitation/create") -) - // Namespace: messaging const ( // MessagingBatchMessageCountKey is the attribute Key conforming to the @@ -12073,12 +10911,14 @@ const ( 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. + // "network.io.direction" semantic conventions. It represents the direction of + // traffic from the perspective of the observing host's physical or virtual + // network interface. It should not be used to represent the logical direction + // of a stateful connection or network flow. // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "transmit" NetworkIODirectionKey = attribute.Key("network.io.direction") @@ -12395,10 +11235,10 @@ var ( // Enum values for network.io.direction var ( // transmit - // Stability: development + // Stability: release_candidate NetworkIODirectionTransmit = NetworkIODirectionKey.String("transmit") // receive - // Stability: development + // Stability: release_candidate NetworkIODirectionReceive = NetworkIODirectionKey.String("receive") ) @@ -12577,90 +11417,6 @@ func OncRPCVersion(val int) attribute.KeyValue { return OncRPCVersionKey.Int(val) } -// Namespace: openai -const ( - // OpenAIAPITypeKey is the attribute Key conforming to the "openai.api.type" - // semantic conventions. It represents the type of OpenAI API being used. - // - // Type: Enum - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: - OpenAIAPITypeKey = attribute.Key("openai.api.type") - - // OpenAIRequestServiceTierKey is the attribute Key conforming to the - // "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" - OpenAIRequestServiceTierKey = attribute.Key("openai.request.service_tier") - - // OpenAIResponseServiceTierKey is the attribute Key conforming to the - // "openai.response.service_tier" semantic conventions. It represents the - // service tier used for the response. - // - // Type: string - // RequirementLevel: Recommended - // Stability: Development - // - // Examples: "scale", "default" - OpenAIResponseServiceTierKey = attribute.Key("openai.response.service_tier") - - // OpenAIResponseSystemFingerprintKey is the attribute Key conforming to the - // "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" - OpenAIResponseSystemFingerprintKey = attribute.Key("openai.response.system_fingerprint") -) - -// OpenAIResponseServiceTier returns an attribute KeyValue conforming to the -// "openai.response.service_tier" semantic conventions. It represents the service -// tier used for the response. -func OpenAIResponseServiceTier(val string) attribute.KeyValue { - return OpenAIResponseServiceTierKey.String(val) -} - -// OpenAIResponseSystemFingerprint returns an attribute KeyValue conforming to -// the "openai.response.system_fingerprint" semantic conventions. It represents a -// fingerprint to track any eventual change in the Generative AI environment. -func OpenAIResponseSystemFingerprint(val string) attribute.KeyValue { - return OpenAIResponseSystemFingerprintKey.String(val) -} - -// Enum values for openai.api.type -var ( - // The OpenAI [Chat Completions API]. - // Stability: development - // - // [Chat Completions API]: https://developers.openai.com/api/reference/chat-completions/overview - OpenAIAPITypeChatCompletions = OpenAIAPITypeKey.String("chat_completions") - // The OpenAI [Responses API]. - // Stability: development - // - // [Responses API]: https://developers.openai.com/api/reference/responses/overview - OpenAIAPITypeResponses = OpenAIAPITypeKey.String("responses") -) - -// Enum values for openai.request.service_tier -var ( - // The system will utilize scale tier credits until they are exhausted. - // Stability: development - OpenAIRequestServiceTierAuto = OpenAIRequestServiceTierKey.String("auto") - // The system will utilize the default scale tier. - // Stability: development - OpenAIRequestServiceTierDefault = OpenAIRequestServiceTierKey.String("default") -) - // Namespace: openshift const ( // OpenShiftClusterquotaNameKey is the attribute Key conforming to the @@ -12733,7 +11489,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "example.com", "corp.internal", "prod.db.local" // Note: This attribute SHOULD be set to the value of the `DB_DOMAIN` @@ -12753,7 +11509,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "ORCL1", "ORCL2", "ORCL3" // Note: There can be multiple instances associated with a single database @@ -12769,7 +11525,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "ORCL1", "FREE" // Note: This attribute SHOULD be set to the value of the parameter `DB_NAME` @@ -12782,7 +11538,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "PDB1", "FREEPDB" // Note: This attribute SHOULD reflect the PDB that the session is currently @@ -12800,7 +11556,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "order-processing-service", "db_low.adb.oraclecloud.com", // "db_high.adb.oraclecloud.com" @@ -13529,7 +12285,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 4 // Note: This field can be useful for querying or performing bucket analysis on @@ -13545,7 +12301,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "cmd/otelcol" ProcessCommandKey = attribute.Key("process.command") @@ -13561,7 +12317,7 @@ const ( // // Type: string[] // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "cmd/otecol", "--config=config.yaml" ProcessCommandArgsKey = attribute.Key("process.command_args") @@ -13576,7 +12332,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "C:\cmd\otecol --config="my directory\config.yaml"" ProcessCommandLineKey = attribute.Key("process.command_line") @@ -13588,7 +12344,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: ProcessContextSwitchTypeKey = attribute.Key("process.context_switch.type") @@ -13599,7 +12355,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "2023-11-21T09:25:34.853Z" ProcessCreationTimeKey = attribute.Key("process.creation.time") @@ -13610,7 +12366,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "c89b11207f6479603b0d49bf291c092c2b719293" ProcessExecutableBuildIDGNUKey = attribute.Key("process.executable.build_id.gnu") @@ -13621,7 +12377,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: // "foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY" @@ -13633,7 +12389,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "600DCAFE4A110000F2BF38C493F5FB92" // Note: GNU and Go build IDs may be stripped or unavailable in some @@ -13660,7 +12416,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "otelcol" ProcessExecutableNameKey = attribute.Key("process.executable.name") @@ -13673,7 +12429,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "/usr/bin/cmd/otelcol" ProcessExecutablePathKey = attribute.Key("process.executable.path") @@ -13683,7 +12439,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 127 ProcessExitCodeKey = attribute.Key("process.exit.code") @@ -13694,7 +12450,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "2023-11-21T09:26:12.315Z" ProcessExitTimeKey = attribute.Key("process.exit.time") @@ -13706,7 +12462,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 23 ProcessGroupLeaderPIDKey = attribute.Key("process.group_leader.pid") @@ -13717,7 +12473,7 @@ const ( // // Type: boolean // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: ProcessInteractiveKey = attribute.Key("process.interactive") @@ -13728,7 +12484,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // 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" @@ -13746,7 +12502,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "root" ProcessOwnerKey = attribute.Key("process.owner") @@ -13757,7 +12513,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 111 ProcessParentPIDKey = attribute.Key("process.parent_pid") @@ -13767,7 +12523,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 1234 ProcessPIDKey = attribute.Key("process.pid") @@ -13778,7 +12534,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 1000 ProcessRealUserIDKey = attribute.Key("process.real_user.id") @@ -13789,7 +12545,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "operator" ProcessRealUserNameKey = attribute.Key("process.real_user.name") @@ -13801,7 +12557,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0 ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") @@ -13812,7 +12568,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "OpenJDK Runtime Environment" ProcessRuntimeNameKey = attribute.Key("process.runtime.name") @@ -13823,7 +12579,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 14.0.2 ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") @@ -13834,7 +12590,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 1002 ProcessSavedUserIDKey = attribute.Key("process.saved_user.id") @@ -13845,7 +12601,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "operator" ProcessSavedUserNameKey = attribute.Key("process.saved_user.name") @@ -13857,7 +12613,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 14 ProcessSessionLeaderPIDKey = attribute.Key("process.session_leader.pid") @@ -13868,7 +12624,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "running" // @@ -13880,7 +12636,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "cat /etc/hostname", "xfce4-session", "bash" // Note: In many Unix-like systems, process title (proctitle), is the string @@ -13894,7 +12650,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 1001 ProcessUserIDKey = attribute.Key("process.user.id") @@ -13905,7 +12661,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "root" ProcessUserNameKey = attribute.Key("process.user.name") @@ -13915,7 +12671,7 @@ const ( // // Type: int // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: 12 // Note: The process ID within a PID namespace. This is not necessarily unique @@ -13929,7 +12685,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "/root" ProcessWorkingDirectoryKey = attribute.Key("process.working_directory") @@ -14178,26 +12934,26 @@ func ProcessWorkingDirectory(val string) attribute.KeyValue { // Enum values for process.context_switch.type var ( // voluntary - // Stability: development + // Stability: release_candidate ProcessContextSwitchTypeVoluntary = ProcessContextSwitchTypeKey.String("voluntary") // involuntary - // Stability: development + // Stability: release_candidate ProcessContextSwitchTypeInvoluntary = ProcessContextSwitchTypeKey.String("involuntary") ) // Enum values for process.state var ( // running - // Stability: development + // Stability: release_candidate ProcessStateRunning = ProcessStateKey.String("running") // sleeping - // Stability: development + // Stability: release_candidate ProcessStateSleeping = ProcessStateKey.String("sleeping") // stopped - // Stability: development + // Stability: release_candidate ProcessStateStopped = ProcessStateKey.String("stopped") // defunct - // Stability: development + // Stability: release_candidate ProcessStateDefunct = ProcessStateKey.String("defunct") ) @@ -14293,6 +13049,12 @@ var ( // // [Rust]: https://wikipedia.org/wiki/Rust_(programming_language) ProfileFrameTypeRust = ProfileFrameTypeKey.String("rust") + // [LuaJIT] + // + // Stability: development + // + // [LuaJIT]: https://en.wikipedia.org/wiki/LuaJIT + ProfileFrameTypeLuajit = ProfileFrameTypeKey.String("luajit") ) // Namespace: rpc @@ -14642,7 +13404,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Alpha // // Examples: "critical", "high", "medium", "low" // Note: Application developers are encouraged to set `service.criticality` to @@ -14840,21 +13602,21 @@ var ( // Service is business-critical; downtime directly impacts revenue, user // experience, or core functionality. // - // Stability: development + // Stability: alpha ServiceCriticalityCritical = ServiceCriticalityKey.String("critical") // Service is important but has degradation tolerance or fallback mechanisms. // - // Stability: development + // Stability: alpha ServiceCriticalityHigh = ServiceCriticalityKey.String("high") // Service provides supplementary functionality; degradation has limited user // impact. // - // Stability: development + // Stability: alpha ServiceCriticalityMedium = ServiceCriticalityKey.String("medium") // Service is non-essential to core operations; used for background tasks or // internal tools. // - // Stability: development + // Stability: alpha ServiceCriticalityLow = ServiceCriticalityKey.String("low") ) @@ -15095,7 +13857,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "minor" SystemPagingFaultTypeKey = attribute.Key("system.paging.fault.type") @@ -15216,10 +13978,10 @@ var ( // Enum values for system.paging.fault.type var ( // major - // Stability: development + // Stability: release_candidate SystemPagingFaultTypeMajor = SystemPagingFaultTypeKey.String("major") // minor - // Stability: development + // Stability: release_candidate SystemPagingFaultTypeMinor = SystemPagingFaultTypeKey.String("minor") ) @@ -15350,6 +14112,9 @@ var ( // java // Stability: stable TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java") + // kotlin + // Stability: stable + TelemetrySDKLanguageKotlin = TelemetrySDKLanguageKey.String("kotlin") // nodejs // Stability: stable TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs") @@ -16191,8 +14956,9 @@ const ( // replaced by the // value `REDACTED`: // - // - [`AWSAccessKeyId`] - // - [`Signature`] + // - [`X-Amz-Signature`] + // - [`X-Amz-Credential`] + // - [`X-Amz-Security-Token`] // - [`sig`] // - [`X-Goog-Signature`] // @@ -16215,8 +14981,9 @@ const ( // `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 + // [`X-Amz-Signature`]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html + // [`X-Amz-Credential`]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html + // [`X-Amz-Security-Token`]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html // [`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") @@ -16278,8 +15045,9 @@ const ( // Query string values for the following keys SHOULD be redacted by default and // replaced by the value `REDACTED`: // - // - [`AWSAccessKeyId`] - // - [`Signature`] + // - [`X-Amz-Signature`] + // - [`X-Amz-Credential`] + // - [`X-Amz-Security-Token`] // - [`sig`] // - [`X-Goog-Signature`] // @@ -16301,8 +15069,9 @@ const ( // `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 + // [`X-Amz-Signature`]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html + // [`X-Amz-Credential`]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html + // [`X-Amz-Security-Token`]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html // [`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") @@ -16752,7 +15521,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "123" VCSChangeIDKey = attribute.Key("vcs.change.id") @@ -16763,7 +15532,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "open", "closed", "merged" VCSChangeStateKey = attribute.Key("vcs.change.state") @@ -16775,7 +15544,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "Fixes broken thing", "feat: add my new feature", "[chore] update // dependency" @@ -16787,7 +15556,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "added", "removed" VCSLineChangeTypeKey = attribute.Key("vcs.line_change.type") @@ -16798,7 +15567,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "my-org", "myteam", "business-unit" VCSOwnerNameKey = attribute.Key("vcs.owner.name") @@ -16809,7 +15578,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "github", "gitlab", "gitea", "bitbucket" VCSProviderNameKey = attribute.Key("vcs.provider.name") @@ -16820,7 +15589,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "my-feature-branch", "tag-1-test" // Note: `base` refers to the starting point of a change. For example, `main` @@ -16837,7 +15606,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc", // "main", "123", "HEAD" @@ -16869,7 +15638,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "branch", "tag" // Note: `base` refers to the starting point of a change. For example, `main` @@ -16885,7 +15654,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "my-feature-branch", "tag-1-test" // Note: `head` refers to where you are right now; the current reference at a @@ -16901,7 +15670,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc", // "main", "123", "HEAD" @@ -16931,7 +15700,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "branch", "tag" // Note: `head` refers to where you are right now; the current reference at a @@ -16945,7 +15714,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "branch", "tag" // @@ -16959,7 +15728,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "semantic-conventions", "my-cool-repo" // Note: Due to it only being the name, it can clash with forks of the same @@ -16974,7 +15743,7 @@ const ( // // Type: string // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: // "https://github.com/opentelemetry/open-telemetry-collector-contrib", @@ -16991,7 +15760,7 @@ const ( // // Type: Enum // RequirementLevel: Recommended - // Stability: Development + // Stability: Release_Candidate // // Examples: "ahead", "behind" VCSRevisionDeltaDirectionKey = attribute.Key("vcs.revision_delta.direction") @@ -17082,53 +15851,53 @@ 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 + // Stability: release_candidate 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 + // Stability: release_candidate 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 + // Stability: release_candidate VCSChangeStateClosed = VCSChangeStateKey.String("closed") // Merged indicates that the change has been successfully integrated into the // target codebase. - // Stability: development + // Stability: release_candidate VCSChangeStateMerged = VCSChangeStateKey.String("merged") ) // Enum values for vcs.line_change.type var ( // How many lines were added. - // Stability: development + // Stability: release_candidate VCSLineChangeTypeAdded = VCSLineChangeTypeKey.String("added") // How many lines were removed. - // Stability: development + // Stability: release_candidate VCSLineChangeTypeRemoved = VCSLineChangeTypeKey.String("removed") ) // Enum values for vcs.provider.name var ( // [GitHub] - // Stability: development + // Stability: release_candidate // // [GitHub]: https://github.com VCSProviderNameGithub = VCSProviderNameKey.String("github") // [GitLab] - // Stability: development + // Stability: release_candidate // // [GitLab]: https://gitlab.com VCSProviderNameGitlab = VCSProviderNameKey.String("gitlab") // [Gitea] - // Stability: development + // Stability: release_candidate // // [Gitea]: https://gitea.io VCSProviderNameGitea = VCSProviderNameKey.String("gitea") // [Bitbucket] - // Stability: development + // Stability: release_candidate // // [Bitbucket]: https://bitbucket.org VCSProviderNameBitbucket = VCSProviderNameKey.String("bitbucket") @@ -17137,12 +15906,12 @@ var ( // Enum values for vcs.ref.base.type var ( // [branch] - // Stability: development + // Stability: release_candidate // // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch VCSRefBaseTypeBranch = VCSRefBaseTypeKey.String("branch") // [tag] - // Stability: development + // Stability: release_candidate // // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag VCSRefBaseTypeTag = VCSRefBaseTypeKey.String("tag") @@ -17151,12 +15920,12 @@ var ( // Enum values for vcs.ref.head.type var ( // [branch] - // Stability: development + // Stability: release_candidate // // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch VCSRefHeadTypeBranch = VCSRefHeadTypeKey.String("branch") // [tag] - // Stability: development + // Stability: release_candidate // // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag VCSRefHeadTypeTag = VCSRefHeadTypeKey.String("tag") @@ -17165,12 +15934,12 @@ var ( // Enum values for vcs.ref.type var ( // [branch] - // Stability: development + // Stability: release_candidate // // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch VCSRefTypeBranch = VCSRefTypeKey.String("branch") // [tag] - // Stability: development + // Stability: release_candidate // // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag VCSRefTypeTag = VCSRefTypeKey.String("tag") @@ -17179,10 +15948,10 @@ var ( // Enum values for vcs.revision_delta.direction var ( // How many revisions the change is behind the target ref. - // Stability: development + // Stability: release_candidate VCSRevisionDeltaDirectionBehind = VCSRevisionDeltaDirectionKey.String("behind") // How many revisions the change is ahead of the target ref. - // Stability: development + // Stability: release_candidate VCSRevisionDeltaDirectionAhead = VCSRevisionDeltaDirectionKey.String("ahead") ) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/doc.go similarity index 83% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/doc.go index a45d424d8..aadce15c0 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/doc.go @@ -6,6 +6,6 @@ // Package semconv implements OpenTelemetry semantic conventions. // // OpenTelemetry semantic conventions are agreed standardized naming -// patterns for OpenTelemetry things. This package represents the v1.41.0 +// patterns for OpenTelemetry things. This package represents the v1.43.0 // version of the OpenTelemetry semantic conventions. -package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" +package semconv diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/error_type.go similarity index 96% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/error_type.go index 0b13f0de8..5d8eff222 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/error_type.go @@ -3,7 +3,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" +package semconv import ( "errors" diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/exception.go similarity index 80% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/exception.go index 5f0151aff..6c9b05adb 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/exception.go @@ -3,7 +3,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0" +package semconv const ( // ExceptionEventName is the name of the Span event representing an exception. diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/httpconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/httpconv/metric.go similarity index 96% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/httpconv/metric.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/httpconv/metric.go index 1b811e2d7..1eb8c9e2a 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/httpconv/metric.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/httpconv/metric.go @@ -9,16 +9,11 @@ package httpconv 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{} }} + "go.opentelemetry.io/otel/semconv/internal/metricpool" ) // ErrorTypeAttr is an attribute conforming to the error.type semantic @@ -170,12 +165,8 @@ func (m ClientActiveRequests) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -201,12 +192,8 @@ func (m ClientActiveRequests) AddSet(ctx context.Context, incr int64, set attrib return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) @@ -417,12 +404,8 @@ func (m ClientConnectionDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -448,24 +431,13 @@ func (m ClientConnectionDuration) RecordSet(ctx context.Context, val float64, se return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) } -// 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) -} - // AttrNetworkProtocolVersion returns an optional attribute for the // "network.protocol.version" semantic convention. It represents the actual // version of the protocol used for network communication. @@ -473,6 +445,13 @@ func (ClientConnectionDuration) AttrNetworkProtocolVersion(val string) attribute 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. @@ -572,12 +551,8 @@ func (m ClientOpenConnections) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -604,24 +579,13 @@ func (m ClientOpenConnections) AddSet(ctx context.Context, incr int64, set attri return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) } -// 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) -} - // AttrNetworkProtocolVersion returns an optional attribute for the // "network.protocol.version" semantic convention. It represents the actual // version of the protocol used for network communication. @@ -629,6 +593,13 @@ func (ClientOpenConnections) AttrNetworkProtocolVersion(val string) attribute.Ke 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. @@ -718,13 +689,6 @@ func (ClientOpenConnectionsObservable) AttrServerPort(val int) attribute.KeyValu return attribute.Int("server.port", 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) -} - // AttrNetworkProtocolVersion returns an optional attribute for the // "network.protocol.version" semantic convention. It represents the actual // version of the protocol used for network communication. @@ -732,6 +696,13 @@ func (ClientOpenConnectionsObservable) AttrNetworkProtocolVersion(val string) at 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. @@ -836,12 +807,8 @@ func (m ClientRequestBodySize) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -875,12 +842,8 @@ func (m ClientRequestBodySize) RecordSet(ctx context.Context, val int64, set att return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Histogram.Record(ctx, val, *o...) @@ -1025,12 +988,8 @@ func (m ClientRequestDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -1057,12 +1016,8 @@ func (m ClientRequestDuration) RecordSet(ctx context.Context, val float64, set a return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) @@ -1213,12 +1168,8 @@ func (m ClientResponseBodySize) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -1252,12 +1203,8 @@ func (m ClientResponseBodySize) RecordSet(ctx context.Context, val int64, set at return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Histogram.Record(ctx, val, *o...) @@ -1398,12 +1345,8 @@ func (m ServerActiveRequests) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -1429,12 +1372,8 @@ func (m ServerActiveRequests) AddSet(ctx context.Context, incr int64, set attrib return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) @@ -1634,12 +1573,8 @@ func (m ServerRequestBodySize) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -1672,12 +1607,8 @@ func (m ServerRequestBodySize) RecordSet(ctx context.Context, val int64, set att return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Histogram.Record(ctx, val, *o...) @@ -1830,12 +1761,8 @@ func (m ServerRequestDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -1861,12 +1788,8 @@ func (m ServerRequestDuration) RecordSet(ctx context.Context, val float64, set a return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) @@ -2025,12 +1948,8 @@ func (m ServerResponseBodySize) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -2063,12 +1982,8 @@ func (m ServerResponseBodySize) RecordSet(ctx context.Context, val int64, set at return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Histogram.Record(ctx, val, *o...) 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 93% 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 d50e19849..9eaf0fd9a 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 @@ -9,16 +9,11 @@ package otelconv 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{} }} + "go.opentelemetry.io/otel/semconv/internal/metricpool" ) // ErrorTypeAttr is an attribute conforming to the error.type semantic @@ -192,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, @@ -205,12 +206,8 @@ func (m SDKExporterLogExported) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -231,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 @@ -240,12 +243,8 @@ func (m SDKExporterLogExported) AddSet(ctx context.Context, incr int64, set attr return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) @@ -442,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, @@ -457,12 +458,8 @@ func (m SDKExporterLogInflight) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -476,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 @@ -487,12 +486,8 @@ func (m SDKExporterLogInflight) AddSet(ctx context.Context, incr int64, set attr return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) @@ -683,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, @@ -696,12 +697,8 @@ func (m SDKExporterMetricDataPointExported) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -722,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 @@ -731,12 +734,8 @@ func (m SDKExporterMetricDataPointExported) AddSet(ctx context.Context, incr int return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) @@ -935,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, @@ -950,12 +951,8 @@ func (m SDKExporterMetricDataPointInflight) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -969,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 @@ -980,12 +979,8 @@ func (m SDKExporterMetricDataPointInflight) AddSet(ctx context.Context, incr int return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) @@ -1175,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 @@ -1191,12 +1191,8 @@ func (m SDKExporterOperationDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -1216,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 @@ -1228,12 +1229,8 @@ func (m SDKExporterOperationDuration) RecordSet(ctx context.Context, val float64 return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) @@ -1357,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, @@ -1370,12 +1372,8 @@ func (m SDKExporterSpanExported) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -1396,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 @@ -1405,12 +1408,8 @@ func (m SDKExporterSpanExported) AddSet(ctx context.Context, incr int64, set att return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) @@ -1607,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, @@ -1622,12 +1623,8 @@ func (m SDKExporterSpanInflight) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -1641,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 @@ -1652,12 +1651,8 @@ func (m SDKExporterSpanInflight) AddSet(ctx context.Context, incr int64, set att return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) @@ -1846,12 +1841,8 @@ func (m SDKLogCreated) Add(ctx context.Context, incr int64, attrs ...attribute.K return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributes(attrs...)) m.Int64Counter.Add(ctx, incr, *o...) @@ -1867,12 +1858,8 @@ func (m SDKLogCreated) AddSet(ctx context.Context, incr int64, set attribute.Set return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) @@ -2018,12 +2005,8 @@ func (m SDKMetricReaderCollectionDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -2051,12 +2034,8 @@ func (m SDKMetricReaderCollectionDuration) RecordSet(ctx context.Context, val fl return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) @@ -2148,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. @@ -2164,12 +2148,8 @@ func (m SDKProcessorLogProcessed) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -2185,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. @@ -2197,12 +2182,8 @@ func (m SDKProcessorLogProcessed) AddSet(ctx context.Context, incr int64, set at return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) @@ -2210,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)) } @@ -2292,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)) } @@ -2525,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. @@ -2541,12 +2522,8 @@ func (m SDKProcessorSpanProcessed) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -2562,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. @@ -2574,12 +2555,8 @@ func (m SDKProcessorSpanProcessed) AddSet(ctx context.Context, incr int64, set a return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) @@ -2587,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)) } @@ -2669,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)) } @@ -2899,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, @@ -2912,12 +2888,8 @@ func (m SDKSpanLive) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -2930,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 @@ -2939,12 +2914,8 @@ func (m SDKSpanLive) AddSet(ctx context.Context, incr int64, set attribute.Set) return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64UpDownCounter.Add(ctx, incr, *o...) @@ -3100,12 +3071,8 @@ func (m SDKSpanStarted) Add( return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append( *o, @@ -3130,12 +3097,8 @@ func (m SDKSpanStarted) AddSet(ctx context.Context, incr int64, set attribute.Se return } - o := addOptPool.Get().(*[]metric.AddOption) - defer func() { - clear(*o) - *o = (*o)[:0] - addOptPool.Put(o) - }() + o := metricpool.AddOptions() + defer metricpool.PutAddOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Int64Counter.Add(ctx, incr, *o...) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/rpcconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv/metric.go similarity index 94% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/rpcconv/metric.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv/metric.go index 7b4acec91..c766d4b9e 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/rpcconv/metric.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/rpcconv/metric.go @@ -9,16 +9,11 @@ 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{} }} + "go.opentelemetry.io/otel/semconv/internal/metricpool" ) // ErrorTypeAttr is an attribute conforming to the error.type semantic @@ -138,12 +133,8 @@ func (m ClientCallDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -171,12 +162,8 @@ func (m ClientCallDuration) RecordSet(ctx context.Context, val float64, set attr return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) @@ -299,12 +286,8 @@ func (m ServerCallDuration) Record( return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append( *o, @@ -332,12 +315,8 @@ func (m ServerCallDuration) RecordSet(ctx context.Context, val float64, set attr return } - o := recOptPool.Get().(*[]metric.RecordOption) - defer func() { - clear(*o) - *o = (*o)[:0] - recOptPool.Put(o) - }() + o := metricpool.RecordOptions() + defer metricpool.PutRecordOptions(o) *o = append(*o, metric.WithAttributeSet(set)) m.Float64Histogram.Record(ctx, val, *o...) diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/schema.go similarity index 75% rename from vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go rename to vendor/go.opentelemetry.io/otel/semconv/v1.43.0/schema.go index 24948a48f..ce5f5f5c5 100644 --- a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go +++ b/vendor/go.opentelemetry.io/otel/semconv/v1.43.0/schema.go @@ -3,9 +3,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.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.41.0" +const SchemaURL = "https://opentelemetry.io/schemas/1.43.0" diff --git a/vendor/go.opentelemetry.io/otel/trace.go b/vendor/go.opentelemetry.io/otel/trace.go index 6836c6547..9c1567a2e 100644 --- a/vendor/go.opentelemetry.io/otel/trace.go +++ b/vendor/go.opentelemetry.io/otel/trace.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel import ( "go.opentelemetry.io/otel/internal/global" diff --git a/vendor/go.opentelemetry.io/otel/trace/auto.go b/vendor/go.opentelemetry.io/otel/trace/auto.go index a75cf047d..17cf898cd 100644 --- a/vendor/go.opentelemetry.io/otel/trace/auto.go +++ b/vendor/go.opentelemetry.io/otel/trace/auto.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "context" @@ -20,7 +20,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" "go.opentelemetry.io/otel/trace/embedded" "go.opentelemetry.io/otel/trace/internal/telemetry" ) @@ -358,6 +358,16 @@ func convAttrValue(value attribute.Value) telemetry.Value { out = append(out, convAttrValue(v)) } return telemetry.SliceValue(out...) + case attribute.MAP: + kvs := value.AsMap() + out := make([]telemetry.Attr, 0, len(kvs)) + for _, kv := range kvs { + out = append(out, telemetry.Attr{ + Key: string(kv.Key), + Value: convAttrValue(kv.Value), + }) + } + return telemetry.MapValue(out...) } return telemetry.Value{} } diff --git a/vendor/go.opentelemetry.io/otel/trace/config.go b/vendor/go.opentelemetry.io/otel/trace/config.go index 4cedba5ac..862ecc898 100644 --- a/vendor/go.opentelemetry.io/otel/trace/config.go +++ b/vendor/go.opentelemetry.io/otel/trace/config.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "slices" diff --git a/vendor/go.opentelemetry.io/otel/trace/context.go b/vendor/go.opentelemetry.io/otel/trace/context.go index 8c45a7107..89927eda6 100644 --- a/vendor/go.opentelemetry.io/otel/trace/context.go +++ b/vendor/go.opentelemetry.io/otel/trace/context.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import "context" diff --git a/vendor/go.opentelemetry.io/otel/trace/doc.go b/vendor/go.opentelemetry.io/otel/trace/doc.go index cdbf41d6d..57de8f348 100644 --- a/vendor/go.opentelemetry.io/otel/trace/doc.go +++ b/vendor/go.opentelemetry.io/otel/trace/doc.go @@ -116,4 +116,4 @@ It is strongly recommended that authors only embed That implementation is the only one OpenTelemetry authors can guarantee will fully implement all the API interfaces when a user updates their API. */ -package trace // import "go.opentelemetry.io/otel/trace" +package trace diff --git a/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go index 3e359a00b..59d8a510b 100644 --- a/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go +++ b/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go @@ -11,7 +11,7 @@ // the API package). // // [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace -package embedded // import "go.opentelemetry.io/otel/trace/embedded" +package embedded // TracerProvider is embedded in // [go.opentelemetry.io/otel/trace.TracerProvider]. diff --git a/vendor/go.opentelemetry.io/otel/trace/hex.go b/vendor/go.opentelemetry.io/otel/trace/hex.go index 1cbef1d4b..5f156b0dc 100644 --- a/vendor/go.opentelemetry.io/otel/trace/hex.go +++ b/vendor/go.opentelemetry.io/otel/trace/hex.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace const ( // hexLU is a hex lookup table of the 16 lowercase hex digits. diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/attr.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/attr.go index ff0f6eac6..9503318eb 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/attr.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/attr.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry // Attr is a key-value pair. type Attr struct { diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/doc.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/doc.go index 5debe90bb..949e2165c 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/doc.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/doc.go @@ -5,4 +5,4 @@ Package telemetry provides a lightweight representations of OpenTelemetry telemetry that is compatible with the OTLP JSON protobuf encoding. */ -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/id.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/id.go index bea56f2e7..3a6d6b87a 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/id.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/id.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "encoding/hex" diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/number.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/number.go index f5e3a8cec..29e629d66 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/number.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/number.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "encoding/json" diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/resource.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/resource.go index 1798a702d..cecad8bae 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/resource.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/resource.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "bytes" diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/scope.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/scope.go index c2b4c635b..b6f2e28d4 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/scope.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/scope.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "bytes" diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go index 61c7819a2..0da6e5fd6 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "bytes" diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go index 1039bf40c..5dac1b2cb 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry // StatusCode is the status of a Span. // diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go index e5f10767c..44197b808 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "bytes" diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go index cb7927b81..9d2d68063 100644 --- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go +++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package telemetry // import "go.opentelemetry.io/otel/trace/internal/telemetry" +package telemetry import ( "bytes" diff --git a/vendor/go.opentelemetry.io/otel/trace/nonrecording.go b/vendor/go.opentelemetry.io/otel/trace/nonrecording.go index c00221e7b..d672f03c2 100644 --- a/vendor/go.opentelemetry.io/otel/trace/nonrecording.go +++ b/vendor/go.opentelemetry.io/otel/trace/nonrecording.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace // nonRecordingSpan is a minimal implementation of a Span that wraps a // SpanContext. It performs no operations other than to return the wrapped diff --git a/vendor/go.opentelemetry.io/otel/trace/noop.go b/vendor/go.opentelemetry.io/otel/trace/noop.go index 400fab123..b954251b2 100644 --- a/vendor/go.opentelemetry.io/otel/trace/noop.go +++ b/vendor/go.opentelemetry.io/otel/trace/noop.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/trace/noop/noop.go b/vendor/go.opentelemetry.io/otel/trace/noop/noop.go index 689d220df..4f8190e41 100644 --- a/vendor/go.opentelemetry.io/otel/trace/noop/noop.go +++ b/vendor/go.opentelemetry.io/otel/trace/noop/noop.go @@ -10,7 +10,7 @@ // This implementation can be embedded in other implementations of the // OpenTelemetry trace API. Doing so will mean the implementation defaults to // no operation for methods it does not implement. -package noop // import "go.opentelemetry.io/otel/trace/noop" +package noop import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/trace/provider.go b/vendor/go.opentelemetry.io/otel/trace/provider.go index ef85cb70c..891cc0b8c 100644 --- a/vendor/go.opentelemetry.io/otel/trace/provider.go +++ b/vendor/go.opentelemetry.io/otel/trace/provider.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import "go.opentelemetry.io/otel/trace/embedded" diff --git a/vendor/go.opentelemetry.io/otel/trace/span.go b/vendor/go.opentelemetry.io/otel/trace/span.go index d01e79366..603b2c146 100644 --- a/vendor/go.opentelemetry.io/otel/trace/span.go +++ b/vendor/go.opentelemetry.io/otel/trace/span.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/trace/trace.go b/vendor/go.opentelemetry.io/otel/trace/trace.go index e3d103c4b..c4c383819 100644 --- a/vendor/go.opentelemetry.io/otel/trace/trace.go +++ b/vendor/go.opentelemetry.io/otel/trace/trace.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "encoding/json" diff --git a/vendor/go.opentelemetry.io/otel/trace/tracer.go b/vendor/go.opentelemetry.io/otel/trace/tracer.go index 77952d2a0..7e6e5ee93 100644 --- a/vendor/go.opentelemetry.io/otel/trace/tracer.go +++ b/vendor/go.opentelemetry.io/otel/trace/tracer.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "context" diff --git a/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/vendor/go.opentelemetry.io/otel/trace/tracestate.go index e9cb3fd4d..9ac78fa04 100644 --- a/vendor/go.opentelemetry.io/otel/trace/tracestate.go +++ b/vendor/go.opentelemetry.io/otel/trace/tracestate.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package trace // import "go.opentelemetry.io/otel/trace" +package trace import ( "encoding/json" diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index 72746acfd..ea7903096 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -1,9 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otel // import "go.opentelemetry.io/otel" +package otel // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.44.0" + return "1.45.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index d6dbf803e..3b1ad7301 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.44.0 + version: v1.45.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.66.0 + version: v0.67.0 modules: - go.opentelemetry.io/otel/exporters/prometheus - go.opentelemetry.io/otel/metric/x experimental-logs: - version: v0.20.0 + version: v0.21.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.17 + version: v0.0.18 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 304f64763..cef358000 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.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go b/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go index 748c9fb1c..e148ddd13 100644 --- a/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go +++ b/vendor/go.opentelemetry.io/proto/otlp/metrics/v1/metrics.pb.go @@ -527,7 +527,7 @@ type Metric struct { // A description of the metric, which can be used in documentation. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // The unit in which the metric value is reported. Follows the format - // described by https://unitsofmeasure.org/ucum.html. + // described by https://ucum.org/ucum and https://units-of-measurement.org/ Unit string `protobuf:"bytes,3,opt,name=unit,proto3" json:"unit,omitempty"` // Data determines the aggregation type (if any) of the metric, what is the // reported value type for the data points, as well as the relatationship to 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 8d99551fe..b1da45687 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 315b84ac3..55041bf51 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 000000000..ce5eb3d43 --- /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/crypto/ssh/agent/keyring.go b/vendor/golang.org/x/crypto/ssh/agent/keyring.go index a9e29b6f8..a4f4c11e4 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/keyring.go +++ b/vendor/golang.org/x/crypto/ssh/agent/keyring.go @@ -104,7 +104,7 @@ func (r *keyring) Unlock(passphrase []byte) error { if !r.locked { return errors.New("agent: not locked") } - if 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) { + if subtle.ConstantTimeCompare(passphrase, r.passphrase) != 1 { return fmt.Errorf("agent: incorrect passphrase") } diff --git a/vendor/golang.org/x/crypto/ssh/agent/server.go b/vendor/golang.org/x/crypto/ssh/agent/server.go index 782c54eb7..27394125d 100644 --- a/vendor/golang.org/x/crypto/ssh/agent/server.go +++ b/vendor/golang.org/x/crypto/ssh/agent/server.go @@ -246,10 +246,10 @@ func setConstraints(key *AddedKey, constraintBytes []byte) error { // on arbitrary inputs; the CRT coefficient recomputation is cubic in // |p| and can consume excessive CPU on oversized keys. func checkRSAKeyParams(N, E, P, Q *big.Int) error { - if N.BitLen() > 8192 { + if N.BitLen() > 16384 { return errors.New("agent: RSA modulus too large") } - if P.BitLen() > 4096 || Q.BitLen() > 4096 { + if P.BitLen() > 8192 || Q.BitLen() > 8192 { return errors.New("agent: RSA prime too large") } if E.BitLen() > 24 { diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go index 6f75d77ec..fa848f51a 100644 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ b/vendor/golang.org/x/crypto/ssh/certs.go @@ -229,15 +229,20 @@ func parseCert(in []byte, privAlgo string) (*Certificate, error) { return nil, err } c.Reserved = g.Reserved + // Reject a certificate whose signature key is itself a certificate before + // parsing it. Certificates signed by certificates are not supported (see + // PROTOCOL.certkeys), and rejecting after ParsePublicKey returns would allow + // a chain of nested certificates to recurse once per level, exhausting the + // goroutine stack. + if sigAlgo, _, ok := parseString(g.SignatureKey); !ok { + return nil, errShortRead + } else if _, ok := certKeyAlgoNames[string(sigAlgo)]; ok { + return nil, fmt.Errorf("ssh: the signature key type %q is invalid for certificates", sigAlgo) + } k, err := ParsePublicKey(g.SignatureKey) if err != nil { return nil, err } - // The Type() function is intended to return only certificate key types, but - // we use certKeyAlgoNames anyway for safety, to match [Certificate.Type]. - if _, ok := certKeyAlgoNames[k.Type()]; ok { - return nil, fmt.Errorf("ssh: the signature key type %q is invalid for certificates", k.Type()) - } c.SignatureKey = k c.Signature, rest, ok = parseSignatureBody(g.Signature) if !ok || len(rest) > 0 { diff --git a/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go index afc9aef18..ba3279e91 100644 --- a/vendor/golang.org/x/crypto/ssh/channel.go +++ b/vendor/golang.org/x/crypto/ssh/channel.go @@ -216,6 +216,10 @@ type channel struct { // packetPool has a buffer for each extended channel ID to // save allocations during writes. packetPool map[uint32][]byte + + // closeOnce guards close so it is idempotent: closing the internal Go + // channels (msg, incomingRequests) more than once would panic. + closeOnce sync.Once } // writePacket sends a packet. If the packet is a channel close, it updates @@ -340,7 +344,18 @@ func (ch *channel) handleData(packet []byte) error { if extended == 1 { ch.extPending.write(data) } else if extended > 0 { - // discard other extended data. + // RFC 4254, Section 5.2 defines no extended data types other + // than stderr (type 1, handled above) and this package provides + // no API to read them, so the data is discarded. Credit its + // window back immediately: it can never be read, so the + // deduction above would otherwise shrink the window permanently. + // adjustWindow returns io.EOF if the local side has already + // sent a channel close; ignore it like ReadExtended does, since + // an error returned here would terminate the mux read loop and + // tear down the whole connection. + if err := ch.adjustWindow(length); err != nil && err != io.EOF { + return err + } } else { ch.pending.write(data) } @@ -393,17 +408,19 @@ func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) } func (c *channel) close() { - c.pending.eof() - c.extPending.eof() - close(c.msg) - close(c.incomingRequests) - c.writeMu.Lock() - // This is not necessary for a normal channel teardown, but if - // there was another error, it is. - c.sentClose = true - c.writeMu.Unlock() - // Unblock writers. - c.remoteWin.close() + c.closeOnce.Do(func() { + c.pending.eof() + c.extPending.eof() + close(c.msg) + close(c.incomingRequests) + c.writeMu.Lock() + // This is not necessary for a normal channel teardown, but if + // there was another error, it is. + c.sentClose = true + c.writeMu.Unlock() + // Unblock writers. + c.remoteWin.close() + }) } // responseMessageReceived is called when a success or failure message is @@ -493,19 +510,20 @@ func (ch *channel) handlePacket(packet []byte) error { func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel { ch := &channel{ - remoteWin: window{Cond: newCond()}, - myWindow: channelWindowSize, - pending: newBuffer(), - extPending: newBuffer(), - direction: direction, - incomingRequests: make(chan *Request, chanSize), - msg: make(chan interface{}, chanSize), - chanType: chanType, - extraData: extraData, - mux: m, - packetPool: make(map[uint32][]byte), + remoteWin: window{Cond: newCond()}, + myWindow: channelWindowSize, + maxIncomingPayload: channelMaxPacket, + pending: newBuffer(), + extPending: newBuffer(), + direction: direction, + incomingRequests: make(chan *Request, chanSize), + msg: make(chan interface{}, chanSize), + chanType: chanType, + extraData: extraData, + mux: m, + packetPool: make(map[uint32][]byte), } - ch.localId = m.chanList.add(ch) + m.chanList.add(ch) return ch } @@ -529,7 +547,6 @@ func (ch *channel) Accept() (Channel, <-chan *Request, error) { if ch.decided { return nil, nil, errDecidedAlready } - ch.maxIncomingPayload = channelMaxPacket confirm := channelOpenConfirmMsg{ PeersID: ch.remoteId, MyID: ch.localId, diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go index 60af2fc4d..138cc9003 100644 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ b/vendor/golang.org/x/crypto/ssh/client_auth.go @@ -798,7 +798,7 @@ func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, return authFailure, nil, fmt.Errorf("GSS-API Error:\n"+ "Major Status: %d\n"+ "Minor Status: %d\n"+ - "Error Message: %s\n", userAuthGSSAPIErrorResp.MajorStatus, userAuthGSSAPIErrorResp.MinorStatus, + "Error Message: %q\n", userAuthGSSAPIErrorResp.MajorStatus, userAuthGSSAPIErrorResp.MinorStatus, userAuthGSSAPIErrorResp.Message) case msgUserAuthGSSAPIToken: userAuthGSSAPITokenReq := &userAuthGSSAPIToken{} diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go index 2e44e9c9e..aed0fd926 100644 --- a/vendor/golang.org/x/crypto/ssh/common.go +++ b/vendor/golang.org/x/crypto/ssh/common.go @@ -419,7 +419,7 @@ type AlgorithmNegotiationError struct { } func (a *AlgorithmNegotiationError) Error() string { - return fmt.Sprintf("ssh: no common algorithm for %s; we offered: %v, peer offered: %v", + return fmt.Sprintf("ssh: no common algorithm for %s; we offered: %q, peer offered: %q", a.What, a.SupportedAlgorithms, a.RequestedAlgorithms) } @@ -544,7 +544,7 @@ func (c *Config) SetDefaults() { if c.Rand == nil { c.Rand = rand.Reader } - if c.Ciphers == nil { + if len(c.Ciphers) == 0 { c.Ciphers = defaultCiphers } var ciphers []string @@ -556,7 +556,7 @@ func (c *Config) SetDefaults() { } c.Ciphers = ciphers - if c.KeyExchanges == nil { + if len(c.KeyExchanges) == 0 { c.KeyExchanges = defaultKexAlgos } var kexs []string @@ -571,7 +571,7 @@ func (c *Config) SetDefaults() { } c.KeyExchanges = kexs - if c.MACs == nil { + if len(c.MACs) == 0 { c.MACs = defaultMACs } var macs []string diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go index 378f6407b..9e0ed089c 100644 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ b/vendor/golang.org/x/crypto/ssh/connection.go @@ -17,7 +17,7 @@ type OpenChannelError struct { } func (e *OpenChannelError) Error() string { - return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message) + return fmt.Sprintf("ssh: rejected: %s (%q)", e.Reason, e.Message) } // ConnMetadata holds metadata for the connection. diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index 4be3cbb6d..711a7f7c4 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -162,7 +162,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt t.remoteAddr = addr t.hostKeyCallback = config.HostKeyCallback t.bannerCallback = config.BannerCallback - if config.HostKeyAlgorithms != nil { + if len(config.HostKeyAlgorithms) > 0 { t.hostKeyAlgorithms = config.HostKeyAlgorithms } else { t.hostKeyAlgorithms = defaultHostKeyAlgos diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 64377715e..fbbfb6cf4 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -485,10 +485,11 @@ func parseRSA(in []byte) (out PublicKey, rest []byte, err error) { return nil, nil, err } - // 8192 bits is also the maximum RSA key size accepted by crypto/tls for - // signature verification: - // https://github.com/golang/go/blob/69801b25/src/crypto/tls/handshake_client.go#L1096 - if w.N.BitLen() > 8192 { + // 16384 bits is the largest RSA key OpenSSH will generate (ssh-keygen + // caps -b at 16384), so it is the practical upper bound for keys seen on + // the wire. Rejecting anything larger bounds the CPU spent verifying an + // attacker-supplied key and signature, mitigating a denial of service. + if w.N.BitLen() > 16384 { return nil, nil, errors.New("ssh: rsa modulus too large") } if w.E.BitLen() > 24 { @@ -1669,13 +1670,13 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv } // Mirror the validation done in parseRSA for public keys: cap the - // modulus at the same limit enforced by crypto/tls, reject oversized - // or invalid exponents, and additionally bound the prime factors to + // modulus at the OpenSSH-generated maximum, reject oversized or + // invalid exponents, and additionally bound the prime factors to // avoid the expensive CRT coefficient recomputation in pk.Precompute. - if key.N.BitLen() > 8192 { + if key.N.BitLen() > 16384 { return nil, errors.New("ssh: rsa modulus too large") } - if key.P.BitLen() > 4096 || key.Q.BitLen() > 4096 { + if key.P.BitLen() > 8192 || key.Q.BitLen() > 8192 { return nil, errors.New("ssh: rsa prime too large") } if key.E.BitLen() > 24 { diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go index de86f71cf..1d23dde25 100644 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ b/vendor/golang.org/x/crypto/ssh/messages.go @@ -44,16 +44,7 @@ type disconnectMsg struct { } func (d *disconnectMsg) Error() string { - return fmt.Sprintf("ssh: disconnect, reason %d: %q", d.Reason, sanitizeString(d.Message)) -} - -func sanitizeString(s string) string { - return strings.Map(func(r rune) rune { - if r == '\t' || (r >= ' ' && r < 0x7f) { - return r - } - return -1 - }, s) + return fmt.Sprintf("ssh: disconnect, reason %d: %q", d.Reason, d.Message) } // See RFC 4253, section 7.1. diff --git a/vendor/golang.org/x/crypto/ssh/mux.go b/vendor/golang.org/x/crypto/ssh/mux.go index 5775881c6..955560bda 100644 --- a/vendor/golang.org/x/crypto/ssh/mux.go +++ b/vendor/golang.org/x/crypto/ssh/mux.go @@ -32,18 +32,21 @@ type chanList struct { offset uint32 } -// Assigns a channel ID to the given channel. -func (c *chanList) add(ch *channel) uint32 { +// add stores the given channel and assigns its localId while holding the +// lock, so that getChan can never return a channel whose localId is not yet +// initialized. +func (c *chanList) add(ch *channel) { c.Lock() defer c.Unlock() for i := range c.chans { if c.chans[i] == nil { c.chans[i] = ch - return uint32(i) + c.offset + ch.localId = uint32(i) + c.offset + return } } c.chans = append(c.chans, ch) - return uint32(len(c.chans)-1) + c.offset + ch.localId = uint32(len(c.chans)-1) + c.offset } // getChan returns the channel for the given ID. @@ -343,8 +346,6 @@ func (m *mux) OpenChannel(chanType string, extra []byte) (Channel, <-chan *Reque func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) { ch := m.newChannel(chanType, channelOutbound, extra) - ch.maxIncomingPayload = channelMaxPacket - open := channelOpenMsg{ ChanType: chanType, PeersWindow: ch.myWindow, diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 3c0fcc953..e09026268 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -26,10 +26,16 @@ type Permissions struct { // defines "force-command" (only allow the given command to // execute) and "source-address" (only allow connections from // the given address). The SSH package currently only enforces - // the "source-address" critical option. It is up to server - // implementations to enforce other critical options, such as - // "force-command", by checking them after the SSH handshake - // is successful. In general, SSH servers should reject + // the "source-address" critical option: it is validated against + // the client's remote address whenever it is present in the + // Permissions returned by any authentication callback. Its value + // is a comma-separated list of IP addresses and CIDR blocks; + // consistently with OpenSSH, a connection whose remote address is + // not an IP address, such as a Unix domain socket, never matches + // the list and is rejected when the option is present. It is up + // to server implementations to enforce other critical options, + // such as "force-command", by checking them after the SSH + // handshake is successful. In general, SSH servers should reject // connections that specify critical options that are unknown // or not supported. CriticalOptions map[string]string @@ -223,7 +229,9 @@ type ServerConfig struct { // Permissions object can be the same object, optionally modified, or a // completely new object. If VerifiedPublicKeyCallback is non-nil, // PublicKeyCallback is not allowed to return a PartialSuccessError, which - // can instead be returned by VerifiedPublicKeyCallback. + // can instead be returned by VerifiedPublicKeyCallback. The + // signatureAlgorithm argument is the format of the signature that was + // successfully verified. // // VerifiedPublicKeyCallback does not affect which authentication methods // are included in the list of methods that can be attempted by the client. @@ -442,6 +450,10 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) return perms, err } +// checkSourceAddress matches addr against sourceAddrs, a comma-separated list +// of IP addresses and CIDR blocks. Consistently with OpenSSH, a remote address +// that is not IP-based, such as a Unix domain socket, never matches the list +// and is rejected. func checkSourceAddress(addr net.Addr, sourceAddrs string) error { if addr == nil { return errors.New("ssh: no address known for client, but source-address match required") @@ -449,7 +461,7 @@ func checkSourceAddress(addr net.Addr, sourceAddrs string) error { tcpAddr, ok := addr.(*net.TCPAddr) if !ok { - return fmt.Errorf("ssh: remote address %v is not an TCP address when checking source-address match", addr) + return fmt.Errorf("ssh: remote address %v is not a TCP address when checking source-address match", addr) } for _, sourceAddr := range strings.Split(sourceAddrs, ",") { @@ -472,6 +484,21 @@ func checkSourceAddress(addr net.Addr, sourceAddrs string) error { return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr) } +// checkSourceAddressCriticalOption enforces the source-address critical +// option, if present in perms, as documented in Permissions.CriticalOptions. +// A present but empty value matches no address, so it denies authentication, +// consistently with OpenSSH, rather than being treated as absent. +func checkSourceAddressCriticalOption(addr net.Addr, perms *Permissions) error { + if perms == nil { + return nil + } + saco, ok := perms.CriticalOptions[sourceAddressCriticalOption] + if !ok { + return nil + } + return checkSourceAddress(addr, saco) +} + func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, token []byte, s *connection, sessionID []byte, userAuthReq userAuthRequestMsg) (authErr error, perms *Permissions, err error) { gssAPIServer := gssapiConfig.Server @@ -685,7 +712,7 @@ userAuthLoop: } if userAuthReq.Service != serviceSSH { - return nil, errors.New("ssh: client attempted to negotiate for unknown service: " + userAuthReq.Service) + return nil, fmt.Errorf("ssh: client attempted to negotiate for unknown service: %q", userAuthReq.Service) } if s.user != userAuthReq.User && partialSuccessReturned { @@ -771,7 +798,8 @@ userAuthLoop: pubKey, err := ParsePublicKey(pubKeyData) if err != nil { - return nil, err + authErr = err + break } candidate, ok := cache.get(s.user, pubKeyData) @@ -784,13 +812,14 @@ userAuthLoop: return nil, errors.New("ssh: invalid library usage: PublicKeyCallback must not return partial success when VerifiedPublicKeyCallback is defined") } - if (candidate.result == nil || isPartialSuccessError) && - candidate.perms != nil && - candidate.perms.CriticalOptions != nil && - candidate.perms.CriticalOptions[sourceAddressCriticalOption] != "" { - if err := checkSourceAddress( - s.RemoteAddr(), - candidate.perms.CriticalOptions[sourceAddressCriticalOption]); err != nil { + // This check is authoritative for the Permissions returned by + // PublicKeyCallback: the check at the end of the auth loop sees + // the final Permissions, which VerifiedPublicKeyCallback may + // have replaced, and is skipped on partial success. It also + // makes public key queries fail before the client signs when + // PublicKeyCallback supplies the restriction. + if candidate.result == nil || isPartialSuccessError { + if err := checkSourceAddressCriticalOption(s.RemoteAddr(), candidate.perms); err != nil { candidate.result = err } } @@ -864,14 +893,7 @@ userAuthLoop: // Only call VerifiedPublicKeyCallback after the key has been accepted // and successfully verified. If authErr is non-nil, the key is not // considered verified and the callback must not run. - perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, algo) - } - if authErr == nil && perms != nil && perms.CriticalOptions != nil { - if saco := perms.CriticalOptions[sourceAddressCriticalOption]; saco != "" { - if err := checkSourceAddress(s.RemoteAddr(), saco); err != nil { - authErr = err - } - } + perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, sig.Format) } } case "gssapi-with-mic": @@ -925,6 +947,17 @@ userAuthLoop: authErr = fmt.Errorf("ssh: unknown method %q", userAuthReq.Method) } + // The source-address critical option is enforced on the Permissions + // returned by any authentication callback. Permissions returned + // together with a PartialSuccessError skip this check: that is safe + // because they are required to be nil, as enforced in the partial + // success handling below. + if authErr == nil { + if err := checkSourceAddressCriticalOption(s.RemoteAddr(), perms); err != nil { + authErr = err + } + } + authErrs = append(authErrs, authErr) if config.AuthLogCallback != nil { diff --git a/vendor/golang.org/x/crypto/ssh/ssh_gss.go b/vendor/golang.org/x/crypto/ssh/ssh_gss.go index a6249a122..a7a099754 100644 --- a/vendor/golang.org/x/crypto/ssh/ssh_gss.go +++ b/vendor/golang.org/x/crypto/ssh/ssh_gss.go @@ -118,24 +118,28 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) { OIDS: make([]asn1.ObjectIdentifier, n), } for i := 0; i < int(n); i++ { - var ( - desiredMech []byte - err error - ) + var desiredMech []byte desiredMech, rest, ok = parseString(rest) if !ok { return nil, errors.New("parse string failed") } - if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil { + trailing, err := asn1.Unmarshal(desiredMech, &s.OIDS[i]) + if err != nil { return nil, err } + if len(trailing) != 0 { + return nil, errors.New("trailing bytes after OID") + } + } + if len(rest) != 0 { + return nil, errors.New("trailing bytes after mechanisms") } return s, nil } // See RFC 4462 section 3.6. func buildMIC(sessionID string, username string, service string, authMethod string) []byte { - out := make([]byte, 0, 0) + out := make([]byte, 0) out = appendString(out, sessionID) out = append(out, msgUserAuthRequest) out = appendString(out, username) diff --git a/vendor/golang.org/x/crypto/ssh/streamlocal.go b/vendor/golang.org/x/crypto/ssh/streamlocal.go index 152470fcb..8e997da3d 100644 --- a/vendor/golang.org/x/crypto/ssh/streamlocal.go +++ b/vendor/golang.org/x/crypto/ssh/streamlocal.go @@ -58,6 +58,7 @@ func (c *Client) dialStreamLocal(socketPath string) (Channel, error) { return nil, err } go DiscardRequests(in) + go io.Copy(io.Discard, ch.Stderr()) return ch, err } @@ -79,6 +80,7 @@ func (l *unixListener) Accept() (net.Conn, error) { return nil, err } go DiscardRequests(incoming) + go io.Copy(io.Discard, ch.Stderr()) return &chanConn{ Channel: ch, diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go index 78c41fe5a..213d8a614 100644 --- a/vendor/golang.org/x/crypto/ssh/tcpip.go +++ b/vendor/golang.org/x/crypto/ssh/tcpip.go @@ -332,6 +332,7 @@ func (l *tcpListener) Accept() (net.Conn, error) { return nil, err } go DiscardRequests(incoming) + go io.Copy(io.Discard, ch.Stderr()) return &chanConn{ Channel: ch, @@ -495,6 +496,7 @@ func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel return nil, err } go DiscardRequests(in) + go io.Copy(io.Discard, ch.Stderr()) return ch, nil } diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 46219da2b..e6d0c265a 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 7a1d97669..ecd3eeca9 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 8cbdf3f01..3bd7eb753 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 534e77ab9..741fb9706 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 { - cc.mu.Lock() - defer cc.mu.Unlock() - if cc.doNotReuse { - return false - } if err := cc.cc.Reserve(); err != nil { return false } - cc.reserved++ - return true + reserved := true + cc.mu.Lock() + if cc.doNotReuse { + reserved = false + } else { + cc.reserved++ + } + cc.mu.Unlock() + if !reserved { + cc.cc.Release() + } + return reserved } func (cc *ClientConn) setDoNotReuse() { diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index c4bca5203..b27c7e84a 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -24,12 +24,10 @@ import ( "fmt" "math" "net/url" - "os" "slices" "strings" "sync" "sync/atomic" - "syscall" "time" "google.golang.org/grpc/balancer" @@ -1573,26 +1571,13 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address, // to the provided transport.GoAwayInfo, as specified by gRFC A94: // https://github.com/grpc/proposal/blob/master/A94-grpc-subchannel-disconnections-metrics.md func disconnectErrorString(info transport.GoAwayInfo) string { - err := info.Err - var sysErr syscall.Errno - switch { - case info.Reason != transport.GoAwayInvalid: + if info.Reason != transport.GoAwayInvalid { return fmt.Sprintf("GOAWAY %s", info.GoAwayCode.String()) - case err == nil: - return "unknown" - case errors.Is(err, context.Canceled): - return "subchannel shutdown" - case errors.Is(err, syscall.ECONNRESET): - return "connection reset" - case errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded): - return "connection timed out" - case errors.Is(err, syscall.ECONNABORTED): - return "connection aborted" - case errors.As(err, &sysErr): - return "socket error" - default: + } + if info.Err == nil { return "unknown" } + return disconnectErrorLabel(info.Err) } // startHealthCheck starts the health checking stream (RPC) to watch the health diff --git a/vendor/google.golang.org/grpc/clientconn_disconnect_reason_noplan9.go b/vendor/google.golang.org/grpc/clientconn_disconnect_reason_noplan9.go new file mode 100644 index 000000000..f0fcd8842 --- /dev/null +++ b/vendor/google.golang.org/grpc/clientconn_disconnect_reason_noplan9.go @@ -0,0 +1,48 @@ +//go:build !plan9 + +/* + * + * Copyright 2026 gRPC 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. + * + */ + +package grpc + +import ( + "context" + "errors" + "os" + "syscall" +) + +// disconnectErrorLabel returns the grpc.disconnect_error metric label for a +// transport error, as specified by gRFC A94. +func disconnectErrorLabel(err error) string { + var sysErr syscall.Errno + switch { + case errors.Is(err, context.Canceled): + return "subchannel shutdown" + case errors.Is(err, syscall.ECONNRESET): + return "connection reset" + case errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded): + return "connection timed out" + case errors.Is(err, syscall.ECONNABORTED): + return "connection aborted" + case errors.As(err, &sysErr): + return "socket error" + default: + return "unknown" + } +} diff --git a/vendor/google.golang.org/grpc/clientconn_disconnect_reason_plan9.go b/vendor/google.golang.org/grpc/clientconn_disconnect_reason_plan9.go new file mode 100644 index 000000000..930b12664 --- /dev/null +++ b/vendor/google.golang.org/grpc/clientconn_disconnect_reason_plan9.go @@ -0,0 +1,39 @@ +/* + * + * Copyright 2026 gRPC 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. + * + */ + +package grpc + +import ( + "context" + "errors" + "os" +) + +// disconnectErrorLabel returns the grpc.disconnect_error metric label for a +// transport error, as specified by gRFC A94. syscall.Errno does not exist on +// plan9, so only the portable classifications are available. +func disconnectErrorLabel(err error) string { + switch { + case errors.Is(err, context.Canceled): + return "subchannel shutdown" + case errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded): + return "connection timed out" + default: + return "unknown" + } +} diff --git a/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/grpc.go b/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/grpc.go index cff016d66..31344f175 100644 --- a/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/grpc.go +++ b/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/grpc.go @@ -178,13 +178,8 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen. g.P("// This is a compile-time assertion to ensure that this generated file") g.P("// is compatible with the grpc package it is being compiled against.") - if *useGenericStreams { - g.P("// Requires gRPC-Go v1.64.0 or later.") - g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion9")) - } else { - g.P("// Requires gRPC-Go v1.62.0 or later.") - g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion8")) // When changing, update version number above. - } + g.P("// Requires gRPC-Go v1.64.0 or later.") + g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion9")) g.P() for _, service := range file.Services { genService(gen, file, g, service) @@ -333,11 +328,7 @@ func clientSignature(g *protogen.GeneratedFile, method *protogen.Method) string if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { s += "*" + g.QualifiedGoIdent(method.Output.GoIdent) } else { - if *useGenericStreams { - s += clientStreamInterface(g, method) - } else { - s += method.Parent.GoName + "_" + method.GoName + "Client" - } + s += clientStreamInterface(g, method) } s += ", error)" return s @@ -373,12 +364,8 @@ func genClientMethod(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated return } - streamImpl := unexport(service.GoName) + method.GoName + "Client" - if *useGenericStreams { - typeParam := g.QualifiedGoIdent(method.Input.GoIdent) + ", " + g.QualifiedGoIdent(method.Output.GoIdent) - streamImpl = g.QualifiedGoIdent(grpcPackage.Ident("GenericClientStream")) + "[" + typeParam + "]" - } - + typeParam := g.QualifiedGoIdent(method.Input.GoIdent) + ", " + g.QualifiedGoIdent(method.Output.GoIdent) + streamImpl := g.QualifiedGoIdent(grpcPackage.Ident("GenericClientStream")) + "[" + typeParam + "]" serviceDescVar := service.GoName + "_ServiceDesc" g.P("stream, err := c.cc.NewStream(ctx, &", serviceDescVar, ".Streams[", index, `], `, fmSymbol, `, cOpts...)`) g.P("if err != nil { return nil, err }") @@ -392,61 +379,9 @@ func genClientMethod(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated g.P() // Auxiliary types aliases, for backwards compatibility. - if *useGenericStreams { - g.P("// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.") - g.P("type ", service.GoName, "_", method.GoName, "Client = ", clientStreamInterface(g, method)) - g.P() - return - } - - // Stream auxiliary types and methods, if we're not taking advantage of the - // pre-implemented generic types and their methods. - genSend := method.Desc.IsStreamingClient() - genRecv := method.Desc.IsStreamingServer() - genCloseAndRecv := !method.Desc.IsStreamingServer() - - g.P("type ", service.GoName, "_", method.GoName, "Client interface {") - if genSend { - g.P("Send(*", method.Input.GoIdent, ") error") - } - if genRecv { - g.P("Recv() (*", method.Output.GoIdent, ", error)") - } - if genCloseAndRecv { - g.P("CloseAndRecv() (*", method.Output.GoIdent, ", error)") - } - g.P(grpcPackage.Ident("ClientStream")) - g.P("}") + g.P("// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.") + g.P("type ", service.GoName, "_", method.GoName, "Client = ", clientStreamInterface(g, method)) g.P() - - g.P("type ", streamImpl, " struct {") - g.P(grpcPackage.Ident("ClientStream")) - g.P("}") - g.P() - - if genSend { - g.P("func (x *", streamImpl, ") Send(m *", method.Input.GoIdent, ") error {") - g.P("return x.ClientStream.SendMsg(m)") - g.P("}") - g.P() - } - if genRecv { - g.P("func (x *", streamImpl, ") Recv() (*", method.Output.GoIdent, ", error) {") - g.P("m := new(", method.Output.GoIdent, ")") - g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") - g.P("return m, nil") - g.P("}") - g.P() - } - if genCloseAndRecv { - g.P("func (x *", streamImpl, ") CloseAndRecv() (*", method.Output.GoIdent, ", error) {") - g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") - g.P("m := new(", method.Output.GoIdent, ")") - g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") - g.P("return m, nil") - g.P("}") - g.P() - } } func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string { @@ -460,11 +395,7 @@ func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string reqArgs = append(reqArgs, "*"+g.QualifiedGoIdent(method.Input.GoIdent)) } if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { - if *useGenericStreams { - reqArgs = append(reqArgs, serverStreamInterface(g, method)) - } else { - reqArgs = append(reqArgs, method.Parent.GoName+"_"+method.GoName+"Server") - } + reqArgs = append(reqArgs, serverStreamInterface(g, method)) } return method.GoName + "(" + strings.Join(reqArgs, ", ") + ") " + ret } @@ -545,11 +476,8 @@ func genServerMethod(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated return hname } - streamImpl := unexport(service.GoName) + method.GoName + "Server" - if *useGenericStreams { - typeParam := g.QualifiedGoIdent(method.Input.GoIdent) + ", " + g.QualifiedGoIdent(method.Output.GoIdent) - streamImpl = g.QualifiedGoIdent(grpcPackage.Ident("GenericServerStream")) + "[" + typeParam + "]" - } + typeParam := g.QualifiedGoIdent(method.Input.GoIdent) + ", " + g.QualifiedGoIdent(method.Output.GoIdent) + streamImpl := g.QualifiedGoIdent(grpcPackage.Ident("GenericServerStream")) + "[" + typeParam + "]" g.P("func ", hnameFuncNameFormatter(hname), "(srv interface{}, stream ", grpcPackage.Ident("ServerStream"), ") error {") if !method.Desc.IsStreamingClient() { @@ -563,59 +491,9 @@ func genServerMethod(_ *protogen.Plugin, _ *protogen.File, g *protogen.Generated g.P() // Auxiliary types aliases, for backwards compatibility. - if *useGenericStreams { - g.P("// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.") - g.P("type ", service.GoName, "_", method.GoName, "Server = ", serverStreamInterface(g, method)) - g.P() - return hname - } - - // Stream auxiliary types and methods, if we're not taking advantage of the - // pre-implemented generic types and their methods. - genSend := method.Desc.IsStreamingServer() - genSendAndClose := !method.Desc.IsStreamingServer() - genRecv := method.Desc.IsStreamingClient() - - g.P("type ", service.GoName, "_", method.GoName, "Server interface {") - if genSend { - g.P("Send(*", method.Output.GoIdent, ") error") - } - if genSendAndClose { - g.P("SendAndClose(*", method.Output.GoIdent, ") error") - } - if genRecv { - g.P("Recv() (*", method.Input.GoIdent, ", error)") - } - g.P(grpcPackage.Ident("ServerStream")) - g.P("}") + g.P("// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.") + g.P("type ", service.GoName, "_", method.GoName, "Server = ", serverStreamInterface(g, method)) g.P() - - g.P("type ", streamImpl, " struct {") - g.P(grpcPackage.Ident("ServerStream")) - g.P("}") - g.P() - - if genSend { - g.P("func (x *", streamImpl, ") Send(m *", method.Output.GoIdent, ") error {") - g.P("return x.ServerStream.SendMsg(m)") - g.P("}") - g.P() - } - if genSendAndClose { - g.P("func (x *", streamImpl, ") SendAndClose(m *", method.Output.GoIdent, ") error {") - g.P("return x.ServerStream.SendMsg(m)") - g.P("}") - g.P() - } - if genRecv { - g.P("func (x *", streamImpl, ") Recv() (*", method.Input.GoIdent, ", error) {") - g.P("m := new(", method.Input.GoIdent, ")") - g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") - g.P("return m, nil") - g.P("}") - g.P() - } - return hname } diff --git a/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/main.go b/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/main.go index 83bff58e0..94e7ffcf5 100644 --- a/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/main.go +++ b/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/main.go @@ -42,10 +42,9 @@ import ( "google.golang.org/protobuf/types/pluginpb" ) -const version = "1.6.1" +const version = "1.6.2" var requireUnimplemented *bool -var useGenericStreams *bool func main() { showVersion := flag.Bool("version", false, "print the version and exit") @@ -57,7 +56,6 @@ func main() { var flags flag.FlagSet requireUnimplemented = flags.Bool("require_unimplemented_servers", true, "set to false to match legacy behavior") - useGenericStreams = flags.Bool("use_generic_streams_experimental", true, "set to true to use generic types for streaming client and server objects; this flag is EXPERIMENTAL and may be changed or removed in a future release") protogen.Options{ ParamFunc: flags.Set, diff --git a/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh b/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh index c70fd0fa6..fb67b1f41 100644 --- a/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh +++ b/vendor/google.golang.org/grpc/cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh @@ -30,7 +30,7 @@ popd protoc \ --go-grpc_out="${TEMPDIR}" \ - --go-grpc_opt=paths=source_relative,use_generic_streams_experimental=true \ + --go-grpc_opt=paths=source_relative \ "examples/route_guide/routeguide/route_guide.proto" GOLDENFILE="examples/route_guide/routeguide/route_guide_grpc.pb.go" diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 29d332e7b..333448127 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/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go index a2312f8ea..e4b691913 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/xds.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go @@ -69,9 +69,8 @@ var ( // https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md XDSSPIFFEEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_MTLS_SPIFFE", false) - // XDSHTTPConnectEnabled is true if gRPC should parse custom Metadata - // configuring use of an HTTP CONNECT proxy via xDS from cluster resources. - // For more details, see: + // XDSHTTPConnectEnabled controls support for dynamic HTTP CONNECT proxying + // configured via the xDS control plane. For more details, see: // https://github.com/grpc/proposal/blob/master/A86-xds-http-connect.md XDSHTTPConnectEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_HTTP_CONNECT", false) @@ -88,7 +87,7 @@ var ( // XDSORCAToLRSPropEnabled controls whether ORCA metrics are explicitly // filtered and prefix-propagated to the LRS server. For more details, see: // https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md - XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", false) + XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", true) // XDSClientExtProcEnabled indicates whether ExtProc filter is enabled on // the client side. For more details, see: diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go index 9b6d8a1fa..d4999fcca 100644 --- a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go +++ b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go @@ -20,10 +20,15 @@ package grpcsync import ( "context" + "errors" "google.golang.org/grpc/internal/buffer" ) +// ErrSerializerClosed is returned by ScheduleAndWait if the CallbackSerializer +// was closed before the callback could be scheduled. +var ErrSerializerClosed = errors.New("callback serializer is closed") + // CallbackSerializer provides a mechanism to schedule callbacks in a // synchronized manner. It provides a FIFO guarantee on the order of execution // of scheduled callbacks. New callbacks can be scheduled by invoking the @@ -77,6 +82,27 @@ func (cs *CallbackSerializer) ScheduleOr(f func(ctx context.Context), onFailure } } +// ScheduleAndWait schedules the provided callback function f to be executed in +// the order it was added and blocks until f has run. If the context passed to +// NewCallbackSerializer was canceled before this method is called, f is not run +// and ScheduleAndWait returns ErrSerializerClosed. +// +// Callbacks are expected to honor the context when performing any blocking +// operations, and should return early when the context is canceled. +func (cs *CallbackSerializer) ScheduleAndWait(f func(ctx context.Context)) error { + done := make(chan struct{}) + var err error + cs.ScheduleOr(func(ctx context.Context) { + f(ctx) + close(done) + }, func() { + err = ErrSerializerClosed + close(done) + }) + <-done + return err +} + func (cs *CallbackSerializer) run(ctx context.Context) { defer close(cs.done) 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 2d83b2ece..00aeca419 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/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go index 6320e9b57..238950bbb 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -24,7 +24,6 @@ import ( "sync" "google.golang.org/grpc/internal/serviceconfig" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/resolver" ) @@ -52,82 +51,7 @@ type RPCConfig struct { Context context.Context MethodConfig serviceconfig.MethodConfig // configuration to use for this RPC OnCommitted func() // Called when the RPC has been committed (retries no longer possible) - Interceptor ClientInterceptor -} - -// ClientStream is the same as grpc.ClientStream, but defined here for circular -// dependency reasons. -type ClientStream interface { - // Header returns the header metadata received from the server if there - // is any. It blocks if the metadata is not ready to read. - Header() (metadata.MD, error) - // Trailer returns the trailer metadata from the server, if there is any. - // It must only be called after stream.CloseAndRecv has returned, or - // stream.Recv has returned a non-nil error (including io.EOF). - Trailer() metadata.MD - // CloseSend closes the send direction of the stream. It closes the stream - // when non-nil error is met. It is also not safe to call CloseSend - // concurrently with SendMsg. - CloseSend() error - // Context returns the context for this stream. - // - // It should not be called until after Header or RecvMsg has returned. Once - // called, subsequent client-side retries are disabled. - Context() context.Context - // SendMsg is generally called by generated code. On error, SendMsg aborts - // the stream. If the error was generated by the client, the status is - // returned directly; otherwise, io.EOF is returned and the status of - // the stream may be discovered using RecvMsg. - // - // SendMsg blocks until: - // - There is sufficient flow control to schedule m with the transport, or - // - The stream is done, or - // - The stream breaks. - // - // SendMsg does not wait until the message is received by the server. An - // untimely stream closure may result in lost messages. To ensure delivery, - // users should ensure the RPC completed successfully using RecvMsg. - // - // It is safe to have a goroutine calling SendMsg and another goroutine - // calling RecvMsg on the same stream at the same time, but it is not safe - // to call SendMsg on the same stream in different goroutines. It is also - // not safe to call CloseSend concurrently with SendMsg. - SendMsg(m any) error - // RecvMsg blocks until it receives a message into m or the stream is - // done. It returns io.EOF when the stream completes successfully. On - // any other error, the stream is aborted and the error contains the RPC - // status. - // - // It is safe to have a goroutine calling SendMsg and another goroutine - // calling RecvMsg on the same stream at the same time, but it is not - // safe to call RecvMsg on the same stream in different goroutines. - RecvMsg(m any) error -} - -// ClientInterceptor is an interceptor for gRPC client streams. -type ClientInterceptor interface { - // NewStream creates a ClientStream for an RPC. - // - // Implementations must delegate stream creation to the provided newStream - // function. To intercept or override stream behavior, implementations - // may wrap the ClientStream returned by the delegate. - // - // Note: RPCInfo.Context is currently unused and will be nil. - // - // The done function is invoked when the RPC has finished using its - // underlying connection or if a connection could not be assigned. Because - // interceptors operate at the application layer, RPC operations may - // continue on the ClientStream even after done has been called. The - // caller must ensure done is non-nil. - // - // To ensure RPC completion notifications propagate through the entire - // interceptor chain, implementations must ensure that the done function - // passed to the delegate newStream invokes the done function passed to - // NewStream. - NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error) - // Close closes the interceptor. Once called, no new calls to NewStream are - // accepted. Ongoing calls to NewStream are allowed to complete. - Close() + Interceptor any } // ServerInterceptor is an interceptor for incoming RPC's on gRPC server side. diff --git a/vendor/google.golang.org/grpc/internal/transport/client_stream.go b/vendor/google.golang.org/grpc/internal/transport/client_stream.go index ad382b0fd..046f0a555 100644 --- a/vendor/google.golang.org/grpc/internal/transport/client_stream.go +++ b/vendor/google.golang.org/grpc/internal/transport/client_stream.go @@ -39,9 +39,8 @@ const nonGRPCDataMaxLen = 1024 type ClientStream struct { Stream // Embed for common stream functionality. - ct *http2Client - done chan struct{} // closed at the end of stream to unblock writers. - doneFunc func() // invoked at the end of stream. + ct *http2Client + done chan struct{} // closed at the end of stream to unblock writers. headerChan chan struct{} // closed to indicate the end of header metadata. header metadata.MD // the received header metadata 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 a8356c9ad..9cd8d28d3 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 822c09ba6..10d197741 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -498,10 +498,9 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr, handler s ct: t, done: make(chan struct{}), headerChan: make(chan struct{}), - doneFunc: callHdr.DoneFunc, 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. @@ -998,9 +997,6 @@ func (t *http2Client) closeStream(s *ClientStream, err error, rst bool, rstCode t.controlBuf.executeAndPut(addBackStreamQuota, cleanup) // This will unblock write. close(s.done) - if s.doneFunc != nil { - s.doneFunc() - } } // Close kicks off the shutdown process of the transport. This should be called 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 be8ae9f9c..63c6539a3 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 6dfae3984..5fc901e5c 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: @@ -594,8 +692,6 @@ type CallHdr struct { PreviousAttempts int // value of grpc-previous-rpc-attempts header to set - DoneFunc func() // called when the stream is finished - // Authority is used to explicitly override the `:authority` header. // // This value comes from one of two sources: diff --git a/vendor/google.golang.org/grpc/mem/buffer_pool.go b/vendor/google.golang.org/grpc/mem/buffer_pool.go index 3b02b9091..aa121379f 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 2b410b16e..9b355d446 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/stream.go b/vendor/google.golang.org/grpc/stream.go index 4aac644a8..51aff85df 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -201,6 +201,15 @@ func endOfClientStream(cc *ClientConn, err error, opts ...CallOption) { } } +// clientInterceptor is structurally identical to the ClientInterceptor defined +// in internal/xds/httpfilter/httpfilter.go. It is defined locally here so that +// we can type-assert the generic Interceptor field in iresolver.RPCConfig +// without introducing a dependency on xDS packages. +type clientInterceptor interface { + NewStream(ctx context.Context, ri iresolver.RPCInfo, newStream func(ctx context.Context, opts ...CallOption) (ClientStream, error), opts ...CallOption) (ClientStream, error) + Close() +} + func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { if channelz.IsOn() { cc.incrCallsStarted() @@ -244,8 +253,11 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth mc := &emptyMethodConfig var onCommit func() - newStream := func(ctx context.Context, done func()) (iresolver.ClientStream, error) { - return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, done, nameResolutionDelayed, opts...) + newStream := func(ctx context.Context, filterOpts ...CallOption) (ClientStream, error) { + if filterOpts != nil { + opts = combine(opts, filterOpts) + } + return newClientStreamWithParams(ctx, desc, cc, method, mc, onCommit, nameResolutionDelayed, opts...) } rpcInfo := iresolver.RPCInfo{Context: ctx, Method: method} @@ -270,20 +282,24 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth if rpcConfig.Interceptor != nil { rpcInfo.Context = nil ns := newStream - newStream = func(ctx context.Context, done func()) (iresolver.ClientStream, error) { - cs, err := rpcConfig.Interceptor.NewStream(ctx, rpcInfo, done, ns) - if err != nil { - return nil, toRPCErr(err) + if interceptor, ok := rpcConfig.Interceptor.(clientInterceptor); ok { + newStream = func(ctx context.Context, filterOpts ...CallOption) (ClientStream, error) { + cs, err := interceptor.NewStream(ctx, rpcInfo, ns, filterOpts...) + if err != nil { + return nil, toRPCErr(err) + } + return cs, nil } - return cs, nil + } else { + return nil, status.Errorf(codes.Internal, "invalid client interceptor type %T", rpcConfig.Interceptor) } } } - return newStream(ctx, func() {}) + return newStream(ctx) } -func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, mc *serviceconfig.MethodConfig, onCommit, doneFunc func(), nameResolutionDelayed bool, opts ...CallOption) (_ iresolver.ClientStream, err error) { +func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, mc *serviceconfig.MethodConfig, onCommit func(), nameResolutionDelayed bool, opts ...CallOption) (_ ClientStream, err error) { callInfo := defaultCallInfo() if mc.WaitForReady != nil { callInfo.failFast = !*mc.WaitForReady @@ -321,7 +337,6 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client Host: cc.authority, Method: method, ContentSubtype: callInfo.contentSubtype, - DoneFunc: doneFunc, Authority: callInfo.authority, } if allowed := callInfo.acceptedResponseCompressors; len(allowed) > 0 { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 53c737fee..64ec3b3cf 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.82.1" +const Version = "1.83.1" 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 04696351eeeef14cbbd69fd1f4250530b1fbfd56..ad35ea4c449a6b23a78974a905b3fcba120223c6 100644 GIT binary patch delta 50 zcmbQmxSw&t6m2eLiGDvNNe)H>4lG0U`MWs{jB1 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 328dc733b..079a53dd1 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 65aaf4d21..58aeff845 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 bfb2cfdea..58ff0e246 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -52,8 +52,8 @@ import ( const ( Major = 1 Minor = 36 - Patch = 11 - PreRelease = "devel" + Patch = 12 + PreRelease = "" ) // String formats the version string for this module in semver format. 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 730331e66..86f0d0926 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 0b23faa95..a51cb1e54 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 1ff0d1494..510894f2b 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. +// 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. // -// Example 1: Pack and unpack a message in C++. +// Protobuf APIs provide utilities to interact with `Any` values: // -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } +// - 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. // -// Example 2: Pack and unpack a message in Java. +// The JSON format representation of an `Any` follows one of these cases: // -// 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()); -// } +// - 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. // -// 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" -// } +// 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. // - // 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: + // Example: type.googleapis.com/google.protobuf.StringValue // - // - 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.) + // 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. // - // 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. + // 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. // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. + // 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. + // + // 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 91ee89a5c..4a0437911 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. +// 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. // -// 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. +// 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". // -// 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. +// 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 30411b728..8325a5048 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. // -// The JSON representation for `Struct` is 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. +// +// 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 484c21fd5..2cd60946c 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/modules.txt b/vendor/modules.txt index d670293c3..f804591e9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# cyphar.com/go-pathrs v0.2.1 +# cyphar.com/go-pathrs v0.2.5 ## explicit; go 1.18 cyphar.com/go-pathrs cyphar.com/go-pathrs/internal/fdutils @@ -88,8 +88,8 @@ github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/bindfilter github.com/Microsoft/go-winio/pkg/guid github.com/Microsoft/go-winio/vhd -# github.com/Microsoft/hcsshim v0.15.0-rc.1 -## explicit; go 1.24.0 +# github.com/Microsoft/hcsshim v0.15.0-rc.4 +## explicit; go 1.26.3 github.com/Microsoft/hcsshim github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options github.com/Microsoft/hcsshim/computestorage @@ -108,7 +108,7 @@ github.com/Microsoft/hcsshim/internal/logfields github.com/Microsoft/hcsshim/internal/longpath github.com/Microsoft/hcsshim/internal/memory github.com/Microsoft/hcsshim/internal/mergemaps -github.com/Microsoft/hcsshim/internal/oc +github.com/Microsoft/hcsshim/internal/ot github.com/Microsoft/hcsshim/internal/protocol/guestrequest github.com/Microsoft/hcsshim/internal/queue github.com/Microsoft/hcsshim/internal/regstate @@ -186,7 +186,7 @@ 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/aws/protocol/eventstream v1.7.16 +# github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 ## explicit; go 1.24 github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/eventstreamapi @@ -534,7 +534,7 @@ github.com/coreos/go-systemd/v22/daemon # github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 ## explicit github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer -# github.com/cyphar/filepath-securejoin v0.6.0 +# github.com/cyphar/filepath-securejoin v0.6.1 ## explicit; go 1.18 github.com/cyphar/filepath-securejoin/internal/consts github.com/cyphar/filepath-securejoin/pathrs-lite @@ -580,14 +580,14 @@ github.com/docker/go-units # github.com/felixge/fgprof v0.9.3 ## 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.9.0 ## explicit; go 1.17 github.com/fsnotify/fsnotify github.com/fsnotify/fsnotify/internal -# github.com/go-logr/logr v1.4.3 +# github.com/go-logr/logr v1.4.4 ## explicit; go 1.18 github.com/go-logr/logr github.com/go-logr/logr/funcr @@ -875,10 +875,10 @@ github.com/opencontainers/selinux/pkg/pwalkdir # github.com/package-url/packageurl-go v0.1.1 ## explicit; go 1.17 github.com/package-url/packageurl-go -# github.com/pelletier/go-toml/v2 v2.3.1 +# github.com/pelletier/go-toml/v2 v2.4.3 ## explicit; go 1.21.0 github.com/pelletier/go-toml/v2 -github.com/pelletier/go-toml/v2/internal/characters +github.com/pelletier/go-toml/v2/internal/parserbridge github.com/pelletier/go-toml/v2/internal/tracker github.com/pelletier/go-toml/v2/unstable # github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 @@ -908,8 +908,8 @@ github.com/planetscale/vtprotobuf/generator/pattern github.com/planetscale/vtprotobuf/protohelpers github.com/planetscale/vtprotobuf/types/known/timestamppb github.com/planetscale/vtprotobuf/vtproto -# 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/internal/github.com/golang/gddo/httputil github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header github.com/prometheus/client_golang/prometheus @@ -919,14 +919,14 @@ github.com/prometheus/client_golang/prometheus/promhttp/internal # github.com/prometheus/client_model v0.6.2 ## explicit; go 1.22.0 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.67.5 -## explicit; go 1.24.0 +# github.com/prometheus/common v0.70.1 +## explicit; go 1.25.0 github.com/prometheus/common/expfmt github.com/prometheus/common/model # github.com/prometheus/otlptranslator v1.0.0 ## explicit; go 1.23.0 github.com/prometheus/otlptranslator -# github.com/prometheus/procfs v0.20.1 +# github.com/prometheus/procfs v0.21.1 ## explicit; go 1.25.0 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs @@ -1008,8 +1008,8 @@ github.com/sigstore/sigstore-go/pkg/verify # github.com/sigstore/timestamp-authority/v2 v2.1.2 ## explicit; go 1.25.0 github.com/sigstore/timestamp-authority/v2/pkg/verification -# github.com/sirupsen/logrus v1.9.4 -## explicit; go 1.17 +# github.com/sirupsen/logrus v1.10.1 +## explicit; go 1.23 github.com/sirupsen/logrus # github.com/spdx/tools-golang v0.5.7 ## explicit; go 1.22 @@ -1090,31 +1090,24 @@ go.etcd.io/bbolt go.etcd.io/bbolt/errors go.etcd.io/bbolt/internal/common go.etcd.io/bbolt/internal/freelist -# go.opencensus.io v0.24.0 -## explicit; go 1.13 -go.opencensus.io -go.opencensus.io/internal -go.opencensus.io/trace -go.opencensus.io/trace/internal -go.opencensus.io/trace/tracestate # go.opentelemetry.io/auto/sdk v1.2.1 ## explicit; go 1.24.0 go.opentelemetry.io/auto/sdk go.opentelemetry.io/auto/sdk/internal/telemetry -# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.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.69.0 +# go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.70.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.69.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 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv -# go.opentelemetry.io/otel v1.44.0 +# go.opentelemetry.io/otel v1.45.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -1126,13 +1119,14 @@ go.opentelemetry.io/otel/internal/baggage go.opentelemetry.io/otel/internal/errorhandler go.opentelemetry.io/otel/internal/global go.opentelemetry.io/otel/propagation +go.opentelemetry.io/otel/semconv/internal/metricpool go.opentelemetry.io/otel/semconv/v1.21.0 go.opentelemetry.io/otel/semconv/v1.37.0 go.opentelemetry.io/otel/semconv/v1.37.0/rpcconv -go.opentelemetry.io/otel/semconv/v1.41.0 -go.opentelemetry.io/otel/semconv/v1.41.0/httpconv -go.opentelemetry.io/otel/semconv/v1.41.0/otelconv -go.opentelemetry.io/otel/semconv/v1.41.0/rpcconv +go.opentelemetry.io/otel/semconv/v1.43.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/exporters/jaeger v1.17.0 ## explicit; go 1.19 go.opentelemetry.io/otel/exporters/jaeger @@ -1140,7 +1134,7 @@ go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift -# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 +# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal @@ -1151,7 +1145,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x -# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 +# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal @@ -1162,11 +1156,11 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/transform go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x -# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.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.45.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal @@ -1176,7 +1170,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/x -# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal @@ -1186,46 +1180,48 @@ 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/exporters/prometheus v0.66.0 +# go.opentelemetry.io/otel/exporters/prometheus v0.67.0 ## explicit; go 1.25.0 go.opentelemetry.io/otel/exporters/prometheus go.opentelemetry.io/otel/exporters/prometheus/internal go.opentelemetry.io/otel/exporters/prometheus/internal/counter go.opentelemetry.io/otel/exporters/prometheus/internal/observ go.opentelemetry.io/otel/exporters/prometheus/internal/x -# go.opentelemetry.io/otel/metric v1.44.0 +# go.opentelemetry.io/otel/metric v1.45.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.45.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.45.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.44.0 +# go.opentelemetry.io/otel/trace v1.45.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/metrics/v1 go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 @@ -1238,7 +1234,7 @@ go.yaml.in/yaml/v2 # 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/blake2b @@ -1269,11 +1265,11 @@ golang.org/x/exp/trace golang.org/x/exp/trace/internal/tracev1 golang.org/x/exp/trace/internal/tracev2 golang.org/x/exp/trace/internal/version -# golang.org/x/mod v0.38.0 +# golang.org/x/mod v0.40.0 ## explicit; go 1.25.0 golang.org/x/mod/semver golang.org/x/mod/sumdb/note -# golang.org/x/net v0.57.0 +# golang.org/x/net v0.58.0 ## explicit; go 1.25.0 golang.org/x/net/http/httpguts golang.org/x/net/http2 @@ -1300,7 +1296,7 @@ golang.org/x/sys/windows/svc/mgr # golang.org/x/term v0.45.0 ## explicit; go 1.25.0 golang.org/x/term -# golang.org/x/text v0.40.0 +# golang.org/x/text v0.41.0 ## explicit; go 1.25.0 golang.org/x/text/secure/bidirule golang.org/x/text/transform @@ -1309,16 +1305,16 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.15.0 ## explicit; go 1.25.0 golang.org/x/time/rate -# google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa +# google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations google.golang.org/genproto/googleapis/api/httpbody -# google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa +# google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.82.1 +# google.golang.org/grpc v1.83.1 ## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes @@ -1391,10 +1387,10 @@ google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status google.golang.org/grpc/tap -# google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 -## explicit; go 1.24.0 +# google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 +## explicit; go 1.25.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc -# google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af +# google.golang.org/protobuf v1.36.12 ## explicit; go 1.23 google.golang.org/protobuf/cmd/protoc-gen-go google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo